Hi, I'm having an issue trying to use delegates on script callback functions as the example in https://www.angelcode.com/angelscript/sdk/docs/manual/doc_callbacks.html
Context: I have a C++ Class for networking, that I could mostly wrap for access in angelscript. Then I need some SetOnConnect, SetOnDisconnect, SetOnMessage functions to bind in Angelscript to call some AS class methods to handle the callbacks.
Following the simplest example, passing a function, it works flawless, but when using the delegate example saving the function, object and type, after doing the cb->Release() line, the application crashes.
Debugging showed that the SetOnConnectCallback(asIScriptFunction* cb) runs ok, cb->Release() decrements the reference counter, but to a value of 2, and it is not deleted.
However, somepoint in “vctools\crt\vcstartup\src\rtc\stack.cpp” which is not available, the address of cb parameter vanishes. Then the garbage collector tries do collect it and fails on as_scriptfunction.cpp line 1646, as content of cb is invalid.
If I comment cb->Release() line, everything seems to work, except that when destroying the object, it won't destroy C++ defined counterpart, nor run it's destructor, and every time I load the scene, memory keeps ramping up.
C++ snippet
Class WebsocketClient : ...
{
...
void SetOnConnectCallback(asIScriptFunction* cb)
{
// Release the previous callback, if any
if (m_on_connect_callback)
m_on_connect_callback->Release();
if (m_on_connect_callbackObject)
ETHScriptWrapper::m_pASEngine->ReleaseScriptObject(m_on_connect_callbackObject, m_on_connect_callbackObjectType);
m_on_connect_callback = 0;
m_on_connect_callbackObject = 0;
m_on_connect_callbackObjectType = 0;
if (cb && cb->GetFuncType() == asFUNC_DELEGATE)
{
m_on_connect_callbackObject = cb->GetDelegateObject();
m_on_connect_callbackObjectType = cb->GetDelegateObjectType();
m_on_connect_callback = cb->GetDelegateFunction();
// Hold on to the object and method
ETHScriptWrapper::m_pASEngine->AddRefScriptObject(m_on_connect_callbackObject, m_on_connect_callbackObjectType);
m_on_connect_callback->AddRef();
// Release the delegate, since it won't be used anymore
cb->Release(); //// That's the problematic line
}
else
{
// Store the received handle for later use
m_on_connect_callback = cb;
// Do not release the received script function
// until it won't be used any more
}
}
...
}
Angelscript snippet:
funcdef void CALLBACK();
class GameScene : Scene
{
private ...
...
private WebsocketClient@ m_room;
GameScene()
{
const string sceneName = "scenes/field.esc";
super(sceneName);
}
void PrintConnected()
{
print("AS >>> is connected! ");
}
void onCreated()
{
SetGravity(vector2(0.0f));
...
@m_room = WebsocketClient();
//CALLBACK @func = CALLBACK(this.PrintConnected);
//m_room.SetOnConnect(@func);
//m_room.SetOnConnect(CALLBACK(this.PrintConnected));
m_room.SetOnConnect(CALLBACK(PrintConnected));
if(!m_room.IsConnected())
m_room.Connect("localhost", "1201");
}
...
}