Jump to content
  • Advertisement
Sign in to follow this  
howie_007

Operator assignment question

Recommended Posts

Should I be able to do this in the script code? The question is about the last line of the below code example.

CPoint velocity;
velocity.x = cos( rotation ) * PROJECTILE_SPEED;
velocity.y = sin( rotation ) * PROJECTILE_SPEED;

float time = HighResTimer.getElapsedTime();
sprite.incPos( velocity * time );

sprite.incPos receives a CPoint as a parameter. There's no compiler error and the code runs but the CPoint recieved by sprite.incPos is all zeros.

Here's my assignment code. Perhaps I'm missing something.

Thank you for all your hard work providing us this amazing scripting tool along with your other tools like the font creator.

// binary operators
Throw( pEngine->RegisterObjectMethod("CPoint", "CPoint opAdd ( CPoint & in )", asMETHODPR(CPoint<float>, operator +, (const CPoint<float> &) const, CPoint<float>), asCALL_THISCALL) );
Throw( pEngine->RegisterObjectMethod("CPoint", "CPoint opSub ( CPoint & in )", asMETHODPR(CPoint<float>, operator -, (const CPoint<float> &) const, CPoint<float>), asCALL_THISCALL) );
Throw( pEngine->RegisterObjectMethod("CPoint", "CPoint opMul ( CPoint & in )", asMETHODPR(CPoint<float>, operator *, (const CPoint<float> &) const, CPoint<float>), asCALL_THISCALL) );
Throw( pEngine->RegisterObjectMethod("CPoint", "CPoint opDiv ( CPoint & in )", asMETHODPR(CPoint<float>, operator /, (const CPoint<float> &) const, CPoint<float>), asCALL_THISCALL) );

Throw( pEngine->RegisterObjectMethod("CPoint", "CPoint opAdd ( float )", asMETHODPR(CPoint<float>, operator +, (float) const, CPoint<float>), asCALL_THISCALL) );
Throw( pEngine->RegisterObjectMethod("CPoint", "CPoint opSub ( float )", asMETHODPR(CPoint<float>, operator -, (float) const, CPoint<float>), asCALL_THISCALL) );
Throw( pEngine->RegisterObjectMethod("CPoint", "CPoint opMul ( float )", asMETHODPR(CPoint<float>, operator *, (float) const, CPoint<float>), asCALL_THISCALL) );
Throw( pEngine->RegisterObjectMethod("CPoint", "CPoint opDiv ( float )", asMETHODPR(CPoint<float>, operator /, (float) const, CPoint<float>), asCALL_THISCALL) );

// compound assignment operators
Throw( pEngine->RegisterObjectMethod("CPoint", "CPoint opAddAssign ( CPoint & in )", asMETHODPR(CPoint<float>, operator +=, (const CPoint<float> &), CPoint<float>), asCALL_THISCALL) );
Throw( pEngine->RegisterObjectMethod("CPoint", "CPoint opSubAssign ( CPoint & in )", asMETHODPR(CPoint<float>, operator -=, (const CPoint<float> &), CPoint<float>), asCALL_THISCALL) );
Throw( pEngine->RegisterObjectMethod("CPoint", "CPoint opMulAssign ( CPoint & in )", asMETHODPR(CPoint<float>, operator *=, (const CPoint<float> &), CPoint<float>), asCALL_THISCALL) );
Throw( pEngine->RegisterObjectMethod("CPoint", "CPoint opDivAssign ( CPoint & in )", asMETHODPR(CPoint<float>, operator /=, (const CPoint<float> &), CPoint<float>), asCALL_THISCALL) );

Throw( pEngine->RegisterObjectMethod("CPoint", "CPoint opAddAssign ( float )", asMETHODPR(CPoint<float>, operator +=, (float) , CPoint<float>), asCALL_THISCALL) );
Throw( pEngine->RegisterObjectMethod("CPoint", "CPoint opSubAssign ( float )", asMETHODPR(CPoint<float>, operator -=, (float) , CPoint<float>), asCALL_THISCALL) );
Throw( pEngine->RegisterObjectMethod("CPoint", "CPoint opMulAssign ( float )", asMETHODPR(CPoint<float>, operator *=, (float) , CPoint<float>), asCALL_THISCALL) );
Throw( pEngine->RegisterObjectMethod("CPoint", "CPoint opDivAssign ( float )", asMETHODPR(CPoint<float>, operator /=, (float) , CPoint<float>), asCALL_THISCALL) );

 

