(void*) as Parameter and @this handle

Started by
4 comments, last by saejox 11 years, 11 months ago
Hi,

I would like to use function such as


r = engine->RegisterObjectMethod("EventManager", "int RegisterSomeCallback(?&in ,const string &in)", asMETHODPR(EventManager, RegisterSomeCallback, (void *,const string &), int), asCALL_THISCALL);assert( r >= 0 );


Angelscript Code

class Npc
{
int callbackid;
Npc()
{
// pass object pointer to engine with function name
callbackid = EM.RegisterSomeCallback(@this, "CallBackFunction");
}

void CallBackFunction()
{
print("Success!");
}

~Npc()
{
EM.UnregisterCallback(callbackid);
}
}


passing @this as a pointer is not possible as i figured. or am i doing it wrong?
also is ?&in correct way to register void* parameter?

thank you.
Advertisement
Another related question smile.png

is it possible to pass an object function's pointer to another Angelscript function or to C++ ?
You can pass @this to a ?&in parameter. AngelScript will then pass a pointer to the handle as the argument.

Note that the ?&in parameter in AngelScript is translated to 2 distinct parameters in the registered function, the first is the void* that receives the pointer to the value, and the second is an int that receives the typeId of the value.

Manual: The variable parameter type

Your function RegisterSomeCallback must then be implemented as:


int EventManager::RegisterSomeCallback(void *ptr, int typeId, const string &methodName)
{
// Make sure it is a handle that is received
if( typeId & asTYPEID_OBJHANDLE )
{
// Get the address of the object
void *obj = *reinterpret_cast<void**>(ptr);

// Get the object type
asIObjectType *type = engine->GetObjectTypeById(typeId);

// Get the method
asIScriptFunction *func = type->GetMethodByName(methodName.c_str());
if( func )
{
// Keep a reference to the object for the callback
engine->AddRefScriptObject(obj, type);

...
}
}
}



No, it is currently not possible to take the pointer of a class method in AngelScript. In a future version I'll implement something similar to delegates to support this.

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

i thought typeid was optional and engine registers only handle if it doesn't exist. silly me.

i did it like this (might be useful for someone in the future)

int EventManager::RegisterSomeCallback(void *ptr, int typeId, const string &methodName)
{
if( typeId & asTYPEID_OBJHANDLE )
{
// cast it to asIScriptObject
asIScriptObject*obj = *static_cast<asIScriptObject**>(ptr); // static_cast works just fine


// Get the object type
asIObjectType *type = obj->GetObjectType(); // faster than engine->GetObjectTypeById lookup i think

// Get the method
asIScriptFunction *func = type->GetMethodByName(methodName.c_str());
if( func )
{
obj->AddRef() // dont need engine here neither
}

}
}


Thank you. It works beautifully!
That works too. Though you may want to add a check to make sure the handle is really to a script object, so the application doesn't crash in case the script calls the function with a handle to a registered object instead.


// Make sure the value is a handle to a script object
if( (typeId & asTYPEID_OBJHANDLE) && (typeId & asTYPEID_SCRIPTOBJECT) )
{
...
}

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


That works too. Though you may want to add a check to make sure the handle is really to a script object, so the application doesn't crash in case the script calls the function with a handle to a registered object instead.


// Make sure the value is a handle to a script object
if( (typeId & asTYPEID_OBJHANDLE) && (typeId & asTYPEID_SCRIPTOBJECT) )
{
...
}



thank you.

This topic is closed to new replies.

Advertisement