Global Operator

Started by
7 comments, last by Madcap 6 years, 6 months ago

I'm setting up a class as a value type using "asOBJ_VALUE | asOBJ_POD | asGetTypeTraits<Obj>()" flags in the registerobjecttype function.  I've set up the object properties, methods, override methods and the operators.  However, some operators for this object type are global and take the two parameters.  I'm trying to register them as global functions with this (C++ operator prototype is beneath too:


RegisterGlobalFunction("const Obj opMul(const Obj &in, const Obj &in)", 
		asFUNCTIONPR(operator*, (const Obj&, const Obj&), const Obj, asCALL_CDECL);

const Obj operator * (const Obj &a, const Obj &b);

And while I'm not getting any syntax errors, and that it appears to register without errors, it doesn't work in script:

Quote

No matching operator that takes the types 'Obj' and 'Obj' found

These 'global;' operators are for the "val * val" and the member operators use the assignment "*=".  Also, I had to add the "asGetTypeTraits<Obj>()" flag so I can use the return by value that the global operator uses.

Advertisement

I'm not sure why the operator needs to be a global? You use opMul as a method function and opMul_r as the reverse (a * b and b * a).

For example:


Obj opMul(const Obj &in rightHandSide)
Obj opMul_r(const Obj &in leftHandSide)

In the first, the object itself is the left hand side, and on the second it's the right hand side.

They're outside the class because it was easier to implement them to work with all the other classes in the same group that interact with each other.  Anyway, I put one of them into the class and got it to work after I registered the assignment operator.  I'll do some testing and see how it works.  I'm curious why I can't register an operator as a global function, though. 

I use these classes to write out some complex math, and there are cases where I use three or more binary operator functions, like so:


const Obj operator - (const Obj &a, const Obj &b);
const Obj operator - (const Obj &a, const float &b);
const Obj operator - (const float &a, const Obj &b);

Using only one parameter, like they are as class members, would cause problems when trying to override an operator, because two would have the same signature.

Maybe I can have some binary ops in the class and the remaining outside.  I don't think I will need every conceivable scenario on the scripting side, but any suggestions to get this to all work at both ends would be appreciated.

 

Basically:


const Obj operator - (const float &a, const Obj &b);

Isn't using the member properties, since it's just a single float subtracted by an Obj then returning the sum as Obj.  I don't know where else to put it other than outside of the class.

You might be able to point to the global function directly using asCALL_CDECL_OBJFIRST or asCALL_CDECL_OBJLAST actually, if you don't want to use a wrapper function.

Thanks, I think that worked.  It's giving me the correct sum.


RegisterGlobalFunction("const Obj opSub(const float &in)",
		asFUNCTIONPR(operator-, (const float &, const Obj &), const Obj), asCALL_CDECL_OBJLAST)

I'm using a static member function in each class to register each class.  I had to take the above code out of that method because it was pointing to the member operator I also set up:


const Obj operator - (const Obj &v) const;

RegisterObjectMethod("Obj", "const Obj opSub(const Obj &in) const", asMETHODPR(Obj, operator-, (const Obj &) const, const Obj), asCALL_THISCALL)

I'll put it in with the overridable construct functions under a private namespace.  I might put all the binary ops relating to this object in there, to keep things neat and save me from having to recode them in C++.

Wait, how does your first snippet work as a global Angelscript function? You're not specifying the type for the right hand side. Did you actually mean the use RegisterObjectMethod for that? I'm a bit confused at what your exact problem is now, but it looks like you have both set up while your scripts are actually only using 1 of those definitions (the RegisterObjectMethod one).

After coming out of hibernation I realised that I forgot to actually register the global one. The script appears to be treating floats, including written numbers (eg. 2.0f),  like an Obj.    The one opSub actually setup takes only an Obj.    I get syntax error when I try and write the same bit of math in raw C++. 

So if I used "obj = obj2 - 2.0f - obj3 - 10.0f" in script, it will call that one method operator and pass 2.0f or 10.0f to the Obj parameter.  Say Obj is a Vec2, then both floats are set to 2.0f or 10.0f.  For this test the result is the same.

I believe it's using "asBEHAVE_CONSTRUCT, "void f(const float)" to assign the Obj in the operator parameter. 

This will break things later on, since it needs to be a lot more strict about what is being passed. 

OK, I put all the binary operators that deal with the member property into their classes.  The few funny ones remaining will have to stay outside.  However, they're only used to simplify a few expressions in the matrices and quaternion classes, so it's doubtful that they will be needed on the scripting side.  In fact, what confused me is that I put them in the class source file based on their return type when I wrote them long ago, when they should really be put in a source on their own or where they are actually used. 

I'll carry on registering them all (the first couple went OK).

Thanks for your help.

This topic is closed to new replies.

Advertisement