Share this post


Link to post
Share on other sites
Advertisement

Yes, it should be possible to do what you've done. There can be many different causes for the problem you're facing. The most likely is that something is wrong with how you've registered the CPoint type, but I cannot at this point exclude a possible bug in the library.

 

Can you show how you've registered the CPoint (other than the operators). I need to see the RegisterObjectType, behaviours and also opAssign (if you have registered it).

Also, does incPos take the CPoint by value or by reference? Can you show the declaration?

 

Share this post


Link to post
Share on other sites

Here is the c++ angelscript wrapper function that receives the point.

void IncPos1(CPoint<float> & pos, CSprite & sprite)
{
    sprite.getObject()->incPos(pos);
}

Here's the CPoint class registration code


/************************************************************************
 *    FILE NAME:       scriptpoint.cpp
 *
 *    DESCRIPTION:     CPoint script object registration
 ************************************************************************/

// Physical component dependency
#include <script/scriptpoint.h>

// Game lib dependencies
#include <common/point.h>
#include <script/scriptmanager.h>
#include <script/scriptglobals.h>

// AngelScript lib dependencies
#include <angelscript.h>

namespace NScriptPoint
{
    /************************************************************************
     *    DESC:  Constructor
     ************************************************************************/
    void Constructor(void * thisPointer)
    {
        new(thisPointer) CPoint<float>();
    }

    /************************************************************************
     *    DESC:  Copy Constructor
     ************************************************************************/
    void CopyConstructor(const CPoint<float> & other, void * pThisPointer)
    {
        new(pThisPointer) CPoint<float>(other);
    }

    void ConstructorFromThreeFloats(float x, float y, float z, void * pThisPointer)
    {
        new(pThisPointer) CPoint<float>(x, y, z);
    }

    void ConstructorFromTwoFloats(float x, float y, void * pThisPointer)
    {
        new(pThisPointer) CPoint<float>(x, y);
    }

    /************************************************************************
     *    DESC:  Destructor
     ************************************************************************/
    void Destructor(void * pThisPointer)
    {
        ((CPoint<float>*)pThisPointer)->~CPoint();
    }
    
    /************************************************************************
    *    DESC:  Wrapper function due to type being a template
    ************************************************************************/
    float GetLengthSquared2D1(CPoint<float> & point)
    {
        return point.getLengthSquared2D();
    }
    
    float GetLengthSquared2D2(CPoint<float> & in, CPoint<float> & point)
    {
        return point.getLengthSquared2D( in );
    }
    
    float GetLength2D1(CPoint<float> & point)
    {
        return point.getLength2D();
    }
    
    float GetLength2D2(CPoint<float> & in, CPoint<float> & point)
    {
        return point.getLength2D( in );
    }
    
    float GetLengthSquared1(CPoint<float> & point)
    {
        return point.getLengthSquared();
    }
    
    float GetLengthSquared2(CPoint<float> & in, CPoint<float> & point)
    {
        return point.getLengthSquared( in );
    }
    
    float GetLength1(CPoint<float> & point)
    {
        return point.getLength();
    }
    
    float GetLength2(CPoint<float> & in, CPoint<float> & point)
    {
        return point.getLength( in );
    }
    
    bool IsEquilEnough(CPoint<float> & in, float val, CPoint<float> & point)
    {
        return point.isEquilEnough( in, val );
    }

    float GetDotProduct(CPoint<float> & in, CPoint<float> & point)
    {
        return point.getDotProduct( in );
    }
    
    float GetDotProduct2D(CPoint<float> & in, CPoint<float> & point)
    {
        return point.getDotProduct2D( in );
    }
    
    CPoint<float> GetCrossProduct(CPoint<float> & in, CPoint<float> & point)
    {
        return point.getCrossProduct( in );
    }
    
    void Cap(float value, CPoint<float> & point)
    {
        point.cap(value);
    }


