🎉 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!

Returning and assigning object references

Started by
2 comments, last by WitchLord 19 years, 4 months ago
I was looking for a lightweight scripting system to implement in a 2d space shooter arcade that I'm trying to build in my spare time and after taking a look at lua + derivatives ) and squirrel I came across angel script. The are some reasons I've chosen angel script over squirrel. I love it's syntax and the way registering works, allowing me to register already existent classes whilst not forcing me to write methods aware of the virtual machine state, stack and such. I did happen to get to a problem though. I don't know if this is possible. What I'm trying to do is to export an already created object's reference into the script. Sample script follows ( sorry for the length )


// c++

class aManager
{
    public:

        aManager();
        ~aManager();

        void Print();
        void SetProperty( int aValue );


        aManager GetNew()
        {
            return aManager();
        }

        int GetProperty();
        int m_Property;
};


aManager::aManager()
{
    m_Property = 10;
    printf( "constructing new object with pointer %p\n", this );
}

aManager::~aManager()
{
}


void aManager::Print()
{
    printf( "%p says : %d\n", this, m_Property );
}

void aManager::SetProperty( int aValue )
{
    m_Property = aValue;
}

int aManager::GetProperty()
{
    return m_Property;
}


void aManager_Constructor( aManager *obj )
{
    new( obj ) aManager();
}

void aManager_Destructor( aManager *obj )
{
    obj->~aManager();
}

int main()
{
    asIScriptEngine *engine = asCreateScriptEngine( ANGELSCRIPT_VERSION );

    engine->RegisterObjectType( "aManager", sizeof( aManager ), asOBJ_CLASS | asOBJ_CLASS_CONSTRUCTOR | asOBJ_CLASS_DESTRUCTOR );

    engine->RegisterObjectBehaviour( "aManager", asBEHAVE_CONSTRUCT, "void aManager()", asFUNCTION(aManager_Constructor), asCALL_CDECL_OBJLAST );
    engine->RegisterObjectBehaviour( "aManager", asBEHAVE_DESTRUCT, "void aManager()", asFUNCTION(aManager_Destructor), asCALL_CDECL_OBJLAST );

    engine->RegisterObjectProperty( "aManager" , "int m_Property", offsetof( aManager, m_Property ) );

    engine->RegisterObjectMethod( "aManager", "void SetProperty( int )", asMETHOD(aManager,SetProperty), asCALL_THISCALL );
    engine->RegisterObjectMethod( "aManager", "int GetProperty()", asMETHOD(aManager,GetProperty), asCALL_THISCALL );
    engine->RegisterObjectMethod( "aManager", "void Print()", asMETHOD(aManager,Print), asCALL_THISCALL );
    engine->RegisterObjectMethod( "aManager", "aManager GetNew()", asMETHOD(aManager,GetNew), asCALL_THISCALL );

    // load and compile script

    char  theFilename[] = "test.as";
    char *theBuffer;
    int   theLength;

    GetFileContent( theFilename, &theBuffer, &theLength );

    engine->AddScriptSection( "module", "section", theBuffer, theLength, 0 );
    delete( theBuffer );

    engine->Build( "module" );

    // create context

    asIScriptContext *theContext;
    engine->CreateContext( &theContext );

    // get function and run it

    char theFunctionDeclaration[] = "void main()";

    int theFunctionID = engine->GetFunctionIDByDecl( "module", theFunctionDeclaration );
    theContext->Prepare( theFunctionID );

    theContext->Execute();

    // clean up

    theContext->Release();

    return ( 0 );
}


and here's the script file :


// test.as file

void main()
{
    aManager obj1;

    obj1.Print();
    obj1.SetProperty( obj1.GetProperty() + 10 );
    obj1.Print();

    aManager obj2 = obj1.GetNew();
}

If we look to "aManager obj2 = obj1.GetNew();" we notice the system creates two objects instead of one. I understand this is because when declaring the type of obj2 "aManager obj2", the constructor is called automatically and I'm forced to do that because it needs to have variables declared. I was wondering though if there's any way of returning and assigning a reference of an object created in c++ to an undeclared script var. or perhaps a workaround. thank you and keep on the great work ! benishor.
---novocaine thru yer veinz
Advertisement
If you register the asBEHAVE_ADDREF and asBEHAVE_RELEASE behaviours, you can use object handles to hold references to the manager objects, instead of keeping unique copies in each variable.

Some changes needed:

// C++class aManager{  aManager() {refCount = 1; ... any other initializations needed}  int refCount;  void AddRef() {refCount++;}  void Release() {int r = --refCount; if( refCount == 0 ) delete this; return r; }  aManager *GetNew()  {     // The constructor already initializes refCount to 1    return new aManager();  }  ... leave the rest as is}int main(){  ...  engine->RegisterObjectBehaviour("aManager", asBEHAVE_ADDREF, "void f()", asMETHOD(aManager, AddRef), asCALL_THISCALL);  engine->RegisterObjectBehaviour("aManager", asBEHAVE_RELEASE, "void f()", asMETHOD(aManager, Release), asCALL_THISCALL);  engine->RegisterObjectMethod("aManager", "aManager @GetNew()", asMETHOD(aManager,GetNew), asCALL_THISCALL);}


// Scriptvoid main(){    aManager obj1;    obj1.Print();    obj1.SetProperty( obj1.GetProperty() + 10 );    obj1.Print();    aManager @obj2 = @obj1.GetNew();    obj2.Print();    obj2.SetProperty( obj2.GetProperty() + 10 );    obj2.Print();}


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 it works just as intended. I guess I would have figured it out had I encountered any references to the addref and release behaviours in the "Registering a C++ class" tutorial. I guess object references would make a good tutorial subject for beginners ( like me ). I'll even write one once I get all things straight if nobody more experienced offers to.

thank you for the quick support !
---novocaine thru yer veinz
You're right. I need to update that article. It was written before I implemented object handles, which is why it doesn't mention them.

It's already difficult for me to find the time to implement all the features needed for the library, much less to write tutorials or articles. If you'd like to write tutorials or sample programs I will be more than happy to add them to the site or even to the actual SDK package if they are good enough.

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

This topic is closed to new replies.

Advertisement