🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Problem with value type & opAssign

Started by
2 comments, last by noizex 5 years, 8 months ago

Hi, 

I try to wrap my head around operator behaviour, documentation does not say much for the C++ side, so I guess it should be probably simple but I can't get this to work:


# this works
vec3 a(1.0f);
vec3 b(0.0f);
vec3 c = a - b;

# this doesn't
Transform@ transform = Transform();
vec3 a(1.0f);
vec3 c = a - transform.position;

(70): No appropriate opAssign method found in 'vec3' for value assignment
(70): Previous error occurred while attempting to create a temporary copy of object

Transform register:


   asCHECK(engine->RegisterObjectType("Transform", 0, asOBJ_REF));
   asCHECK(engine->RegisterObjectBehaviour("Transform", asBEHAVE_FACTORY, "Transform@ f()", asMETHOD(SpatialWorld, makeTransform),
                                           asCALL_THISCALL_ASGLOBAL, this));
   asCHECK(engine->RegisterObjectBehaviour("Transform", asBEHAVE_ADDREF, "void f()", asMETHOD(TransformScriptProxy, addRef), asCALL_THISCALL));
   asCHECK(engine->RegisterObjectBehaviour("Transform", asBEHAVE_RELEASE, "void f()", asMETHOD(TransformScriptProxy, release), asCALL_THISCALL));

   asCHECK(engine->RegisterObjectMethod("Transform", "vec3 get_forward() const", asMETHOD(TransformScriptProxy, getForward), asCALL_THISCALL));
   asCHECK(engine->RegisterObjectMethod("Transform", "vec3 get_position() const", asMETHOD(TransformScriptProxy, getPosition), asCALL_THISCALL));
   asCHECK(engine->RegisterObjectMethod("Transform", "void set_position(const vec3 &in)", asMETHOD(TransformScriptProxy, setPosition), asCALL_THISCALL));

vec3 register:


 // Type & behaviours
   asCHECK(m_engine->RegisterObjectType("vec3", sizeof(glm::vec3), asOBJ_VALUE | asGetTypeTraits<glm::vec3>()));
   asCHECK(m_engine->RegisterObjectBehaviour("vec3", asBEHAVE_CONSTRUCT, "void f()", asFUNCTION(vec3_ConstructorEmpty), asCALL_CDECL_OBJLAST));

   asCHECK(m_engine->RegisterObjectBehaviour("vec3", asBEHAVE_CONSTRUCT, "void f(float, float, float)", asFUNCTION(vec3_Constructor), asCALL_CDECL_OBJFIRST));
   asCHECK(m_engine->RegisterObjectBehaviour("vec3", asBEHAVE_CONSTRUCT, "void f(float)", asFUNCTION(vec3_ConstructorScalar), asCALL_CDECL_OBJFIRST));
   asCHECK(m_engine->RegisterObjectBehaviour("vec3", asBEHAVE_DESTRUCT, "void f()", asFUNCTION(vec3_Destructor), asCALL_CDECL_OBJFIRST));

   // Properties
   asCHECK(m_engine->RegisterObjectProperty("vec3", "float x", asOFFSET(glm::vec3, x)));
   asCHECK(m_engine->RegisterObjectProperty("vec3", "float y", asOFFSET(glm::vec3, y)));
   asCHECK(m_engine->RegisterObjectProperty("vec3", "float z", asOFFSET(glm::vec3, z)));

   // Operators
   asCHECK(m_engine->RegisterObjectMethod("vec3", "vec3& opAddAssign(const vec3 &in) const", asMETHODPR(glm::vec3, operator+=, (const glm::vec3&), glm::vec3&), asCALL_THISCALL));
   asCHECK(m_engine->RegisterObjectMethod("vec3", "vec3& opMulAssign(const vec3 &in) const", asMETHODPR(glm::vec3, operator*=, (const glm::vec3&), glm::vec3&), asCALL_THISCALL));
   asCHECK(m_engine->RegisterObjectMethod("vec3", "vec3& opAssign(const vec3 &in) const", asMETHODPR(glm::vec3, operator=, (const glm::vec3&), glm::vec3&), asCALL_THISCALL));
   asCHECK(m_engine->RegisterObjectMethod("vec3", "vec3 opAdd(const vec3 &in) const", asFUNCTIONPR(glm::operator+, (const glm::vec3&, const glm::vec3&), glm::vec3), asCALL_CDECL_OBJLAST));
   asCHECK(m_engine->RegisterObjectMethod("vec3", "vec3 opSub(const vec3 &in) const", asFUNCTIONPR(glm::operator-, (const glm::vec3&, const glm::vec3&), glm::vec3), asCALL_CDECL_OBJLAST));
   asCHECK(m_engine->RegisterObjectMethod("vec3", "vec3 opMul(const vec3 &in) const", asFUNCTIONPR(glm::operator*, (const glm::vec3&, const glm::vec3&), glm::vec3), asCALL_CDECL_OBJLAST));
   asCHECK(m_engine->RegisterObjectMethod("vec3", "vec3 opMul_r(float) const", asFUNCTIONPR(glm::operator*, (float, const glm::vec3&), glm::vec3), asCALL_CDECL_OBJLAST));
   asCHECK(m_engine->RegisterObjectMethod("vec3", "vec3 opDiv(const vec3 &in) const", asFUNCTIONPR(glm::operator/, (const glm::vec3&, const glm::vec3&), glm::vec3), asCALL_CDECL_OBJLAST));
   
   // Methods
   asCHECK(m_engine->RegisterObjectMethod("vec3", "float length() const", asFUNCTIONPR(glm::length, (const glm::vec3&), float), asCALL_CDECL_OBJFIRST));
   asCHECK(m_engine->RegisterObjectMethod("vec3", "float dot(const vec3& in) const", asFUNCTIONPR(glm::dot, (const glm::vec3&, const glm::vec3&), float), asCALL_CDECL_OBJFIRST));
   asCHECK(m_engine->RegisterObjectMethod("vec3", "vec3 normalize() const", asFUNCTIONPR(glm::normalize, (const glm::vec3&), glm::vec3), asCALL_CDECL_OBJFIRST));
   asCHECK(m_engine->RegisterObjectMethod("vec3", "string str()", asFUNCTIONPR(glm::to_string, (const glm::vec3&), std::string), asCALL_CDECL_OBJLAST));

Anyone knows what might be wrong here? Also if you spot some obvious inefficiencies please let me know - vec3 is small class (it's glm::vec3) that can be copied and used by value - maybe the problem is that I return a value from Transform::get_position() instead of reference? Or that I registered vec3::opAssign as returning reference, but without it I was having errors with registers and overall breakage...


Where are we and when are we and who are we?
How many people in how many places at how many times?
Advertisement

Your opAssign methods are declared as 'const'. This is why the compiler is not able to use them for assignment.

If your vec3 class doesn't really have any pointers or anything else that needs special treatment (which I presume is the case) you may want to register the class as asOBJ_POD which would allow you to skip the registration of the destructor. This should also allow the compiler to do a bitwise copy of the vec3 rather than having to call the opAssign or copy constructor. 

If you prefer not to use asOBJ_POD for some reason, you may want to register the copy constructor instead, as it would be more efficient when creating temporary copies of a vec3 value than first creating an instance then calling opAssign.

 

 

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

Thanks! To be honest I'm not sure why I didn't make it asOBJ_POD - I'm pretty sure that would be the first thing to try for me.. I tried changing it and it now compiles and seems to work fine. 


Where are we and when are we and who are we?
How many people in how many places at how many times?

This topic is closed to new replies.

Advertisement