    /************************************************************************
     *    DESC:  Register the class with AngelScript
     ************************************************************************/
    void Register()
    {
        using namespace NScriptGlobals; // Used for Throw
        
        asIScriptEngine * pEngine = CScriptMgr::Instance().getEnginePtr();
        
        // Register type
        Throw( pEngine->RegisterObjectType("CPoint", sizeof(CPoint<float>), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS | asOBJ_APP_CLASS_CONSTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR | asOBJ_APP_CLASS_DESTRUCTOR ) );

        // Register the object operator overloads
        Throw( pEngine->RegisterObjectBehaviour("CPoint", asBEHAVE_CONSTRUCT, "void f()",                    asFUNCTION(Constructor), asCALL_CDECL_OBJLAST) );
        Throw( pEngine->RegisterObjectBehaviour("CPoint", asBEHAVE_CONSTRUCT, "void f(const CPoint & in)",   asFUNCTION(CopyConstructor), asCALL_CDECL_OBJLAST) );
        Throw( pEngine->RegisterObjectBehaviour("CPoint", asBEHAVE_CONSTRUCT, "void f(float, float, float)", asFUNCTION(ConstructorFromThreeFloats), asCALL_CDECL_OBJLAST) );
        Throw( pEngine->RegisterObjectBehaviour("CPoint", asBEHAVE_CONSTRUCT, "void f(float, float)",        asFUNCTION(ConstructorFromTwoFloats), asCALL_CDECL_OBJLAST) );
        Throw( pEngine->RegisterObjectBehaviour("CPoint", asBEHAVE_DESTRUCT, "void f()",                     asFUNCTION(Destructor), asCALL_CDECL_OBJLAST) );

        // assignment operator
        Throw( pEngine->RegisterObjectMethod("CPoint", "CPoint & opAssign(CPoint & in)", asMETHODPR(CPoint<float>, operator =, (const CPoint<float> &), CPoint<float> &), asCALL_THISCALL) );

        // binary operators
        Throw( pEngine->RegisterObjectMethod("CPoint", "CPoint opAdd ( CPoint & in )", asMETHODPR(CPoint<float>, operator +, (const CPoint<float> &) const, CPoint<float>), asCALL_THISCALL) );
        Throw( pEngine->RegisterObjectMethod("CPoint", "CPoint opSub ( CPoint & in )", asMETHODPR(CPoint<float>, operator -, (const CPoint<float> &) const, CPoint<float>), asCALL_THISCALL) );
        Throw( pEngine->RegisterObjectMethod("CPoint", "CPoint opMul ( CPoint & in )", asMETHODPR(CPoint<float>, operator *, (const CPoint<float> &) const, CPoint<float>), asCALL_THISCALL) );
        Throw( pEngine->RegisterObjectMethod("CPoint", "CPoint opDiv ( CPoint & in )", asMETHODPR(CPoint<float>, operator /, (const CPoint<float> &) const, CPoint<float>), asCALL_THISCALL) );

        Throw( pEngine->RegisterObjectMethod("CPoint", "CPoint opAdd ( float )", asMETHODPR(CPoint<float>, operator +, (float) const, CPoint<float>), asCALL_THISCALL) );
        Throw( pEngine->RegisterObjectMethod("CPoint", "CPoint opSub ( float )", asMETHODPR(CPoint<float>, operator -, (float) const, CPoint<float>), asCALL_THISCALL) );
        Throw( pEngine->RegisterObjectMethod("CPoint", "CPoint opMul ( float )", asMETHODPR(CPoint<float>, operator *, (float) const, CPoint<float>), asCALL_THISCALL) );
        Throw( pEngine->RegisterObjectMethod("CPoint", "CPoint opDiv ( float )", asMETHODPR(CPoint<float>, operator /, (float) const, CPoint<float>), asCALL_THISCALL) );

        // compound assignment operators
        Throw( pEngine->RegisterObjectMethod("CPoint", "CPoint opAddAssign ( CPoint & in )", asMETHODPR(CPoint<float>, operator +=, (const CPoint<float> &), CPoint<float>), asCALL_THISCALL) );
        Throw( pEngine->RegisterObjectMethod("CPoint", "CPoint opSubAssign ( CPoint & in )", asMETHODPR(CPoint<float>, operator -=, (const CPoint<float> &), CPoint<float>), asCALL_THISCALL) );
        Throw( pEngine->RegisterObjectMethod("CPoint", "CPoint opMulAssign ( CPoint & in )", asMETHODPR(CPoint<float>, operator *=, (const CPoint<float> &), CPoint<float>), asCALL_THISCALL) );
        Throw( pEngine->RegisterObjectMethod("CPoint", "CPoint opDivAssign ( CPoint & in )", asMETHODPR(CPoint<float>, operator /=, (const CPoint<float> &), CPoint<float>), asCALL_THISCALL) );

        Throw( pEngine->RegisterObjectMethod("CPoint", "CPoint opAddAssign ( float )", asMETHODPR(CPoint<float>, operator +=, (float) , CPoint<float>), asCALL_THISCALL) );
        Throw( pEngine->RegisterObjectMethod("CPoint", "CPoint opSubAssign ( float )", asMETHODPR(CPoint<float>, operator -=, (float) , CPoint<float>), asCALL_THISCALL) );
        Throw( pEngine->RegisterObjectMethod("CPoint", "CPoint opMulAssign ( float )", asMETHODPR(CPoint<float>, operator *=, (float) , CPoint<float>), asCALL_THISCALL) );
        Throw( pEngine->RegisterObjectMethod("CPoint", "CPoint opDivAssign ( float )", asMETHODPR(CPoint<float>, operator /=, (float) , CPoint<float>), asCALL_THISCALL) );

        // Register property
        Throw( pEngine->RegisterObjectProperty("CPoint", "float x", asOFFSET(CPoint<float>, x)) );
        Throw( pEngine->RegisterObjectProperty("CPoint", "float y", asOFFSET(CPoint<float>, y)) );
        Throw( pEngine->RegisterObjectProperty("CPoint", "float z", asOFFSET(CPoint<float>, z)) );

        // Class members
        Throw( pEngine->RegisterObjectMethod("CPoint", "void clearX()",       asMETHOD(CPoint<float>, clearX), asCALL_THISCALL) );
        Throw( pEngine->RegisterObjectMethod("CPoint", "void clearY()",       asMETHOD(CPoint<float>, clearY), asCALL_THISCALL) );
        Throw( pEngine->RegisterObjectMethod("CPoint", "void clearZ()",       asMETHOD(CPoint<float>, clearZ), asCALL_THISCALL) );
        Throw( pEngine->RegisterObjectMethod("CPoint", "void clear()",        asMETHOD(CPoint<float>, clear), asCALL_THISCALL) );
        Throw( pEngine->RegisterObjectMethod("CPoint", "bool isEmpty()",      asMETHOD(CPoint<float>, isEmpty), asCALL_THISCALL) );
        Throw( pEngine->RegisterObjectMethod("CPoint", "bool isXEmpty()",     asMETHOD(CPoint<float>, isXEmpty), asCALL_THISCALL) );
        Throw( pEngine->RegisterObjectMethod("CPoint", "bool isYEmpty()",     asMETHOD(CPoint<float>, isYEmpty), asCALL_THISCALL) );
        Throw( pEngine->RegisterObjectMethod("CPoint", "bool isZEmpty()",     asMETHOD(CPoint<float>, isZEmpty), asCALL_THISCALL) );
        Throw( pEngine->RegisterObjectMethod("CPoint", "void invert()",       asMETHOD(CPoint<float>, invert), asCALL_THISCALL) );
        Throw( pEngine->RegisterObjectMethod("CPoint", "void invertX()",      asMETHOD(CPoint<float>, invert), asCALL_THISCALL) );
        Throw( pEngine->RegisterObjectMethod("CPoint", "void invertY()",      asMETHOD(CPoint<float>, invert), asCALL_THISCALL) );
        Throw( pEngine->RegisterObjectMethod("CPoint", "void invertZ()",      asMETHOD(CPoint<float>, invert), asCALL_THISCALL) );
        Throw( pEngine->RegisterObjectMethod("CPoint", "CPoint getInvert() const",  asMETHOD(CPoint<float>, getInvert), asCALL_THISCALL) );
        Throw( pEngine->RegisterObjectMethod("CPoint", "void normalize()",    asMETHOD(CPoint<float>, normalize), asCALL_THISCALL) );
        Throw( pEngine->RegisterObjectMethod("CPoint", "void normalize2D()",  asMETHOD(CPoint<float>, normalize2D), asCALL_THISCALL) );
        
        Throw( pEngine->RegisterObjectMethod("CPoint", "float getLengthSquared2D() const",            asFUNCTION(GetLengthSquared2D1), asCALL_CDECL_OBJLAST) );
        Throw( pEngine->RegisterObjectMethod("CPoint", "float getLengthSquared2D(CPoint & in) const", asFUNCTION(GetLengthSquared2D2), asCALL_CDECL_OBJLAST) );
        Throw( pEngine->RegisterObjectMethod("CPoint", "float getLengthSquared() const",              asFUNCTION(GetLengthSquared1), asCALL_CDECL_OBJLAST) );
        Throw( pEngine->RegisterObjectMethod("CPoint", "float getLengthSquared(CPoint & in) const",   asFUNCTION(GetLengthSquared2), asCALL_CDECL_OBJLAST) );
        Throw( pEngine->RegisterObjectMethod("CPoint", "float getLength2D() const",                   asFUNCTION(GetLength2D1), asCALL_CDECL_OBJLAST) );
        Throw( pEngine->RegisterObjectMethod("CPoint", "float getLength2D(CPoint & in) const",        asFUNCTION(GetLength2D2), asCALL_CDECL_OBJLAST) );
        Throw( pEngine->RegisterObjectMethod("CPoint", "float getLength() const",                     asFUNCTION(GetLength1), asCALL_CDECL_OBJLAST) );
        Throw( pEngine->RegisterObjectMethod("CPoint", "float getLength(CPoint & in) const",          asFUNCTION(GetLength2), asCALL_CDECL_OBJLAST) );
        
        Throw( pEngine->RegisterObjectMethod("CPoint", "bool isEquilEnough(CPoint & in, float val)", asFUNCTION(IsEquilEnough), asCALL_CDECL_OBJLAST) );
        Throw( pEngine->RegisterObjectMethod("CPoint", "float getDotProduct(CPoint & in) const",           asFUNCTION(GetDotProduct), asCALL_CDECL_OBJLAST) );
        Throw( pEngine->RegisterObjectMethod("CPoint", "float getDotProduct2D(CPoint & in) const",         asFUNCTION(GetDotProduct2D), asCALL_CDECL_OBJLAST) );
        Throw( pEngine->RegisterObjectMethod("CPoint", "CPoint getCrossProduct(CPoint & in) const",        asFUNCTION(GetCrossProduct), asCALL_CDECL_OBJLAST) );
        Throw( pEngine->RegisterObjectMethod("CPoint", "void cap(float)",                            asFUNCTION(Cap), asCALL_CDECL_OBJLAST) );
    }
}

 

