How use delegates from c++

Started by
3 comments, last by _Engine_ 8 years, 4 months ago

Hi!

I try to implement passing delegates as arguments from script and call it from c++.

i use follow code to store script function -


void ScriptModuleCore::Network::SetDelegate(DelegateAS& delegateAS, asIScriptFunction* cb)
{
   asIScriptEngine* engine = ((ScriptMachine*)(core->Script()->Machine()))->Machine();
 
   if (delegateAS.callback)
   {
     delegateAS.callback->Release();
   }
 
   if (delegateAS.callbackObject)
   {
      engine->ReleaseScriptObject(delegateAS.callbackObject, delegateAS.callbackObjectType);
   }
 
   delegateAS.callback = 0;
   delegateAS.callbackObject = 0;
   delegateAS.callbackObjectType = 0;
 
   if( cb && cb->GetFuncType() == asFUNC_DELEGATE )
   {
      delegateAS.callbackObject     = cb->GetDelegateObject();
      delegateAS.callbackObjectType = cb->GetDelegateObjectType();
      delegateAS.callback           = cb->GetDelegateFunction();
 
      engine->AddRefScriptObject(delegateAS.callbackObject, delegateAS.callbackObjectType);
 
      delegateAS.callback->AddRef();

      cb->Release();
   }
   else
   {
      delegateAS.callback = cb;
   }
} 

follow code executes script function


asIScriptContext* ctx = GrabContext();
	
ctx->Prepare(script_func);			

ctx->SetObject(hack_callbackObject);

ctx->Execute();

All fine when we deal with just function. But if we pass delegate than we got assertion in AngelScript in follow function -


// internal
int asCScriptFunction::GetRefCount()
{
   asASSERT( funcType == asFUNC_DELEGATE );
 
   return externalRefCount.get();
}

Maybe i just doing something wrong when dealing with delegate from c++ or this is bug in AngelScript?

Advertisement

When calling the delegate you can just use it like a normal global script function, there is no need to get the script object and class method from the delegate, unless you really want to store these in a different way than the delegate itself (e.g. if you want to use a weakref).

About the assert failure. Can you show me the callstack where this happened?

I suspect the problem is that the asCScriptFunction instance was destroyed prematurely for some reason, and thus the funcType no longer is a asFUNC_DELEGATE when the call to GetRefCount happened even though it originally was.

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

Hi!

Looks like problem is - i used delegateAS.callback = cb->GetDelegateFunction(); insteed i must store script function in manner i deal with just callback and i must rise reference count.

So now my function with storing scriptfunction looks like:


void ScriptModuleCore::Network::SetDelegate(DelegateAS& delegateAS, asIScriptFunction* cb)
{
	asIScriptEngine* engine = ((ScriptMachine*)(core->Script()->Machine()))->Machine();

	if (delegateAS.callback)
	{
		delegateAS.callback->Release();
	}

	delegateAS.callback = cb;

	if( cb && cb->GetFuncType() == asFUNC_DELEGATE )
	{
		delegateAS.callback->AddRef();
	}
} 

and now works perfect.

Thanks for help :)

To be absolutely correct you should call AddRef on the function regardless if it is a delegate or normal function.

Your function should be like this:

void ScriptModuleCore::Network::SetDelegate(DelegateAS& delegateAS, asIScriptFunction* cb) 
{ 
  asIScriptEngine* engine = ((ScriptMachine*)(core->Script()->Machine()))->Machine(); 
  if (delegateAS.callback) 
  { 
    delegateAS.callback->Release(); 
  } 
  delegateAS.callback = cb; 
  if (cb) 
  { 
    delegateAS.callback->AddRef(); 
  } 
} 

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 corrected code.

Thanks for help :)

This topic is closed to new replies.

Advertisement