Jump to content

  • Log In with Google      Sign In   
  • Create Account

#ActualAndreas Jonsson

Posted 27 June 2013 - 07:20 PM

RegisterGlobalProperty() with funcdef works correctly, what was missing in your code was the @. Here's an example on how to register a property with handle to a funcdef and assigning a function pointer to it.

engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
engine->SetMessageCallback(asMETHOD(COutStream, Callback), &out, asCALL_THISCALL);
 
asIScriptFunction *f = 0;
engine->RegisterFuncdef("void myfunc()");
r = engine->RegisterGlobalProperty("myfunc @f", &f);
if( r < 0 )
  TEST_FAILED;
 
mod = engine->GetModule("mod", asGM_ALWAYS_CREATE);
mod->AddScriptSection("test",
  "void func() {} \n");
mod->Build();
 
r = ExecuteString(engine, "@f = func; \n", mod);
if( r != asEXECUTION_FINISHED )
  TEST_FAILED;
 
if( f == 0 )
  TEST_FAILED;
if( strcmp(f->GetName(), "func") != 0 )
  TEST_FAILED;
 
f->Release();
f = 0;
 
engine->Release();

When I said that casts for funcdefs work just like other casts, I meant in the script language. I.e, you can use the cast<type>(expr) operator on them. Here's a working example with both explicit and implicit casts:

engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
engine->SetMessageCallback(asMETHOD(COutStream, Callback), &out, asCALL_THISCALL);
engine->RegisterGlobalFunction("void assert(bool)", asFUNCTION(Assert), asCALL_GENERIC);
 
mod = engine->GetModule("mod", asGM_ALWAYS_CREATE);
mod->AddScriptSection("test",
  "funcdef void myfunc1(); \n"
  "funcdef void myfunc2(); \n"
  "funcdef void myfunc3(); \n"
  "bool called = false; \n"
  "void func() { called = true; } \n"
  "void main() \n"
  "{ \n"
  "  myfunc1 @f1 = func; \n"
  "  myfunc2 @f2 = cast<myfunc2>(f1); \n" // explicit cast
  "  myfunc3 @f3 = f2; \n"                // implicit cast
  "  assert( f1 is f2 ); \n"
  "  assert( f2 is f3 ); \n"
  "  assert( f3 is func ); \n"
  "  f3(); \n"
  "  assert( called ); \n"
  "} \n");
r = mod->Build();
if( r < 0 )
  TEST_FAILED;
 
r = ExecuteString(engine, "main()", mod);
if( r != asEXECUTION_FINISHED )
  TEST_FAILED;
 
engine->Release();

Here's an example of a registered function that receives a function pointer:

bool receivedFuncPtrIsOK = false;
void ReceiveFuncPtr(asIScriptFunction *funcPtr)
{
  if( funcPtr == 0 ) return;
 
  if( strcmp(funcPtr->GetName(), "test") == 0 ) 
    receivedFuncPtrIsOK = true;
 
  funcPtr->Release();
}
 
//---------------------
r = engine->RegisterFuncdef("void AppCallback()");

r = engine->RegisterGlobalFunction("void ReceiveFuncPtr(AppCallback @)", asFUNCTION(ReceiveFuncPtr), asCALL_CDECL); assert( r >= 0 );

script = 
  "void main() \n"
  "{ \n"
  " AppCallback @func = @test; \n"
  "   func(); \n"
  "   ReceiveFuncPtr(func); \n"
  "} \n"
  "void test() \n"
  "{ \n"
  "} \n";
mod->AddScriptSection("script", script);
r = mod->Build();
if( r < 0 )
  TEST_FAILED;
 

r = ExecuteString(engine, "main()", mod);
if( r != asEXECUTION_FINISHED )
TEST_FAILED;
 
if( !receivedFuncPtrIsOK )
  TEST_FAILED;
 



I've confirmed that engine->RegisterObjectBehaviour("jjBEHAVIOR", asBEHAVE_IMPLICIT_REF_CAST, "DifferentFunctionPointer@ a()", asFUNCTION(0), asCALL_CDECL_OBJLAST); doesn't return an error. I'll have have that fixed.

 

I've now fixed this in revision 1657.


#2Andreas Jonsson

Posted 27 June 2013 - 06:15 PM

RegisterGlobalProperty() with funcdef works correctly, what was missing in your code was the @. Here's an example on how to register a property with handle to a funcdef and assigning a function pointer to it.

engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
engine->SetMessageCallback(asMETHOD(COutStream, Callback), &out, asCALL_THISCALL);
 
asIScriptFunction *f = 0;
engine->RegisterFuncdef("void myfunc()");
r = engine->RegisterGlobalProperty("myfunc @f", &f);
if( r < 0 )
  TEST_FAILED;
 
mod = engine->GetModule("mod", asGM_ALWAYS_CREATE);
mod->AddScriptSection("test",
  "void func() {} \n");
mod->Build();
 
r = ExecuteString(engine, "@f = func; \n", mod);
if( r != asEXECUTION_FINISHED )
  TEST_FAILED;
 
if( f == 0 )
  TEST_FAILED;
if( strcmp(f->GetName(), "func") != 0 )
  TEST_FAILED;
 
f->Release();
f = 0;
 
engine->Release();

When I said that casts for funcdefs work just like other casts, I meant in the script language. I.e, you can use the cast<type>(expr) operator on them. Here's a working example with both explicit and implicit casts:

engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
engine->SetMessageCallback(asMETHOD(COutStream, Callback), &out, asCALL_THISCALL);
engine->RegisterGlobalFunction("void assert(bool)", asFUNCTION(Assert), asCALL_GENERIC);
 
mod = engine->GetModule("mod", asGM_ALWAYS_CREATE);
mod->AddScriptSection("test",
  "funcdef void myfunc1(); \n"
  "funcdef void myfunc2(); \n"
  "funcdef void myfunc3(); \n"
  "bool called = false; \n"
  "void func() { called = true; } \n"
  "void main() \n"
  "{ \n"
  "  myfunc1 @f1 = func; \n"
  "  myfunc2 @f2 = cast<myfunc2>(f1); \n" // explicit cast
  "  myfunc3 @f3 = f2; \n"                // implicit cast
  "  assert( f1 is f2 ); \n"
  "  assert( f2 is f3 ); \n"
  "  assert( f3 is func ); \n"
  "  f3(); \n"
  "  assert( called ); \n"
  "} \n");
r = mod->Build();
if( r < 0 )
  TEST_FAILED;
 
r = ExecuteString(engine, "main()", mod);
if( r != asEXECUTION_FINISHED )
  TEST_FAILED;
 
engine->Release();

Here's an example of a registered function that receives a function pointer:

 

bool receivedFuncPtrIsOK = false;
void ReceiveFuncPtr(asIScriptFunction *funcPtr)
{
  if( funcPtr == 0 ) return;
 
  if( strcmp(funcPtr->GetName(), "test") == 0 ) 
    receivedFuncPtrIsOK = true;
 
  funcPtr->Release();
}
 
//---------------------
r = engine->RegisterFuncdef("void AppCallback()");

r = engine->RegisterGlobalFunction("void ReceiveFuncPtr(AppCallback @)", asFUNCTION(ReceiveFuncPtr), asCALL_CDECL); assert( r >= 0 );

script = 
  "void main() \n"
  "{ \n"
  " AppCallback @func = @test; \n"
  "   func(); \n"
  "   ReceiveFuncPtr(func); \n"
  "} \n"
  "void test() \n"
  "{ \n"
  "} \n";
mod->AddScriptSection("script", script);
r = mod->Build();
if( r < 0 )
  TEST_FAILED;
 

r = ExecuteString(engine, "main()", mod);
if( r != asEXECUTION_FINISHED )
TEST_FAILED;
 
if( !receivedFuncPtrIsOK )
  TEST_FAILED;
 



 

I've confirmed that engine->RegisterObjectBehaviour("jjBEHAVIOR", asBEHAVE_IMPLICIT_REF_CAST, "DifferentFunctionPointer@ a()", asFUNCTION(0), asCALL_CDECL_OBJLAST); doesn't return an error. I'll have have that fixed.


#1Andreas Jonsson

Posted 27 June 2013 - 06:05 PM

RegisterGlobalProperty() with funcdef works correctly, what was missing in your code was the @. Here's an example on how to register a property with handle to a funcdef and assigning a function pointer to it.

 

engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
engine->SetMessageCallback(asMETHOD(COutStream, Callback), &out, asCALL_THISCALL);
 
asIScriptFunction *f = 0;
engine->RegisterFuncdef("void myfunc()");
r = engine->RegisterGlobalProperty("myfunc @f", &f);
if( r < 0 )
  TEST_FAILED;
 
mod = engine->GetModule("mod", asGM_ALWAYS_CREATE);
mod->AddScriptSection("test",
  "void func() {} \n");
mod->Build();
 
r = ExecuteString(engine, "@f = func; \n", mod);
if( r != asEXECUTION_FINISHED )
  TEST_FAILED;
 
if( f == 0 )
  TEST_FAILED;
if( strcmp(f->GetName(), "func") != 0 )
  TEST_FAILED;
 
f->Release();
f = 0;
 
engine->Release();

 

When I said that casts for funcdefs work just like other casts, I meant in the script language. I.e, you can use the cast<type>(expr) operator on them. Here's a working example with both explicit and implicit casts:

 

engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
engine->SetMessageCallback(asMETHOD(COutStream, Callback), &out, asCALL_THISCALL);
engine->RegisterGlobalFunction("void assert(bool)", asFUNCTION(Assert), asCALL_GENERIC);
 
mod = engine->GetModule("mod", asGM_ALWAYS_CREATE);
mod->AddScriptSection("test",
  "funcdef void myfunc1(); \n"
  "funcdef void myfunc2(); \n"
  "funcdef void myfunc3(); \n"
  "bool called = false; \n"
  "void func() { called = true; } \n"
  "void main() \n"
  "{ \n"
  "  myfunc1 @f1 = func; \n"
  "  myfunc2 @f2 = cast<myfunc2>(f1); \n" // explicit cast
  "  myfunc3 @f3 = f2; \n"                // implicit cast
  "  assert( f1 is f2 ); \n"
  "  assert( f2 is f3 ); \n"
  "  assert( f3 is func ); \n"
  "  f3(); \n"
  "  assert( called ); \n"
  "} \n");
r = mod->Build();
if( r < 0 )
  TEST_FAILED;
 
r = ExecuteString(engine, "main()", mod);
if( r != asEXECUTION_FINISHED )
  TEST_FAILED;
 
engine->Release();

PARTNERS