Share this post


Link to post
Share on other sites

In doing some experimentation, I noticed doing the below didn't work. I'm sure I don't have the overloaded operators setup correctly for this.

CPoint point1(5, 2, 7);
CPoint point2(3, 4, 9);
CPoint result;
result = point1 * point2;
Print( "point1: " + point1.x + ", " + point1.y + ", " + point1.z );
Print( "point2: " + point2.x + ", " + point2.y + ", " + point2.z );
Print( "Result: " + result.x + ", " + result.y + ", " + result.z );

-------------------------------------------------------

point1: 5, 2, 7
point2: 3, 4, 9
Result: 1.49854e-33, -1.03028e+37, 3.97328e-34

 

Share this post


Link to post
Share on other sites

I suspect the problem is related to how you've registered the operators. You're not using 'const CPoint &in' for the arguments. The fact that you don't use 'const' causes the script compiler to have to make unnecessary copies of the object in order to guarantee that the value is not modified by the called function. Try changing how you register the operators and see if that works.   

    Throw( pEngine->RegisterObjectMethod("CPoint", "CPoint & opAssign(const CPoint & in)", asMETHODPR(CPoint<float>, operator =, (const CPoint<float> &), CPoint<float> &), asCALL_THISCALL) );

    Throw( pEngine->RegisterObjectMethod("CPoint", "CPoint opMul ( const CPoint & in )", asMETHODPR(CPoint<float>, operator *, (const CPoint<float> &) const, CPoint<float>), asCALL_THISCALL) );

 

Of course, if this turns out to be the cause, then there is a bug in the library that I need to fix, because it should work even without the 'const'.

 

Share this post


Link to post
Share on other sites

OK. Maybe it is the RegisterObjectType that is wrong, causing the native ABI to not understand how C++ is returning the CPoint.

Try changing the RegisterObjectType to the following:

Throw( pEngine->RegisterObjectType("CPoint", sizeof(CPoint<float>),
  asOBJ_VALUE | asOBJ_POD | asGetTypeTraits<CPoint<float>>() | asOBJ_APP_CLASS_ALLFLOATS ) );

 

Unfortunately I have not been able to reproduce the problem you're reporting, and without being able to debug the problem myself I can only guess what might be wrong.

BTW, what compiler and OS are you using? 

Share this post


Link to post
Share on other sites

I changed the RegisterObjectType as you suggested and that worked! Awesome! Thank you for the help!

The computer is an aging home built gaming rig repurposed as a development maching using an AMD Phenom chip running Arch Linux.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!