#include "utils.h"
const bool fail = true;
/*/ global funcdef var (setter) + imports /*/
const char* funcdef_import_assert_as =
"import void bar() from \"somewhere\";"
"void test1(){ @foo = test2; }"
"void test2(){ @foo = bar; }"; // the problem
void set_funcdef_var(asIScriptFunction*) {}
bool funcdef_import_assert()
{
COutStream cout;
asIScriptEngine* engine = asCreateScriptEngine( ANGELSCRIPT_VERSION );
engine->SetMessageCallback( asMETHOD(COutStream,Callback), &cout, asCALL_THISCALL );
engine->RegisterFuncdef( "void MyVoid()" );
engine->RegisterGlobalFunction( "void set_foo(MyVoid@)", asFUNCTION(set_funcdef_var), asCALL_CDECL );
int r;
asIScriptModule* module = engine->GetModule( "script", asGM_ALWAYS_CREATE );
module->AddScriptSection( "script", funcdef_import_assert_as );
if( module->Build() < 0 ) // assert (-DNDEBUG not present)
{
PRINTF( "script1 Build fail\n" );
return( fail );
}
CBytecodeStream bytecode("");
if( module->SaveByteCode( &bytecode ) < 0 )
{
PRINTF( "bytecode save fail\n" );
return( fail );
}
asIScriptModule* module_bytecode = engine->GetModule( "script_bytecode", asGM_ALWAYS_CREATE );
if( module_bytecode->LoadByteCode( &bytecode ) < 0 ) // error (-DNDEBUG present)
{
PRINTF( "bytecode load fail\n" );
return( fail );
}
engine->Release();
return( !fail );
}
Angelscript compiled with NDEBUG (my setup)(0, 0) : Error : LoadByteCode failed. The bytecode is invalid. Number of bytes read from stream: 187
Angelscript compiled without NDEBUGtestgnuc: ../../source/as_scriptfunction.cpp:468: virtual int asCScriptFunction::AddRef() const: Assertion `funcType != asFUNC_IMPORTED' failed.
-------------------------------------------------------And related question:
Is such code the correct way of handling global funcdefs with configuration as above? I have a feeling that blindly calling Release() without AddRef() will lead me into trouble some sunny day (yet i need it or garbare collector will complain when releasing engine).
vector<asUINT> Script::Config::runFunctions;
/// called when changing script function used for loop(), draw(), etc.
void Script::Config::ChangeRunFunction( asUINT type, asIScriptFunction* func )
{
asIScriptContext* ctx = asGetActiveContext();
if( !ctx )
return;
asIScriptEngine* engine = ctx->GetEngine();
if( !engine )
return;
asUINT oldFuncId = runFunctions[type];
asIScriptFunction* oldFunc = engine->GetFunctionById( oldFuncId );
if( oldFunc )
oldFunc->Release();
int funcId = 0;
if( func )
funcId = func->GetId();
runFunctions[type] = funcId;
}
/// called before releasing engine
void Script::Config::Finish( asIScriptEngine* engine )
{
for( auto funcId : runFunctions )
{
if( !funcId )
continue;
asIScriptFunction* func = engine->GetFunctionById( funcId );
if( func )
func->Release();
}
}