Registering overloaded operators

Started by
6 comments, last by WitchLord 15 years, 8 months ago
I would like to know if it's possible to register overloaded operators with angel script. This is not really related to only angelscript, I had the same problem with lua as well. I couldn't register overloaded functions since the compiler doesn't know wich of several functions i meant with &CObj::Func. Is there a way to solve this problem without writing a function for every overload? It would be great since I'm currently rewriting my game to support angelscript (lua really annoyed me in the end). *edit* Just something that pops in my mind: I've just implemented my vector class (3 dimensional vector, not the array type) with angelscript as you showed on your site. However I'm not shure if I should register is as by reference or by value. What seems more appropriate? *edit2* I also noticed that registering asBEHAVE_ADD functions for a class registered with asOBJ_REF does not work, what do you I need to do to make it work? It would be great if you could give me a detailed description. [Edited by - SiS-Shadowman on August 1, 2008 7:01:00 AM]
Advertisement
You can write a templated wrapper once and use it everytime you need to bind that operator.

An example.

template <typename LHS, typename RHS> LHS operator_add(const LHS& lhs, const RHS& rhs){   return lhs + rhs;}


Now when binding, instead of trying to take the address of operator+, take the address of operator_add<LHS,RHS>. The compiler will select the proper overload for you.
Thanks for the answer. Do you also know how to solve my problem in my second edit? Would be really great :)
For the first edit, it seems more logical to treat a mathematical vector as a build in type, and pass it by value.

For the second, did you check the return code?
Okay, I have tried to register my vector class by value, but I'm unshure if it's okay to only pass "sizeof( myclass )" as the bytesize. I'm not shure if this is correct or not.

However (supposing the above is correct), adding a global add/sub/div/mul operator does now work.
To take the address of any overloaded function, operators included. You need to cast the address to a function pointer with the parameter types defined. This is how C++ understands which function to use.

In AngelScript you do this by using the macro asMETHODPR or asFUNCTIONPR example:

engine->RegisterObjectBehaviour("vec3", asBEHAVE_ASSIGN, "vec3 &f(float)", asMETHODPR(vec3, operator=, (float), vec3&), asCALL_THISCALL);engine->RegisterGlobalBehaviour(asBEHAVE_ADD, "vec3 f(const vec3 &in, const vec3 &in)", asFUNCTIONPR(operator+, (const vec3&, const vec3&), vec3), asCALL_CDECL);


I agree with Deyja, and recommend registering the vector type as asOBJ_VALUE rather than asOBJ_REF. For a tiny type like this it is usually more efficient to treat it as a primitive and avoid the overhead of reference counting. To make it easier for you I also recommend registering the type with the asOBJ_POD modifier. AngelScript then handles the default constructor and assignment operator by itself.

engine->RegisterObjectType("vec3", sizeof(vec3), asOBJ_VALUE | asOBJ_POD | asOBJ_CLASS_CA);


The add behaviour works for reference types and value types both. Reference types can however not be passed by value to a registered function (due to not being able to place reference handled objects on the stack). Perhaps that is where your problem lies.

For an example on registering the add operator for a reference type, you can check out the script string add on.

Regards,
Andreas

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

Thank you for that explaination :)
I implemented it as you said and it works plain perfect.

However a new question pops up. I also want to register 1 or 2 ctors. Do they only work with by value registered classes? Since from the tutorial on your site, I understand that angelscript allocates the memory for me, I only need to "copy" the object into the memory. But if I register an object as by reference, I don't need to pass the size of it to angelscript.

[Edited by - SiS-Shadowman on August 2, 2008 8:45:42 AM]
For value types you have constructors, and for reference types you have factories. The difference between them is that the constructor initializes already allocated memory whereas the factories allocate and initialize the memory.

The fact is that for value types AngelScript needs to know the size of the type so that it can allocate the memory as it sees fit and also copy the objects to the stack when necessary. For reference types the application has complete control over where and how the objects are allocated.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

This topic is closed to new replies.

Advertisement