void GetClassInstance(asIScriptEngine *engine, int funcId, asIScriptObject* &retObj, int& retTypeId) { int r; asIScriptContext* ctxt = engine->CreateContext(); r = ctxt->Prepare( funcId ); r = ctxt->Execute(); CScriptAny *anyResult = *(CScriptAny **)ctxt->GetAddressOfReturnValue(); retTypeId = anyResult->GetTypeId(); retObj = NULL; r = anyResult->Retrieve( (void*)&retObj, retTypeId ); // replace it in the any to clear it out asINT64 dummy = 0; anyResult->Store( dummy ); // and clean out the return object (just as a precaution) ctxt->Abort(); ctxt->Release(); }
bool Test1() { bool fail = false; int r = 0; COutStream out; asIScriptEngine *engine; int refCount; asIScriptObject *myGame = 0; engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); engine->SetMessageCallback(asMETHOD(COutStream, Callback), &out, asCALL_THISCALL); RegisterScriptArray(engine, true); RegisterScriptAny(engine); asIScriptModule *mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection("script", script1, strlen(script1)); r = mod->Build(); if( r < 0 ) { TEST_FAILED; } // Calling the garbage collector mustn't free the object types, even though they are not used yet int tid1 = engine->GetModule(0)->GetTypeIdByDecl("MyGame@[]"); engine->GarbageCollect(); int tid2 = engine->GetModule(0)->GetTypeIdByDecl("MyGame@[]"); if( tid1 != tid2 ) { printf("Object type was released incorrectly by GC\n"); TEST_FAILED; } // Make sure ref count is properly updated asIScriptContext *ctx = engine->CreateContext(); ctx->Prepare(engine->GetModule(0)->GetFunctionIdByName("CreateInstance")); r = ctx->Execute(); if( r != asEXECUTION_FINISHED ) { printf("execution failed\n"); TEST_FAILED; } else { CScriptAny *any = *(CScriptAny**)ctx->GetAddressOfReturnValue(); int typeId = any->GetTypeId(); if( !(typeId & asTYPEID_OBJHANDLE) ) { printf("not a handle\n"); TEST_FAILED; } // Retrieve will increment the reference count for us any->Retrieve(&myGame, typeId); // What is the refcount? myGame->AddRef(); refCount = myGame->Release(); // GC, any, global, application if( refCount != 4 ) { printf("ref count is wrong\n"); TEST_FAILED; } // Clear the reference that the any object holds (this is not necessary) double zero = 0.0; any->Store(zero); // What is the refcount? myGame->AddRef(); refCount = myGame->Release(); // GC, global, application if( refCount != 3 ) { printf("ref count is wrong\n"); TEST_FAILED; } } // Call abort on the context to free up resources (this is not necessary) ctx->Abort(); // What is the refcount? myGame->AddRef(); refCount = myGame->Release(); // GC, global, application if( refCount != 3 ) { printf("ref count is wrong\n"); TEST_FAILED; } // Release the context ctx->Release(); ctx = 0; // What is the refcount? myGame->AddRef(); refCount = myGame->Release(); // GC, global, application if( refCount != 3 ) { printf("ref count is wrong\n"); TEST_FAILED; } // Call garbage collection engine->GarbageCollect(); // What is the refcount? myGame->AddRef(); refCount = myGame->Release(); // GC, global, application if( refCount != 3 ) { printf("ref count is wrong\n"); TEST_FAILED; } // Discard the module, freeing the global variable engine->DiscardModule(0); // What is the refcount? myGame->AddRef(); refCount = myGame->Release(); // GC, application if( refCount != 2 ) { printf("ref count is wrong\n"); TEST_FAILED; } // Release the game object refCount = myGame->Release(); // GC if( refCount != 1 ) { printf("ref count is wrong\n"); TEST_FAILED; } // Release engine engine->Release(); engine = 0; // Success return fail; }