bool Test() { bool fail = false; int r; asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); RegisterScriptArray(engine, true); RegisterScriptString_Generic(engine); engine->RegisterObjectType("Obj", sizeof(Obj), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS); engine->RegisterObjectProperty("Obj", "int v", asOFFSET(Obj, v)); COutStream out; asIScriptModule *mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script1, strlen(script1), 0); engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); r = mod->Build(); if( r < 0 ) { TEST_FAILED; PRINTF("%s: Failed to compile the script\n", TESTNAME); } engine->Release(); // Success return fail; }
bool Test() { bool fail = false; int r; asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); RegisterScriptString_Generic(engine); engine->RegisterGlobalFunction("void Assert(bool)", asFUNCTION(Assert), asCALL_GENERIC); engine->RegisterGlobalFunction("double atof(const string &in)",asFUNCTION(StringToDouble),asCALL_GENERIC); COutStream out; engine->AddScriptSection(0, TESTNAME, script1, strlen(script1), 0); engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); r = engine->Build(0); if( r < 0 ) { fail = true; printf("%s: Failed to compile the script\n", TESTNAME); } asIScriptContext *ctx; r = engine->ExecuteString(0, "TestArrayHandle()", &ctx); if( r != asEXECUTION_FINISHED ) { if( r == asEXECUTION_EXCEPTION ) PrintException(ctx); printf("%s: Failed to execute script\n", TESTNAME); fail = true; } if( ctx ) ctx->Release(); engine->AddScriptSection(0, TESTNAME, script2, strlen(script2), 0); engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); r = engine->Build(0); if( r < 0 ) { fail = true; printf("%s: Failed to compile the script\n", TESTNAME); } r = engine->ExecuteString(0, "TestArrayHandle2()", &ctx); if( r != asEXECUTION_FINISHED ) { if( r == asEXECUTION_EXCEPTION ) PrintException(ctx); printf("%s: Failed to execute script\n", TESTNAME); fail = true; } if( ctx ) ctx->Release(); engine->Release(); // Success return fail; }
bool Test() { bool fail = Test2(); int number = 0; asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); RegisterScriptArray(engine, true); RegisterScriptString_Generic(engine); // Test GetTypeIdByDecl if( engine->GetTypeIdByDecl("int") != engine->GetTypeIdByDecl("const int") ) TEST_FAILED; if( engine->GetTypeIdByDecl("string") != engine->GetTypeIdByDecl("const string") ) TEST_FAILED; // A handle to a const is different from a handle to a non-const if( engine->GetTypeIdByDecl("string@") == engine->GetTypeIdByDecl("const string@") ) TEST_FAILED; // Test debugging engine->RegisterGlobalProperty("int number", &number); COutStream out; engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); asIScriptModule *mod = engine->GetModule("Module1", asGM_ALWAYS_CREATE); mod->AddScriptSection(":1", script1, strlen(script1), 0); mod->Build(); mod = engine->GetModule("Module2", asGM_ALWAYS_CREATE); mod->AddScriptSection(":2", script2, strlen(script2), 0); mod->Build(); // Bind all functions that the module imports mod = engine->GetModule("Module1"); mod->BindAllImportedFunctions(); asIScriptContext *ctx = engine->CreateContext(); ctx->SetLineCallback(asFUNCTION(LineCallback), 0, asCALL_CDECL); ctx->SetExceptionCallback(asFUNCTION(ExceptionCallback), 0, asCALL_CDECL); ctx->Prepare(mod->GetFunctionByDecl("void main()")); int r = ctx->Execute(); if( r == asEXECUTION_EXCEPTION ) { // It is possible to examine the callstack even after the Execute() method has returned ExceptionCallback(ctx, 0); } ctx->Release(); engine->Release(); if( printBuffer != correct ) { TEST_FAILED; printf("%s", printBuffer.c_str()); } // Success return fail; }
asIScriptEngine *ConfigureEngine() { asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); RegisterScriptString_Generic(engine); engine->RegisterGlobalProperty("int number", &number); engine->RegisterObjectType("OBJ", sizeof(int), asOBJ_PRIMITIVE); return engine; }
bool Test() { bool fail = false; int r; asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); COutStream out; engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); RegisterScriptString_Generic(engine); engine->RegisterGlobalFunction("void assert(bool)", asFUNCTION(Assert), asCALL_GENERIC); asIScriptModule *mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script1, strlen(script1), 0); r = mod->Build(); if( r < 0 ) fail = true; int func = engine->GetModule(0)->GetFunctionIdByName("test"); asIScriptContext *ctx = engine->CreateContext(); ctx->Prepare(func); *(int*)ctx->GetAddressOfArg(0) = 3; *(CScriptString**)ctx->GetAddressOfArg(1) = new CScriptString("tst"); *(CScriptString**)ctx->GetAddressOfArg(2) = new CScriptString("42"); // We don't have to add a reference, because we don't want to keep a copy float pi = 3.14f; *(float**)ctx->GetAddressOfArg(3) = π r = ctx->Execute(); if( r != asEXECUTION_FINISHED ) fail = true; if( *(int*)ctx->GetAddressOfReturnValue() != 107 ) fail = true; func = engine->GetModule(0)->GetFunctionIdByName("test2"); ctx->Prepare(func); r = ctx->Execute(); if( r != asEXECUTION_FINISHED ) fail = true; if( ((CScriptString*)ctx->GetAddressOfReturnValue())->buffer != "tst" ) fail = true; ctx->Release(); engine->Release(); // Success return fail; }
bool Test() { bool fail = false; //--- asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); // Verify that the function doesn't crash when the stack is empty asIScriptContext *ctx = asGetActiveContext(); assert( ctx == 0 ); RegisterScriptString_Generic(engine); engine->RegisterGlobalFunction("void Suspend()", asFUNCTION(Suspend), asCALL_GENERIC); engine->RegisterGlobalProperty("int loopCount", &loopCount); COutStream out; engine->AddScriptSection(0, TESTNAME ":1", script1, strlen(script1), 0); engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); engine->Build(0); ctx = engine->CreateContext(); ctx->SetLineCallback(asFUNCTION(LineCallback), 0, asCALL_STDCALL); if( ctx->Prepare(engine->GetFunctionIDByDecl(0, "void TestSuspend()")) >= 0 ) { while( loopCount < 5 && !doSuspend ) ctx->Execute(); } else fail = true; // Release the engine first engine->Release(); // Now release the context ctx->Release(); //--- // If the library was built with the flag BUILD_WITH_LINE_CUES the script // will return after each increment of the loopCount variable. engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); engine->RegisterGlobalProperty("int loopCount", &loopCount); engine->AddScriptSection(0, TESTNAME ":2", script2, strlen(script2), 0); engine->Build(0); ctx = engine->CreateContext(); ctx->SetLineCallback(asFUNCTION(LineCallback), 0, asCALL_STDCALL); ctx->Prepare(engine->GetFunctionIDByDecl(0, "void TestSuspend2()")); loopCount = 0; while( ctx->GetState() != asEXECUTION_FINISHED ) ctx->Execute(); if( loopCount != 3 ) { printf("%s: failed\n", TESTNAME); fail = true; } ctx->Prepare(asPREPARE_PREVIOUS); loopCount = 0; while( ctx->GetState() != asEXECUTION_FINISHED ) ctx->Execute(); if( loopCount != 3 ) { printf("%s: failed\n", TESTNAME); fail = true; } ctx->Release(); engine->Release(); // Success return fail; }
bool Test() { bool fail = false; if( !fail ) fail = Test2(); int r; asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); COutStream out; CBufferedOutStream bout; engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); RegisterScriptString_Generic(engine); engine->RegisterGlobalFunction("void Assert(bool)", asFUNCTION(Assert), asCALL_GENERIC); // Register an interface from the application r = engine->RegisterInterface("appintf"); assert( r >= 0 ); r = engine->RegisterInterfaceMethod("appintf", "void test()"); assert( r >= 0 ); // Test working example asIScriptModule *mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script1, strlen(script1), 0); r = mod->Build(); if( r < 0 ) TEST_FAILED; r = ExecuteString(engine, "test()", mod); if( r != asEXECUTION_FINISHED ) TEST_FAILED; // Test calling the interface method from the application int typeId = engine->GetModule(0)->GetTypeIdByDecl("myclass"); asIScriptObject *obj = (asIScriptObject*)engine->CreateScriptObject(typeId); int intfTypeId = engine->GetModule(0)->GetTypeIdByDecl("myintf"); asIObjectType *type = engine->GetObjectTypeById(intfTypeId); asIScriptFunction *func = type->GetMethodByDecl("void test()"); asIScriptContext *ctx = engine->CreateContext(); r = ctx->Prepare(func); if( r < 0 ) TEST_FAILED; ctx->SetObject(obj); ctx->Execute(); if( r != asEXECUTION_FINISHED ) TEST_FAILED; intfTypeId = engine->GetTypeIdByDecl("appintf"); type = engine->GetObjectTypeById(intfTypeId); func = type->GetMethodByDecl("void test()"); r = ctx->Prepare(func); if( r < 0 ) TEST_FAILED; ctx->SetObject(obj); ctx->Execute(); if( r != asEXECUTION_FINISHED ) TEST_FAILED; if( ctx ) ctx->Release(); if( obj ) obj->Release(); // Test class that don't implement all functions of the interface. // Test instanciating an interface. Shouldn't work. // Test that classes don't implement the same interface twice // Try copying an interface variable to another. Shouldn't work. // Test implicit conversion from class to interface that is not being implemented. Should give compiler error // Test implicit conversion from interface to class. Should give compiler error. engine->SetMessageCallback(asMETHOD(CBufferedOutStream,Callback), &bout, asCALL_THISCALL); mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script2, strlen(script2), 0); r = mod->Build(); if( r >= 0 ) TEST_FAILED; if( bout.buffer != "TestInterface (5, 23) : Warning : The interface 'intf' is already implemented\n" "TestInterface (5, 7) : Error : Missing implementation of 'void intf::test()'\n" "TestInterface (9, 1) : Info : Compiling void test(intf&inout)\n" "TestInterface (11, 9) : Error : Data type can't be 'intf'\n" "TestInterface (13, 6) : Error : There is no copy operator for the type 'intf' available.\n" "TestInterface (15, 16) : Error : Can't implicitly convert from 'myclass&' to 'nointf@&'.\n" "TestInterface (16, 16) : Error : Can't implicitly convert from 'intf@&' to 'myclass@&'.\n" ) { printf("%s", bout.buffer.c_str()); TEST_FAILED; } engine->Release(); // Test cast for both temporary handle and non-temporary handle { const char *script = "interface ScriptLogic {} \n" "class PlayerLogic : ScriptLogic {} \n" "ScriptLogic @getScriptObject() { return PlayerLogic(); } \n"; engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); RegisterStdString(engine); mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script); r = mod->Build(); if( r < 0 ) TEST_FAILED; // Non-temporary handle r = ExecuteString(engine, "ScriptLogic @c = getScriptObject(); cast<PlayerLogic>(c);", mod); if( r != asEXECUTION_FINISHED ) TEST_FAILED; // Temporary handle r = ExecuteString(engine, "cast<PlayerLogic>(getScriptObject());", mod); if( r != asEXECUTION_FINISHED ) TEST_FAILED; engine->Release(); } // It should be possible to inherit the implementation of an interface method { const char *script = "interface I { void method(); } \n" "class B { void method() {} } \n" "class D : B, I {} \n" "D d; \n"; engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script); r = mod->Build(); if( r < 0 ) TEST_FAILED; engine->Release(); } // Allow script declared interfaces to inherit from other interfaces { engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); engine->SetMessageCallback(asMETHOD(CBufferedOutStream,Callback), &bout, asCALL_THISCALL); mod = engine->GetModule(0, asGM_ALWAYS_CREATE); const char *script = "interface A { void a(); } \n" "interface B : A { void b(); } \n" "class C : B {} \n"; // Must implement both a() and b() bout.buffer = ""; mod->AddScriptSection(TESTNAME, script); r = mod->Build(); if( r >= 0 ) TEST_FAILED; if( bout.buffer != "TestInterface (3, 7) : Error : Missing implementation of 'void B::b()'\n" "TestInterface (3, 7) : Error : Missing implementation of 'void A::a()'\n" ) { printf("%s", bout.buffer.c_str()); TEST_FAILED; } // Don't allow shared interface to implement non-shared interface script = "interface A {} \n" "shared interface B : A {} \n"; bout.buffer = ""; mod->AddScriptSection(TESTNAME, script); r = mod->Build(); if( r >= 0 ) TEST_FAILED; if( bout.buffer != "TestInterface (2, 22) : Error : Shared type cannot implement non-shared interface 'A'\n" ) { printf("%s", bout.buffer.c_str()); TEST_FAILED; } // Implicit casts to an inherited interface should work script = "interface A {} \n" "interface B : A {} \n" "void func() \n" "{ \n" " A@ a; B@ b; \n" " @a = b; \n" "} \n"; bout.buffer = ""; mod->AddScriptSection(TESTNAME, script); r = mod->Build(); if( r < 0 ) TEST_FAILED; if( bout.buffer != "" ) { printf("%s", bout.buffer.c_str()); TEST_FAILED; } // Don't allow circular inheritance script = "interface A : C {} \n" "interface B : A {} \n" "interface C : B {} \n"; bout.buffer = ""; mod->AddScriptSection(TESTNAME, script); r = mod->Build(); if( r >= 0 ) TEST_FAILED; if( bout.buffer != "TestInterface (3, 15) : Error : Can't implement itself, or another interface that implements this interface\n" ) { printf("%s", bout.buffer.c_str()); TEST_FAILED; } engine->Release(); } // Success return fail; }
bool TestEnumGlobVar() { bool ret = false; asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); RegisterScriptString_Generic(engine); int r; r = engine->RegisterObjectType("obj", 0, 0); assert( r >= 0 ); r = engine->RegisterObjectBehaviour("obj", asBEHAVE_ADDREF, "void f()", asFUNCTION(AddRef_Release_dummy), asCALL_GENERIC); assert( r >= 0 ); r = engine->RegisterObjectBehaviour("obj", asBEHAVE_RELEASE, "void f()", asFUNCTION(AddRef_Release_dummy), asCALL_GENERIC); assert( r >= 0 ); int o = 0xBAADF00D; r = engine->RegisterGlobalProperty("obj o", &o); engine->AddScriptSection(0, "test", script, sizeof(script)-1, 0); COutStream out; engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); engine->Build(0); int count = engine->GetGlobalVarCount(0); if( count != 6 ) { printf("%s: GetGlobalVarCount() returned %d, expected 6.\n", TESTNAME, count); ret = true; } const char *buffer = 0; if( (buffer = engine->GetGlobalVarDeclaration(0)) == 0 ) { printf("%s: GetGlobalVarDeclaration() failed\n", TESTNAME); ret = true; } else if( strcmp(buffer, "int a") != 0 ) { printf("%s: GetGlobalVarDeclaration() returned %s\n", TESTNAME, buffer); ret = true; } int id = engine->GetGlobalVarIDByName(0, "b"); if( id < 0 ) { printf("%s: GetGlobalVarIDByName() returned %d\n", TESTNAME, id); ret = true; } id = engine->GetGlobalVarIDByDecl(0, "double c"); if( id < 0 ) { printf("%s: GetGlobalVarIDByDecl() returned %d\n", TESTNAME, id); ret = true; } if( (buffer = engine->GetGlobalVarName(3)) == 0 ) { printf("%s: GetGlobalVarName() failed\n", TESTNAME); ret = true; } else if( strcmp(buffer, "d") != 0 ) { printf("%s: GetGlobalVarName() returned %s\n", TESTNAME, buffer); ret = true; } unsigned long *d; d = (unsigned long *)engine->GetGlobalVarPointer(3); if( d == 0 ) { printf("%s: GetGlobalVarPointer() returned %d\n", TESTNAME, r); ret = true; } if( *d != 0xC0DE ) { printf("%s: Failed\n", TESTNAME); ret = true; } std::string *e; e = (std::string*)engine->GetGlobalVarPointer(4); if( e == 0 ) { printf("%s: Failed\n", TESTNAME); ret = true; } if( *e != "test" ) { printf("%s: Failed\n", TESTNAME); ret = true; } int *f; f = (int*)engine->GetGlobalVarPointer(5); if( f == 0 ) { printf("%s: failed\n", TESTNAME); ret = true; } if( *f != 0xBAADF00D ) { printf("%s: failed\n", TESTNAME); ret = true; } engine->Release(); return ret; }
bool Test() { bool fail = false; int r; COutStream out; asIScriptContext *ctx; asIScriptEngine *engine; CBufferedOutStream bout; // --------------------------------------------- engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); RegisterScriptArray(engine, true); RegisterScriptString_Generic(engine); RegisterScriptAny(engine); engine->RegisterGlobalFunction("void Assert(bool)", asFUNCTION(Assert), asCALL_GENERIC); r = engine->RegisterGlobalFunction("void SetMyAny(any@)", asFUNCTION(SetMyAny), asCALL_GENERIC); assert( r >= 0 ); asIScriptModule *mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection("TestAny", script1, strlen(script1), 0); engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); r = mod->Build(); if( r < 0 ) { TEST_FAILED; printf("%s: Failed to compile the script\n", "TestAny"); } ctx = engine->CreateContext(); r = ExecuteString(engine, "TestAny()", mod, ctx); if( r != asEXECUTION_FINISHED ) { if( r == asEXECUTION_EXCEPTION ) PrintException(ctx); TEST_FAILED; printf("%s: Execution failed\n", "TestAny"); } if( ctx ) ctx->Release(); engine->Release(); //-------------------------------------------------- // Verify that the GC can handle circles with any structures engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); RegisterScriptArray(engine, true); RegisterScriptString_Generic(engine); RegisterScriptAny(engine); engine->RegisterGlobalFunction("void Assert(bool)", asFUNCTION(Assert), asCALL_GENERIC); r = engine->RegisterGlobalFunction("void SetMyAny(any@)", asFUNCTION(SetMyAny), asCALL_GENERIC); assert( r >= 0 ); mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection("TestAny", script2, strlen(script2), 0); engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); r = mod->Build(); if( r < 0 ) { TEST_FAILED; printf("%s: Failed to compile the script\n", "TestAny"); } ctx = engine->CreateContext(); r = ExecuteString(engine, "TestAny()", mod, ctx); if( r != asEXECUTION_FINISHED ) { if( r == asEXECUTION_EXCEPTION ) PrintException(ctx); TEST_FAILED; printf("%s: Execution failed\n", "TestAny"); } if( ctx ) ctx->Release(); asUINT gcCurrentSize, gcTotalDestroyed, gcTotalDetected; engine->GetGCStatistics(&gcCurrentSize, &gcTotalDestroyed, &gcTotalDetected); engine->GarbageCollect(); engine->GetGCStatistics(&gcCurrentSize, &gcTotalDestroyed, &gcTotalDetected); if( !fail ) assert( gcCurrentSize == 8 && gcTotalDestroyed == 8 && gcTotalDetected == 7 ); engine->Release(); //------------------------------------------------------- // Don't allow const handle to retrieve() engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); RegisterScriptArray(engine, true); RegisterScriptString_Generic(engine); RegisterScriptAny(engine); engine->RegisterGlobalFunction("void Assert(bool)", asFUNCTION(Assert), asCALL_GENERIC); r = engine->RegisterGlobalFunction("void SetMyAny(any@)", asFUNCTION(SetMyAny), asCALL_GENERIC); assert( r >= 0 ); mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection("TestAny", script3, strlen(script3), 0); engine->SetMessageCallback(asMETHOD(CBufferedOutStream,Callback), &bout, asCALL_THISCALL); r = mod->Build(); if( r < 0 ) { TEST_FAILED; printf("%s: Failed to Build()\n", "TestAny"); } if( bout.buffer != "TestAny (5, 1) : Info : Compiling void TestAny()\n" "TestAny (9, 15) : Warning : Argument cannot be assigned. Output will be discarded.\n" ) { printf("%s", bout.buffer.c_str()); TEST_FAILED; } engine->Release(); //-------------------------------------------------------- // Make sure it is possible to pass any to the application engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); RegisterScriptArray(engine, true); RegisterScriptString_Generic(engine); RegisterScriptAny(engine); engine->RegisterGlobalFunction("void Assert(bool)", asFUNCTION(Assert), asCALL_GENERIC); r = engine->RegisterGlobalFunction("void SetMyAny(any@)", asFUNCTION(SetMyAny), asCALL_GENERIC); assert( r >= 0 ); mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection("TestAny", script4, strlen(script4), 0); engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); r = mod->Build(); if( r < 0 ) { TEST_FAILED; printf("%s: Failed to compile\n", "TestAny"); } r = ExecuteString(engine, "TestAny()", mod); if( r != asEXECUTION_FINISHED ) { TEST_FAILED; printf("%s: Failed to execute\n", "TestAny"); } if( myAny ) { int typeId = myAny->GetTypeId(); if( !(typeId & asTYPEID_OBJHANDLE) ) TEST_FAILED; if( (typeId & asTYPEID_MASK_OBJECT) != asTYPEID_APPOBJECT ) TEST_FAILED; const char *decl = engine->GetTypeDeclaration(typeId); if( (decl == 0) || (strcmp(decl, "string@") != 0) ) { TEST_FAILED; printf("%s: Failed to return the correct type\n", "TestAny"); } int typeId2 = engine->GetTypeIdByDecl("string@"); if( typeId != typeId2 ) { TEST_FAILED; printf("%s: Failed to return the correct type\n", "TestAny"); } CScriptString *str = 0; myAny->Retrieve((void*)&str, typeId); if( str->buffer != "test" ) { TEST_FAILED; printf("%s: Failed to set the string correctly\n", "TestAny"); } if( str ) str->Release(); myAny->Release(); myAny = 0; } else TEST_FAILED; //-------------------------------------- // Make sure the any type can store primitives as well r = ExecuteString(engine, "any a; a.store(1); int b; a.retrieve(b); Assert(b == 1);"); if( r != asEXECUTION_FINISHED ) TEST_FAILED; engine->Release(); { engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); engine->SetMessageCallback(asMETHOD(COutStream, Callback), &out, asCALL_THISCALL); RegisterScriptMath3D(engine); RegisterScriptAny(engine); engine->RegisterGlobalFunction("void assert(bool)", asFUNCTION(Assert), asCALL_GENERIC); mod = engine->GetModule(0, asGM_ALWAYS_CREATE); const char *script = "void main() \n" "{ \n" " any storage; \n" " storage.store(vector3(1,1,1)); \n" "} \n"; mod->AddScriptSection("script", script); r = mod->Build(); if( r < 0 ) TEST_FAILED; ctx = engine->CreateContext(); r = ExecuteString(engine, "main()", mod, ctx); if( r != asEXECUTION_FINISHED ) { if( r == asEXECUTION_EXCEPTION ) PrintException(ctx); TEST_FAILED; } ctx->Release(); engine->Release(); } // Success return fail; }
bool Test() { bool fail = false; int r; asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); RegisterScriptString_Generic(engine); engine->RegisterGlobalProperty("float[] @floatArray", &floatArray); engine->RegisterGlobalProperty("string[] @stringArray", &stringArray); COutStream out; asIScriptModule *mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script1, strlen(script1), 0); engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); r = mod->Build(); if( r < 0 ) fail = true; r = engine->ExecuteString(0, "Test()"); if( r != asEXECUTION_FINISHED ) fail = true; else { if( (floatArray->GetArrayTypeId() & asTYPEID_MASK_OBJECT) != asTYPEID_SCRIPTARRAY ) fail = true; if( floatArray->GetArrayTypeId() != engine->GetTypeIdByDecl("float[]") ) fail = true; if( floatArray->GetElementTypeId() != engine->GetTypeIdByDecl("float") ) fail = true; if( floatArray->GetElementCount() != 2 ) fail = true; if( *(float*)floatArray->GetElementPointer(0) != 1.1f ) fail = true; if( *(float*)floatArray->GetElementPointer(1) != 1.2f ) fail = true; if( stringArray->GetArrayTypeId() != engine->GetTypeIdByDecl("string[]") ) fail = true; if( stringArray->GetElementTypeId() != engine->GetTypeIdByDecl("string") ) fail = true; if( stringArray->GetElementCount() != 1 ) fail = true; if( ((CScriptString*)stringArray->GetElementPointer(0))->buffer != "test" ) fail = true; stringArray->Resize(2); } if( floatArray ) floatArray->Release(); if( stringArray ) stringArray->Release(); engine->Release(); // Success return fail; }
bool Test() { bool fail = Test2(); int r; COutStream out; CBufferedOutStream bout; // Test that removing a group doesn't remove other functions // http://www.gamedev.net/topic/657987-bug-new-functions-not-accessibly-by-getglobalfunctionbyindex-after-removing-different-configuration-group/ { asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); engine->SetMessageCallback(asMETHOD(COutStream, Callback), &out, asCALL_THISCALL); // register 3 script functions a(), b() and c() r = engine->RegisterGlobalFunction("void a()", asFUNCTION(0), asCALL_GENERIC); assert(r>=0); r = engine->RegisterGlobalFunction("void b()", asFUNCTION(0), asCALL_GENERIC); assert(r>=0); r = engine->RegisterGlobalFunction("void c()", asFUNCTION(0), asCALL_GENERIC); assert(r>=0); asIScriptFunction *func = engine->GetGlobalFunctionByIndex(0); if( func == 0 || string(func->GetName()) != "a" ) TEST_FAILED; func = engine->GetGlobalFunctionByIndex(1); if( func == 0 || string(func->GetName()) != "b" ) TEST_FAILED; func = engine->GetGlobalFunctionByIndex(2); if( func == 0 || string(func->GetName()) != "c" ) TEST_FAILED; // Add a dynamic group, then remove it r = engine->BeginConfigGroup("myconfig"); assert(r>=0); r = engine->RegisterGlobalFunction("void x()", asFUNCTION(0), asCALL_GENERIC); assert(r>=0); r = engine->RegisterGlobalFunction("void y()", asFUNCTION(0), asCALL_GENERIC); assert(r>=0); r = engine->EndConfigGroup(); assert(r>=0); r = engine->RemoveConfigGroup("myconfig"); assert(r>=0); // original functions should still be available func = engine->GetGlobalFunctionByIndex(0); if( func == 0 || string(func->GetName()) != "a" ) TEST_FAILED; func = engine->GetGlobalFunctionByIndex(1); if( func == 0 || string(func->GetName()) != "b" ) TEST_FAILED; func = engine->GetGlobalFunctionByIndex(2); if( func == 0 || string(func->GetName()) != "c" ) TEST_FAILED; // add some more functions in the default group r = engine->RegisterGlobalFunction("void d()", asFUNCTION(0), asCALL_GENERIC); assert(r>=0); r = engine->RegisterGlobalFunction("void e()", asFUNCTION(0), asCALL_GENERIC); assert(r>=0); r = engine->RegisterGlobalFunction("void f()", asFUNCTION(0), asCALL_GENERIC); assert(r>=0); // original functions should still be available func = engine->GetGlobalFunctionByIndex(0); if( func == 0 || string(func->GetName()) != "a" ) TEST_FAILED; func = engine->GetGlobalFunctionByIndex(1); if( func == 0 || string(func->GetName()) != "b" ) TEST_FAILED; func = engine->GetGlobalFunctionByIndex(2); if( func == 0 || string(func->GetName()) != "c" ) TEST_FAILED; // new functions must also be available func = engine->GetGlobalFunctionByIndex(3); if( func == 0 || string(func->GetName()) != "d" ) TEST_FAILED; func = engine->GetGlobalFunctionByIndex(4); if( func == 0 || string(func->GetName()) != "e" ) TEST_FAILED; func = engine->GetGlobalFunctionByIndex(5); if( func == 0 || string(func->GetName()) != "f" ) TEST_FAILED; engine->Release(); } // Test dynamic config groups with function definitions used for callbacks // http://www.gamedev.net/topic/618909-assertion-failure-in-as-configgroupcpp/ { asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); engine->SetMessageCallback(asMETHOD(CBufferedOutStream, Callback), &bout, asCALL_THISCALL); engine->BeginConfigGroup("gr"); engine->RegisterObjectType("type", 0, asOBJ_REF); #ifndef AS_MAX_PORTABILITY engine->RegisterObjectBehaviour("type", asBEHAVE_ADDREF, "void f()", asMETHOD(Type,AddRef), asCALL_THISCALL); engine->RegisterObjectBehaviour("type", asBEHAVE_RELEASE, "void f()", asMETHOD(Type,Release), asCALL_THISCALL); #else engine->RegisterObjectBehaviour("type", asBEHAVE_ADDREF, "void f()", WRAP_MFN(Type,AddRef), asCALL_GENERIC); engine->RegisterObjectBehaviour("type", asBEHAVE_RELEASE, "void f()", WRAP_MFN(Type,Release), asCALL_GENERIC); #endif engine->RegisterFuncdef("void fun(type @)"); engine->RegisterObjectProperty("type", "fun @callback", asOFFSET(Type,callback)); engine->EndConfigGroup(); asIScriptModule *mod = engine->GetModule("mod", asGM_ALWAYS_CREATE); mod->AddScriptSection("s", "void func(type @) {} \n" "void main(type @t) \n" "{ \n" " @t.callback = func; \n" "} \n"); r = mod->Build(); if( r < 0 ) TEST_FAILED; Type *t = new Type(); // Call the function that sets the callback on the object asIScriptFunction *m = mod->GetFunctionByName("main"); asIScriptContext *ctx = engine->CreateContext(); ctx->Prepare(m); ctx->SetArgObject(0, t); r = ctx->Execute(); if( r != asEXECUTION_FINISHED ) TEST_FAILED; ctx->Release(); // Release the engine, while the object holding the callback is still alive engine->Release(); t->Release(); // The engine will warn about the callback not being released before the engine if( bout.buffer != " (0, 0) : Warning : There is an external reference to an object in module 'mod', preventing it from being deleted\n" " (0, 0) : Info : The function in previous message is named 'func'. The func type is 1\n" ) { PRINTF("%s", bout.buffer.c_str()); TEST_FAILED; } } //------------ // Test global function asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); r = engine->BeginConfigGroup("group1"); assert( r >= 0 ); r = engine->RegisterGlobalFunction("void MyFunc()", asFUNCTION(MyFunc), asCALL_GENERIC); assert( r >= 0 ); r = engine->EndConfigGroup(); assert( r >= 0 ); engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); asIScriptModule *mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script1, strlen(script1), 0); r = mod->Build(); if( r < 0 ) { TEST_FAILED; } r = engine->RemoveConfigGroup("group1"); assert( r == asCONFIG_GROUP_IS_IN_USE ); engine->DiscardModule(0); engine->GarbageCollect(); r = engine->RemoveConfigGroup("group1"); assert( r >= 0 ); bout.buffer = ""; engine->SetMessageCallback(asMETHOD(CBufferedOutStream,Callback), &bout, asCALL_THISCALL); mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script1, strlen(script1), 0); r = mod->Build(); if( r >= 0 || bout.buffer != "TestDynamicConfig (1, 1) : Info : Compiling void Test()\n" "TestDynamicConfig (3, 3) : Error : No matching symbol 'MyFunc'\n" ) { PRINTF("%s", bout.buffer.c_str()); TEST_FAILED; } engine->Release(); //---------------- // Test global property engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); r = engine->BeginConfigGroup("group1"); assert( r >= 0 ); r = engine->RegisterGlobalProperty("int global", (void*)1); assert( r >= 0 ); r = engine->EndConfigGroup(); assert( r >= 0 ); mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script2, strlen(script2), 0); engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); r = mod->Build(); if( r < 0 ) { TEST_FAILED; } r = engine->RemoveConfigGroup("group1"); assert( r == asCONFIG_GROUP_IS_IN_USE ); engine->DiscardModule(0); engine->GarbageCollect(); r = engine->RemoveConfigGroup("group1"); assert( r >= 0 ); bout.buffer = ""; mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script2, strlen(script2), 0); engine->SetMessageCallback(asMETHOD(CBufferedOutStream,Callback), &bout, asCALL_THISCALL); r = mod->Build(); if( r >= 0 || bout.buffer != "TestDynamicConfig (1, 1) : Info : Compiling void Test()\n" "TestDynamicConfig (3, 3) : Error : No matching symbol 'global'\n" ) { PRINTF("%s", bout.buffer.c_str()); TEST_FAILED; } // Try registering the property again r = engine->BeginConfigGroup("group1"); assert( r >= 0 ); r = engine->RegisterGlobalProperty("int global", (void*)1); assert( r >= 0 ); r = engine->EndConfigGroup(); assert( r >= 0 ); engine->Release(); //------------- // Test object types engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); r = engine->BeginConfigGroup("group1"); assert( r >= 0 ); r = engine->RegisterObjectType("mytype", sizeof(int), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_PRIMITIVE); r = engine->EndConfigGroup(); assert( r >= 0 ); mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script3, strlen(script3), 0); engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); r = mod->Build(); if( r < 0 ) { TEST_FAILED; } r = engine->RemoveConfigGroup("group1"); assert( r == asCONFIG_GROUP_IS_IN_USE ); engine->DiscardModule(0); engine->GarbageCollect(); r = engine->RemoveConfigGroup("group1"); assert( r >= 0 ); bout.buffer = ""; mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script3, strlen(script3), 0); engine->SetMessageCallback(asMETHOD(CBufferedOutStream,Callback), &bout, asCALL_THISCALL); r = mod->Build(); if( r >= 0 || bout.buffer != "TestDynamicConfig (1, 1) : Info : Compiling void Test()\n" "TestDynamicConfig (3, 3) : Error : Identifier 'mytype' is not a data type\n" ) { PRINTF("%s", bout.buffer.c_str()); TEST_FAILED; } engine->Release(); //------------------ // Test global behaviours engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); RegisterScriptString_Generic(engine); r = engine->BeginConfigGroup("group1"); assert( r >= 0 ); r = engine->RegisterObjectType("mytype", sizeof(int), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_PRIMITIVE); r = engine->RegisterObjectMethod("mytype", "string@ opAdd_r(const string &in)", asFUNCTION(MyFunc), asCALL_GENERIC); assert( r >= 0 ); r = engine->EndConfigGroup(); assert( r >= 0 ); mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script4, strlen(script4), 0); engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); r = mod->Build(); if( r < 0 ) { TEST_FAILED; } r = engine->RemoveConfigGroup("group1"); assert( r == asCONFIG_GROUP_IS_IN_USE ); engine->DiscardModule(0); engine->GarbageCollect(); r = engine->RemoveConfigGroup("group1"); assert( r >= 0 ); // Register the type again, but without the operator overload r = engine->BeginConfigGroup("group1"); assert( r >= 0 ); r = engine->RegisterObjectType("mytype", sizeof(int), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_PRIMITIVE); r = engine->EndConfigGroup(); assert( r >= 0 ); bout.buffer = ""; mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script4, strlen(script4), 0); engine->SetMessageCallback(asMETHOD(CBufferedOutStream,Callback), &bout, asCALL_THISCALL); r = mod->Build(); if( r >= 0 || bout.buffer != "TestDynamicConfig (1, 1) : Info : Compiling void Test()\n" "TestDynamicConfig (5, 9) : Error : No matching operator that takes the types 'string&' and 'mytype' found\n" ) { PRINTF("%s", bout.buffer.c_str()); TEST_FAILED; } engine->Release(); //------------------ // Test object types held by external variable, i.e. any CScriptAny *any = 0; engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); RegisterScriptAny(engine); engine->BeginConfigGroup("group1"); r = engine->RegisterObjectType("mytype", sizeof(int), asOBJ_REF); r = engine->RegisterObjectBehaviour("mytype", asBEHAVE_FACTORY, "mytype @f()", asFUNCTION(Factory), asCALL_GENERIC); r = engine->RegisterObjectBehaviour("mytype", asBEHAVE_ADDREF, "void f()", asFUNCTION(AddRef), asCALL_GENERIC); r = engine->RegisterObjectBehaviour("mytype", asBEHAVE_RELEASE, "void f()", asFUNCTION(Release), asCALL_GENERIC); any = (CScriptAny*)engine->CreateScriptObject(engine->GetTypeInfoByName("any")); r = engine->RegisterGlobalProperty("any g_any", any); engine->EndConfigGroup(); mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(0, script5); engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); r = mod->Build(); if( r < 0 ) TEST_FAILED; r = ExecuteString(engine, "Test()", mod); if( r != asEXECUTION_FINISHED ) { TEST_FAILED; } engine->DiscardModule(0); engine->GarbageCollect(); int *o = 0; any->Retrieve(&o, engine->GetTypeIdByDecl("mytype@")); if( o == 0 ) TEST_FAILED; if( --(*o) != 1 ) TEST_FAILED; // The mytype variable is still stored in the any variable so we shouldn't be allowed to remove it's configuration group r = engine->RemoveConfigGroup("group1"); assert( r < 0 ); any->Release(); engine->GarbageCollect(); // Now it should be possible to remove the group r = engine->RemoveConfigGroup("group1"); assert( r >= 0 ); engine->Release(); //------------- // Test array types engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); RegisterScriptArray(engine, true); r = engine->BeginConfigGroup("group1"); assert( r >= 0 ); r = engine->RegisterObjectType("int[]", sizeof(int), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_PRIMITIVE); r = engine->EndConfigGroup(); assert( r >= 0 ); asITypeInfo *ot = engine->GetTypeInfoByDecl("int[]"); if( ot->GetSubTypeId() != asTYPEID_INT32 ) TEST_FAILED; mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script6, strlen(script6), 0); engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); r = mod->Build(); if( r < 0 ) { TEST_FAILED; } r = engine->RemoveConfigGroup("group1"); assert( r == asCONFIG_GROUP_IS_IN_USE ); engine->DiscardModule(0); engine->GarbageCollect(); r = engine->RemoveConfigGroup("group1"); assert( r >= 0 ); engine->Release(); //------------- // Test object types in struct members engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); r = engine->BeginConfigGroup("group1"); assert( r >= 0 ); r = engine->RegisterObjectType("mytype", sizeof(int), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_PRIMITIVE); r = engine->EndConfigGroup(); assert( r >= 0 ); mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script7, strlen(script7), 0); engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); r = mod->Build(); if( r < 0 ) { TEST_FAILED; } r = engine->RemoveConfigGroup("group1"); assert( r == asCONFIG_GROUP_IS_IN_USE ); engine->DiscardModule(0); engine->GarbageCollect(); r = engine->RemoveConfigGroup("group1"); assert( r >= 0 ); bout.buffer = ""; mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script7, strlen(script7), 0); engine->SetMessageCallback(asMETHOD(CBufferedOutStream,Callback), &bout, asCALL_THISCALL); r = mod->Build(); if( r >= 0 || bout.buffer != "TestDynamicConfig (3, 3) : Error : Identifier 'mytype' is not a data type in global namespace\n" ) { PRINTF("%s", bout.buffer.c_str()); TEST_FAILED; } engine->Release(); //------------- // Test object types in function declarations engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); r = engine->BeginConfigGroup("group1"); assert( r >= 0 ); r = engine->RegisterObjectType("mytype", sizeof(int), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_PRIMITIVE); r = engine->EndConfigGroup(); assert( r >= 0 ); mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script8, strlen(script8), 0); engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); r = mod->Build(); if( r < 0 ) { TEST_FAILED; } r = engine->RemoveConfigGroup("group1"); assert( r == asCONFIG_GROUP_IS_IN_USE ); engine->DiscardModule(0); engine->GarbageCollect(); r = engine->RemoveConfigGroup("group1"); assert( r >= 0 ); bout.buffer = ""; mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script8, strlen(script8), 0); engine->SetMessageCallback(asMETHOD(CBufferedOutStream,Callback), &bout, asCALL_THISCALL); r = mod->Build(); if( r >= 0 || bout.buffer != "TestDynamicConfig (1, 11) : Error : Identifier 'mytype' is not a data type in global namespace\n" ) { PRINTF("%s", bout.buffer.c_str()); TEST_FAILED; } engine->Release(); //------------- // Test object types in script arrays engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); RegisterScriptArray(engine, true); r = engine->BeginConfigGroup("group1"); assert( r >= 0 ); r = engine->RegisterObjectType("mytype", sizeof(int), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_PRIMITIVE); r = engine->EndConfigGroup(); assert( r >= 0 ); mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script9, strlen(script9), 0); engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); r = mod->Build(); if( r < 0 ) { TEST_FAILED; } r = engine->RemoveConfigGroup("group1"); assert( r == asCONFIG_GROUP_IS_IN_USE ); engine->DiscardModule(0); engine->GarbageCollect(); r = engine->RemoveConfigGroup("group1"); assert( r >= 0 ); bout.buffer = ""; mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script9, strlen(script9), 0); engine->SetMessageCallback(asMETHOD(CBufferedOutStream,Callback), &bout, asCALL_THISCALL); r = mod->Build(); if( r >= 0 || bout.buffer != "TestDynamicConfig (1, 1) : Info : Compiling void Test()\n" "TestDynamicConfig (3, 4) : Error : Identifier 'mytype' is not a data type\n" ) { PRINTF("%s", bout.buffer.c_str()); TEST_FAILED; } engine->Release(); //------------------ // Test object types held by external variable, i.e. any engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); RegisterScriptArray(engine, true); RegisterScriptAny(engine); engine->BeginConfigGroup("group1"); r = engine->RegisterObjectType("mytype", sizeof(int), asOBJ_VALUE | asOBJ_POD); any = (CScriptAny*)engine->CreateScriptObject(engine->GetTypeInfoByName("any")); r = engine->RegisterGlobalProperty("any g_any", any); engine->EndConfigGroup(); mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script10); engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); r = mod->Build(); if( r < 0 ) TEST_FAILED; r = ExecuteString(engine, "Test()", mod); if( r != asEXECUTION_FINISHED ) { TEST_FAILED; } engine->DiscardModule(0); engine->GarbageCollect(); CScriptArray *array = 0; any->Retrieve(&array, engine->GetTypeIdByDecl("mytype[]@")); if( array == 0 ) { TEST_FAILED; } else array->Release(); engine->GarbageCollect(); // The mytype variable is still stored in the any variable so we shouldn't be allowed to remove it's configuration group r = engine->RemoveConfigGroup("group1"); assert( r < 0 ); any->Release(); engine->GarbageCollect(); // Now it should be possible to remove the group r = engine->RemoveConfigGroup("group1"); assert( r >= 0 ); engine->Release(); //------------------- // Test references between config groups engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); engine->BeginConfigGroup("group1"); r = engine->RegisterObjectType("mytype", sizeof(int), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_PRIMITIVE); assert( r >= 0 ); engine->EndConfigGroup(); engine->BeginConfigGroup("group2"); r = engine->RegisterGlobalFunction("void func(mytype)", asFUNCTION(0), asCALL_GENERIC); assert( r >= 0 ); engine->EndConfigGroup(); r = engine->RemoveConfigGroup("group1"); assert( r == asCONFIG_GROUP_IS_IN_USE ); r = engine->RemoveConfigGroup("group2"); assert( r <= 0 ); r = engine->RemoveConfigGroup("group1"); assert( r <= 0 ); engine->Release(); //-------------------- // Test situation where the default group references a dynamic group. It will then be impossible // to remove the dynamic group, but the application must still be able to release the engine. engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); engine->BeginConfigGroup("group1"); r = engine->RegisterObjectType("mytype", sizeof(int), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_PRIMITIVE); assert( r >= 0 ); engine->EndConfigGroup(); r = engine->RegisterGlobalFunction("void func(mytype)", asFUNCTION(0), asCALL_GENERIC); assert( r >= 0 ); r = engine->RemoveConfigGroup("group1"); assert( r == asCONFIG_GROUP_IS_IN_USE ); engine->Release(); //---------------------- // Test that it is possible to repeat the registration of the config group engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); r = engine->BeginConfigGroup("g1"); assert( r >= 0 ); RegisterScriptString_Generic(engine); r = engine->EndConfigGroup(); assert( r >= 0 ); r = ExecuteString(engine, "string a = \"test\""); assert( r == asEXECUTION_FINISHED ); r = engine->GarbageCollect(); assert( r >= 0 ); r = engine->RemoveConfigGroup("g1"); assert( r >= 0 ); // again.. r = engine->BeginConfigGroup("g1"); assert( r >= 0 ); RegisterScriptString_Generic(engine); r = engine->EndConfigGroup(); assert( r >= 0 ); r = ExecuteString(engine, "string a = \"test\""); assert( r == asEXECUTION_FINISHED ); r = engine->GarbageCollect(); assert( r >= 0 ); r = engine->RemoveConfigGroup("g1"); assert( r >= 0 ); engine->Release(); //----------------------------- // Test that it isn't possible to register the same property in two different groups engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); engine->BeginConfigGroup("a"); r = engine->RegisterGlobalProperty("int a", (void*)1); assert( r >= 0 ); engine->EndConfigGroup(); r = engine->RegisterGlobalProperty("int a", (void*)1); assert( r < 0 ); engine->Release(); //------------------------------ // Test that ExecuteString doesn't lock dynamic config groups engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); r = engine->BeginConfigGroup("g1"); assert( r >= 0 ); RegisterScriptString_Generic(engine); r = engine->EndConfigGroup(); assert( r >= 0 ); r = ExecuteString(engine, "string a = \"test\""); assert( r == asEXECUTION_FINISHED ); // Garbage collect and remove config group before discarding module r = engine->GarbageCollect(); assert( r >= 0 ); r = engine->RemoveConfigGroup("g1"); assert( r >= 0 ); engine->Release(); //----------------------- // Make sure the clean-up works when there a groups using types in the default group engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); RegisterStdString(engine); engine->BeginConfigGroup("g"); r = engine->RegisterGlobalFunction("void SaveLesson(const string &in)", asFUNCTION(0), asCALL_GENERIC); assert( r >= 0 ); engine->EndConfigGroup(); engine->Release(); //------------------------- // Test registering object members in a group // http://www.gamedev.net/topic/636396-config-groups-and-object-property-accessors/ engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); engine->RegisterObjectType("type", 0, asOBJ_REF | asOBJ_NOCOUNT); // TODO: It should be possible to register methods and properties in different groups from where the type itself was registered engine->BeginConfigGroup("g"); engine->RegisterObjectMethod("type", "void func()", asFUNCTION(0), asCALL_GENERIC); engine->EndConfigGroup(); asITypeInfo *type = engine->GetTypeInfoByName("type"); if( type->GetMethodCount() != 1 ) TEST_FAILED; r = engine->RemoveConfigGroup("g"); if( r < 0 ) TEST_FAILED; // TODO: Currently the method is not removed as the method will be placed in the same group as the type. When this changes, the method should be removed if( type->GetMethodCount() != 1 ) TEST_FAILED; engine->Release(); // Success return fail; }
bool Test() { bool fail = Test2(); int r; COutStream out; asIScriptContext *ctx; // Test to make sure opIndex properly catches null pointer access // http://www.gamedev.net/topic/676729-crash-instead-of-null-pointer-exception-on-opindex/ { asIScriptEngine *engine = asCreateScriptEngine(); RegisterScriptArray(engine, true); engine->SetMessageCallback(asMETHOD(COutStream, Callback), &out, asCALL_THISCALL); ctx = engine->CreateContext(); r = ExecuteString(engine, "array<array<int>@> a = {null}; a[0][0] = 1;", 0, ctx); if (r != asEXECUTION_EXCEPTION) TEST_FAILED; else if( GetExceptionInfo(ctx) != "func: void ExecuteString()\n" "modl: \n" "sect: ExecuteString\n" "line: 1\n" "desc: Null pointer access\n" ) { PRINTF("%s", GetExceptionInfo(ctx).c_str()); TEST_FAILED; } ctx->Release(); engine->ShutDownAndRelease(); } // Test GetTypeDeclaration with arrays // http://www.gamedev.net/topic/663428-simplest-way-to-get-variable-type/ { asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); RegisterScriptArray(engine, true); int typeId = engine->GetTypeIdByDecl("array<array<int>@>"); if( typeId < 0 ) TEST_FAILED; std::string typeDecl = engine->GetTypeDeclaration(typeId, true); if( typeDecl != "int[]@[]" ) { PRINTF("%s\n", typeDecl.c_str()); TEST_FAILED; } engine->SetDefaultNamespace("foo"); engine->RegisterEnum("MyEnum"); engine->SetDefaultNamespace(""); typeId = engine->GetTypeIdByDecl("array<foo::MyEnum>"); if( typeId < 0 ) TEST_FAILED; typeDecl = engine->GetTypeDeclaration(typeId, true); if( typeDecl != "foo::MyEnum[]" ) { PRINTF("%s\n", typeDecl.c_str()); TEST_FAILED; } engine->ShutDownAndRelease(); } asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); RegisterScriptArray(engine, true); RegisterScriptString_Generic(engine); engine->RegisterGlobalFunction("void Assert(bool)", asFUNCTION(Assert), asCALL_GENERIC); asIScriptModule *mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script1, strlen(script1), 0); r = mod->Build(); if( r < 0 ) { TEST_FAILED; PRINTF("%s: Failed to compile the script\n", TESTNAME); } ctx = engine->CreateContext(); r = ExecuteString(engine, "TestArray()", mod, ctx); if( r != asEXECUTION_FINISHED ) { if( r == asEXECUTION_EXCEPTION ) PRINTF("%s", GetExceptionInfo(ctx).c_str()); PRINTF("%s: Failed to execute script\n", TESTNAME); TEST_FAILED; } if( ctx ) ctx->Release(); mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script2, strlen(script2), 0); r = mod->Build(); if( r < 0 ) { TEST_FAILED; PRINTF("%s: Failed to compile the script\n", TESTNAME); } r = ExecuteString(engine, "TestArrayException()", mod); if( r != asEXECUTION_EXCEPTION ) { PRINTF("%s: No exception\n", TESTNAME); TEST_FAILED; } mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script3, strlen(script3), 0); r = mod->Build(); if( r < 0 ) { TEST_FAILED; PRINTF("%s: Failed to compile the script\n", TESTNAME); } ctx = engine->CreateContext(); r = ExecuteString(engine, "TestArrayMulti()", mod, ctx); if( r != asEXECUTION_FINISHED ) { PRINTF("%s: Failure\n", TESTNAME); TEST_FAILED; } if( r == asEXECUTION_EXCEPTION ) { PRINTF("%s", GetExceptionInfo(ctx).c_str()); } if( ctx ) ctx->Release(); ctx = 0; mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script4, strlen(script4), 0); r = mod->Build(); if( r < 0 ) { TEST_FAILED; PRINTF("%s: Failed to compile the script\n", TESTNAME); } ctx = engine->CreateContext(); r = ExecuteString(engine, "TestArrayChar()", mod, ctx); if( r != asEXECUTION_FINISHED ) { PRINTF("%s: Failure\n", TESTNAME); TEST_FAILED; } if( r == asEXECUTION_EXCEPTION ) { PRINTF("%s", GetExceptionInfo(ctx).c_str()); } if( ctx ) ctx->Release(); mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script5, strlen(script5), 0); r = mod->Build(); if( r < 0 ) TEST_FAILED; ctx = engine->CreateContext(); r = ExecuteString(engine, "TestArrayInitList()", mod, ctx); if( r != asEXECUTION_FINISHED ) TEST_FAILED; if( r == asEXECUTION_EXCEPTION ) PRINTF("%s", GetExceptionInfo(ctx).c_str()); if( ctx ) ctx->Release(); CBufferedOutStream bout; engine->SetMessageCallback(asMETHOD(CBufferedOutStream,Callback), &bout, asCALL_THISCALL); mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script6, strlen(script6), 0); r = mod->Build(); if( r >= 0 ) TEST_FAILED; if( bout.buffer != "TestArray (1, 1) : Info : Compiling void Test()\n" "TestArray (4, 16) : Error : Initialization lists cannot be used with 'int'\n" ) { PRINTF("%s", bout.buffer.c_str()); TEST_FAILED; } // Array object must call default constructor of the script classes engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script7, strlen(script7), 0); r = mod->Build(); if( r < 0 ) TEST_FAILED; r = ExecuteString(engine, "Test()", mod); if( r != asEXECUTION_FINISHED ) TEST_FAILED; // Test bool[] on Mac OS X with PPC CPU // Submitted by Edward Rudd const char *script8 = "bool[] f(10); \n" "for (int i=0; i<10; i++) { \n" " f[i] = false; \n" "} \n" "Assert(f[0] == false); \n" "Assert(f[1] == false); \n" "f[0] = true; \n" "Assert(f[0] == true); \n" "Assert(f[1] == false); \n"; r = ExecuteString(engine, script8); if( r != asEXECUTION_FINISHED ) TEST_FAILED; // Make sure it is possible to do multiple assignments with the array type r = ExecuteString(engine, "int[] a, b, c; a = b = c;"); if( r < 0 ) TEST_FAILED; engine->Release(); // Test circular reference between types { // Create the script engine asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); RegisterScriptArray(engine, true); // Compile asIScriptModule *mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection("script", "class Hoge" "{" " Hoge(){}" " Hoge(HogeManager&){}" "};" "class HogeManager" "{" " Hoge[] hoges;" "};" , 0); mod->Build(); // Release engine engine->Release(); } // Test multidimensional array initialization { // Create the script engine asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); engine->RegisterGlobalFunction("void assert(bool)", asFUNCTION(Assert), asCALL_GENERIC); RegisterScriptArray(engine, true); r = ExecuteString(engine, "int[][] a(2, int[](2)); assert(a[1].length() == 2);\n"); if( r != asEXECUTION_FINISHED ) TEST_FAILED; // Release engine engine->Release(); } // Test array of void { asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); CBufferedOutStream bout; engine->SetMessageCallback(asMETHOD(CBufferedOutStream,Callback), &bout, asCALL_THISCALL); RegisterScriptArray(engine, false); r = ExecuteString(engine, "array<void> a;"); if( r != -1 ) TEST_FAILED; if( bout.buffer != "ExecuteString (1, 7) : Error : Attempting to instantiate invalid template type 'array<void>'\n" ) { PRINTF("%s", bout.buffer.c_str()); TEST_FAILED; } engine->Release(); } // Success return fail; }
bool Test() { bool fail = false; int r; asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); RegisterScriptString_Generic(engine); RegisterScriptAny(engine); engine->RegisterGlobalFunction("void Assert(bool)", asFUNCTION(Assert), asCALL_GENERIC); engine->RegisterGlobalFunction("void print(const string &in)", asFUNCTION(print), asCALL_GENERIC); engine->RegisterGlobalFunction("void Analyze(any &inout)", asFUNCTION(Analyze), asCALL_GENERIC); COutStream out; CBufferedOutStream bout; engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); asIScriptModule *mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script1, strlen(script1), 0); r = mod->Build(); if( r < 0 ) TEST_FAILED; asIScriptContext *ctx = engine->CreateContext(); r = ExecuteString(engine, "Test()", mod, ctx); if( r != asEXECUTION_FINISHED ) { if( r == asEXECUTION_EXCEPTION ) PrintException(ctx); TEST_FAILED; } if( ctx ) ctx->Release(); // Make sure that the error message for wrong constructor name works bout.buffer = ""; engine->SetMessageCallback(asMETHOD(CBufferedOutStream,Callback), &bout, asCALL_THISCALL); mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, "class t{ s() {} };", 18, 0); r = mod->Build(); if( r >= 0 ) TEST_FAILED; if( bout.buffer != "TestScriptClassMethod (1, 10) : Error : The name of constructors and destructors must be the same as the class\n" ) { printf("%s", bout.buffer.c_str()); TEST_FAILED; } // Make sure the default constructor can be overloaded engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); mod = engine->GetModule("test", asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script2, strlen(script2), 0); r = mod->Build(); if( r < 0 ) TEST_FAILED; r = ExecuteString(engine, "Test()", mod); if( r != asEXECUTION_FINISHED ) { TEST_FAILED; } asIObjectType *type = engine->GetModule("test")->GetObjectTypeByName("myclass"); asIScriptObject *s = (asIScriptObject*)engine->CreateScriptObject(type); if( s == 0 ) TEST_FAILED; else { // Validate the property int *v = 0; int n = s->GetPropertyCount(); for( int c = 0; c < n; c++ ) { std::string str = "value"; if( str == s->GetPropertyName(c) ) { v = (int*)s->GetAddressOfProperty(c); if( *v != 1 ) TEST_FAILED; } } // Call the script class method if( type->GetMethodCount() != 2 ) TEST_FAILED; asIScriptFunction *method = type->GetMethodByDecl("void method2()"); if( method == 0 ) TEST_FAILED; else { asIScriptContext *ctx = engine->CreateContext(); ctx->Prepare(method); ctx->SetObject(s); int r = ctx->Execute(); if( r != asEXECUTION_FINISHED ) TEST_FAILED; if( (!v) || (*v != 3) ) TEST_FAILED; ctx->Release(); } s->Release(); } engine->Release(); //---------------------------------- engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); RegisterScriptAny(engine); engine->RegisterGlobalFunction("void Assert(bool)", asFUNCTION(Assert), asCALL_GENERIC); engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection("test3", script3, strlen(script3), 0); r = mod->Build(); if( r < 0 ) TEST_FAILED; int typeId = engine->GetModule(0)->GetTypeIdByDecl("myclass"); type = engine->GetObjectTypeById(typeId); asIScriptFunction *mtd = type->GetMethodByDecl("void func()"); asIScriptObject *obj = (asIScriptObject *)engine->GetModule(0)->GetAddressOfGlobalVar(engine->GetModule(0)->GetGlobalVarIndexByName("c")); if( mtd == 0 || obj == 0 ) TEST_FAILED; else { asIScriptContext *ctx = engine->CreateContext(); ctx->Prepare(mtd); ctx->SetObject(obj); r = ctx->Execute(); if( r != asEXECUTION_FINISHED ) TEST_FAILED; ctx->Release(); } type = engine->GetObjectTypeById(typeId); mtd = type->GetMethodByDecl("void func(int, int)"); if( mtd == 0 || obj == 0 ) TEST_FAILED; else { asIScriptContext *ctx = engine->CreateContext(); ctx->Prepare(mtd); ctx->SetObject(obj); ctx->SetArgDWord(0, 1); ctx->SetArgDWord(1, 1); r = ctx->Execute(); if( r != asEXECUTION_FINISHED ) TEST_FAILED; ctx->Release(); } engine->Release(); //---------------------------- // Verify that global functions and class methods with the same name doesn't conflict engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); RegisterScriptAny(engine); engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection("test4", script4, strlen(script4), 0); r = mod->Build(); if( r < 0 ) TEST_FAILED; asIScriptFunction *func = mod->GetFunctionByDecl("void func()"); if( func == 0 ) TEST_FAILED; engine->Release(); //---------------------------- // Accessing member variables without this engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); RegisterScriptAny(engine); engine->SetMessageCallback(asMETHOD(COutStream, Callback), &out, asCALL_THISCALL); engine->RegisterGlobalFunction("void Assert(bool)", asFUNCTION(Assert), asCALL_GENERIC); mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection("test5", script5, strlen(script5), 0); r = mod->Build(); if( r < 0 ) TEST_FAILED; r = ExecuteString(engine, "test()", mod); if( r != asEXECUTION_FINISHED ) { TEST_FAILED; } engine->Release(); //----------------------------- // Name conflict with class method and object type engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); engine->SetMessageCallback(asMETHOD(COutStream, Callback), &out, asCALL_THISCALL); RegisterScriptString(engine); engine->RegisterGlobalFunction("void print(const string &in)", asFUNCTION(print), asCALL_GENERIC); mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection("test6", script6, strlen(script6), 0); r = mod->Build(); if( r < 0 ) TEST_FAILED; outbuffer = ""; r = ExecuteString(engine, "Test t; t.Set(1); t.Test2();", mod); if( r != asEXECUTION_FINISHED ) { TEST_FAILED; } if( outbuffer != "Test::Set\nTest::Set\nSet::Set\n" ) { printf("%s", outbuffer.c_str()); TEST_FAILED; } engine->Release(); //------------------------------ // The scope operator should permit calling global functions if the class has a method of the same name engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); engine->SetMessageCallback(asMETHOD(COutStream, Callback), &out, asCALL_THISCALL); engine->RegisterGlobalFunction("void assert(bool)", asFUNCTION(Assert), asCALL_GENERIC); mod = engine->GetModule(0, asGM_ALWAYS_CREATE); const char *script = "class A { \n" " void func() { \n" " g = 0; \n" " testScope(); \n" " assert(g == 3); \n" " ::testScope(); \n" " assert(g == 2); \n" " } \n" " void testScope() { g = 3; } \n" "} \n" "void testScope() { g = 2; } \n" "int g; \n"; mod->AddScriptSection("script", script); r = mod->Build(); if( r < 0 ) { TEST_FAILED; } r = ExecuteString(engine, "A a; a.func(); assert( g == 2 );", mod); if( r != asEXECUTION_FINISHED ) { TEST_FAILED; } engine->Release(); //--------------------------- // It should not be possible to declare a method with the same name as the class { engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); engine->SetMessageCallback(asMETHOD(CBufferedOutStream, Callback), &bout, asCALL_THISCALL); mod = engine->GetModule(0, asGM_ALWAYS_CREATE); const char *script = "class A { \n" " void A() {} \n" "} \n"; mod->AddScriptSection("script", script); bout.buffer = ""; r = mod->Build(); if( r >= 0 ) TEST_FAILED; if( bout.buffer != "script (2, 3) : Error : The method cannot be named with the class name\n" ) { printf("%s", bout.buffer.c_str()); TEST_FAILED; } engine->Release(); } // Success return fail; }
bool Test() { bool fail = false; int r; COutStream out; asIScriptContext *ctx; asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); r = engine->SetCommonObjectMemoryFunctions(ScriptAlloc, ScriptFree); engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); RegisterScriptString_Generic(engine); engine->RegisterGlobalFunction("void Assert(bool)", asFUNCTION(Assert), asCALL_GENERIC); engine->AddScriptSection(0, TESTNAME, script1, strlen(script1), 0, false); r = engine->Build(0); if( r < 0 ) { fail = true; printf("%s: Failed to compile the script\n", TESTNAME); } r = engine->ExecuteString(0, "TestArray()", &ctx); if( r != asEXECUTION_FINISHED ) { if( r == asEXECUTION_EXCEPTION ) PrintException(ctx); printf("%s: Failed to execute script\n", TESTNAME); fail = true; } if( ctx ) ctx->Release(); engine->AddScriptSection(0, TESTNAME, script2, strlen(script2), 0, false); r = engine->Build(0); if( r < 0 ) { fail = true; printf("%s: Failed to compile the script\n", TESTNAME); } r = engine->ExecuteString(0, "TestArrayException()"); if( r != asEXECUTION_EXCEPTION ) { printf("%s: No exception\n", TESTNAME); fail = true; } engine->AddScriptSection(0, TESTNAME, script3, strlen(script3), 0, false); r = engine->Build(0); if( r < 0 ) { fail = true; printf("%s: Failed to compile the script\n", TESTNAME); } r = engine->ExecuteString(0, "TestArrayMulti()", &ctx); if( r != asEXECUTION_FINISHED ) { printf("%s: Failure\n", TESTNAME); fail = true; } if( r == asEXECUTION_EXCEPTION ) { PrintException(ctx); } if( ctx ) ctx->Release(); ctx = 0; engine->AddScriptSection(0, TESTNAME, script4, strlen(script4), 0, false); r = engine->Build(0); if( r < 0 ) { fail = true; printf("%s: Failed to compile the script\n", TESTNAME); } r = engine->ExecuteString(0, "TestArrayChar()", &ctx); if( r != asEXECUTION_FINISHED ) { printf("%s: Failure\n", TESTNAME); fail = true; } if( r == asEXECUTION_EXCEPTION ) { PrintException(ctx); } if( ctx ) ctx->Release(); engine->AddScriptSection(0, TESTNAME, script5, strlen(script5), 0, false); r = engine->Build(0); if( r < 0 ) fail = true; r = engine->ExecuteString(0, "TestArrayInitList()", &ctx); if( r != asEXECUTION_FINISHED ) fail = true; if( r == asEXECUTION_EXCEPTION ) PrintException(ctx); if( ctx ) ctx->Release(); CBufferedOutStream bout; engine->SetMessageCallback(asMETHOD(CBufferedOutStream,Callback), &bout, asCALL_THISCALL); engine->AddScriptSection(0, TESTNAME, script6, strlen(script6), 0, false); r = engine->Build(0); if( r >= 0 ) fail = true; if( bout.buffer != "TestArray (1, 1) : Info : Compiling void Test()\n" "TestArray (3, 15) : Error : Initialization lists cannot be used with 'int[]@'\n" "TestArray (4, 16) : Error : Initialization lists cannot be used with 'int'\n" ) fail = true; engine->Release(); // Success return fail; }
bool Test() { bool fail = Test2(); int r; //------------ // Test global function asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); r = engine->BeginConfigGroup("group1"); assert( r >= 0 ); r = engine->RegisterGlobalFunction("void MyFunc()", asFUNCTION(MyFunc), asCALL_GENERIC); assert( r >= 0 ); r = engine->EndConfigGroup(); assert( r >= 0 ); COutStream out; engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); asIScriptModule *mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script1, strlen(script1), 0); r = mod->Build(); if( r < 0 ) { fail = true; } r = engine->RemoveConfigGroup("group1"); assert( r == asCONFIG_GROUP_IS_IN_USE ); engine->DiscardModule(0); r = engine->RemoveConfigGroup("group1"); assert( r >= 0 ); CBufferedOutStream bout; engine->SetMessageCallback(asMETHOD(CBufferedOutStream,Callback), &bout, asCALL_THISCALL); mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script1, strlen(script1), 0); r = mod->Build(); if( r >= 0 || bout.buffer != "TestDynamicConfig (1, 1) : Info : Compiling void Test()\n" "TestDynamicConfig (3, 3) : Error : No matching signatures to 'MyFunc()'\n" ) { fail = true; } engine->Release(); //---------------- // Test global property engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); r = engine->BeginConfigGroup("group1"); assert( r >= 0 ); r = engine->RegisterGlobalProperty("int global", 0); assert( r >= 0 ); r = engine->EndConfigGroup(); assert( r >= 0 ); mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script2, strlen(script2), 0); engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); r = mod->Build(); if( r < 0 ) { fail = true; } r = engine->RemoveConfigGroup("group1"); assert( r == asCONFIG_GROUP_IS_IN_USE ); engine->DiscardModule(0); r = engine->RemoveConfigGroup("group1"); assert( r >= 0 ); bout.buffer = ""; mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script2, strlen(script2), 0); engine->SetMessageCallback(asMETHOD(CBufferedOutStream,Callback), &bout, asCALL_THISCALL); r = mod->Build(); if( r >= 0 || bout.buffer != "TestDynamicConfig (1, 1) : Info : Compiling void Test()\n" "TestDynamicConfig (3, 3) : Error : 'global' is not declared\n" ) { fail = true; } // Try registering the property again r = engine->BeginConfigGroup("group1"); assert( r >= 0 ); r = engine->RegisterGlobalProperty("int global", 0); assert( r >= 0 ); r = engine->EndConfigGroup(); assert( r >= 0 ); engine->Release(); //------------- // Test object types engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); r = engine->BeginConfigGroup("group1"); assert( r >= 0 ); r = engine->RegisterObjectType("mytype", sizeof(int), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_PRIMITIVE); r = engine->EndConfigGroup(); assert( r >= 0 ); mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script3, strlen(script3), 0); engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); r = mod->Build(); if( r < 0 ) { fail = true; } r = engine->RemoveConfigGroup("group1"); assert( r == asCONFIG_GROUP_IS_IN_USE ); engine->DiscardModule(0); r = engine->RemoveConfigGroup("group1"); assert( r >= 0 ); bout.buffer = ""; mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script3, strlen(script3), 0); engine->SetMessageCallback(asMETHOD(CBufferedOutStream,Callback), &bout, asCALL_THISCALL); r = mod->Build(); if( r >= 0 || bout.buffer != "TestDynamicConfig (1, 1) : Info : Compiling void Test()\n" "TestDynamicConfig (3, 10) : Error : Expected ';'\n" ) { fail = true; } engine->Release(); //------------------ // Test global behaviours engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); RegisterScriptString_Generic(engine); r = engine->BeginConfigGroup("group1"); assert( r >= 0 ); r = engine->RegisterObjectType("mytype", sizeof(int), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_PRIMITIVE); r = engine->RegisterObjectMethod("mytype", "string@ opAdd_r(const string &in)", asFUNCTION(MyFunc), asCALL_GENERIC); assert( r >= 0 ); r = engine->EndConfigGroup(); assert( r >= 0 ); mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script4, strlen(script4), 0); engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); r = mod->Build(); if( r < 0 ) { fail = true; } r = engine->RemoveConfigGroup("group1"); assert( r == asCONFIG_GROUP_IS_IN_USE ); engine->DiscardModule(0); r = engine->RemoveConfigGroup("group1"); assert( r >= 0 ); // Register the type again, but without the operator overload r = engine->BeginConfigGroup("group1"); assert( r >= 0 ); r = engine->RegisterObjectType("mytype", sizeof(int), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_PRIMITIVE); r = engine->EndConfigGroup(); assert( r >= 0 ); bout.buffer = ""; mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script4, strlen(script4), 0); engine->SetMessageCallback(asMETHOD(CBufferedOutStream,Callback), &bout, asCALL_THISCALL); r = mod->Build(); if( r >= 0 || bout.buffer != "TestDynamicConfig (1, 1) : Info : Compiling void Test()\n" "TestDynamicConfig (5, 9) : Error : No matching operator that takes the types 'string&' and 'mytype&' found\n" ) { fail = true; } engine->Release(); //------------------ // Test object types held by external variable, i.e. any // TODO: The application needs a way to tell the engine that the type is in use so that it won't be removed /* CScriptAny *any = 0; engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); RegisterScriptAny(engine); engine->BeginConfigGroup("group1"); r = engine->RegisterObjectType("mytype", sizeof(int), asOBJ_PRIMITIVE); r = engine->RegisterObjectBehaviour("mytype", asBEHAVE_CONSTRUCT, "void f()", asFUNCTION(Construct), asCALL_GENERIC); r = engine->RegisterObjectBehaviour("mytype", asBEHAVE_ADDREF, "void f()", asFUNCTION(AddRef), asCALL_GENERIC); r = engine->RegisterObjectBehaviour("mytype", asBEHAVE_RELEASE, "void f()", asFUNCTION(Release), asCALL_GENERIC); any = (CScriptAny*)engine->CreateScriptObject(engine->GetTypeIdByDecl(0, "any")); r = engine->RegisterGlobalProperty("any g_any", any); engine->EndConfigGroup(); mod->AddScriptSection(0, TESTNAME, script5, strlen(script5), 0); engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); r = mod->Build(0); if( r < 0 ) fail = true; r = engine->ExecuteString(0, "Test()"); if( r != asEXECUTION_FINISHED ) { fail = true; } engine->Discard(0); engine->GarbageCollect(); int *o = 0; any->Retrieve(&o, engine->GetTypeIdByDecl(0, "mytype@")); if( o == 0 ) fail = true; if( --(*o) != 1 ) fail = true; // The mytype variable is still stored in the any variable so we shouldn't be allowed to remove it's configuration group r = engine->RemoveConfigGroup("group1"); assert( r < 0 ); any->Release(); engine->GarbageCollect(); // Now it should be possible to remove the group r = engine->RemoveConfigGroup("group1"); assert( r >= 0 ); engine->Release(); */ //------------- // Test array types engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); r = engine->BeginConfigGroup("group1"); assert( r >= 0 ); r = engine->RegisterObjectType("int[]", sizeof(int), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_PRIMITIVE); r = engine->EndConfigGroup(); assert( r >= 0 ); mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script6, strlen(script6), 0); engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); r = mod->Build(); if( r < 0 ) { fail = true; } r = engine->RemoveConfigGroup("group1"); assert( r == asCONFIG_GROUP_IS_IN_USE ); engine->DiscardModule(0); r = engine->RemoveConfigGroup("group1"); assert( r >= 0 ); engine->Release(); //------------- // Test object types in struct members engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); r = engine->BeginConfigGroup("group1"); assert( r >= 0 ); r = engine->RegisterObjectType("mytype", sizeof(int), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_PRIMITIVE); r = engine->EndConfigGroup(); assert( r >= 0 ); mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script7, strlen(script7), 0); engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); r = mod->Build(); if( r < 0 ) { fail = true; } r = engine->RemoveConfigGroup("group1"); assert( r == asCONFIG_GROUP_IS_IN_USE ); engine->DiscardModule(0); r = engine->RemoveConfigGroup("group1"); assert( r >= 0 ); bout.buffer = ""; mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script7, strlen(script7), 0); engine->SetMessageCallback(asMETHOD(CBufferedOutStream,Callback), &bout, asCALL_THISCALL); r = mod->Build(); if( r >= 0 || bout.buffer != "TestDynamicConfig (3, 3) : Error : Identifier 'mytype' is not a data type\n" ) { fail = true; } engine->Release(); //------------- // Test object types in function declarations engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); r = engine->BeginConfigGroup("group1"); assert( r >= 0 ); r = engine->RegisterObjectType("mytype", sizeof(int), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_PRIMITIVE); r = engine->EndConfigGroup(); assert( r >= 0 ); mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script8, strlen(script8), 0); engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); r = mod->Build(); if( r < 0 ) { fail = true; } r = engine->RemoveConfigGroup("group1"); assert( r == asCONFIG_GROUP_IS_IN_USE ); engine->DiscardModule(0); r = engine->RemoveConfigGroup("group1"); assert( r >= 0 ); bout.buffer = ""; mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script8, strlen(script8), 0); engine->SetMessageCallback(asMETHOD(CBufferedOutStream,Callback), &bout, asCALL_THISCALL); r = mod->Build(); if( r >= 0 || bout.buffer != "TestDynamicConfig (1, 11) : Error : Identifier 'mytype' is not a data type\n" "TestDynamicConfig (1, 1) : Info : Compiling void Test(int&in)\n" "TestDynamicConfig (1, 11) : Error : Identifier 'mytype' is not a data type\n" ) { fail = true; } engine->Release(); //------------- // Test object types in script arrays engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); r = engine->BeginConfigGroup("group1"); assert( r >= 0 ); r = engine->RegisterObjectType("mytype", sizeof(int), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_PRIMITIVE); r = engine->EndConfigGroup(); assert( r >= 0 ); mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script9, strlen(script9), 0); engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); r = mod->Build(); if( r < 0 ) { fail = true; } r = engine->RemoveConfigGroup("group1"); assert( r == asCONFIG_GROUP_IS_IN_USE ); engine->DiscardModule(0); r = engine->RemoveConfigGroup("group1"); assert( r >= 0 ); bout.buffer = ""; mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script9, strlen(script9), 0); engine->SetMessageCallback(asMETHOD(CBufferedOutStream,Callback), &bout, asCALL_THISCALL); r = mod->Build(); if( r >= 0 || bout.buffer != "TestDynamicConfig (1, 1) : Info : Compiling void Test()\n" "TestDynamicConfig (3, 11) : Error : Expected expression value\n" ) { fail = true; } engine->Release(); //------------------ // Test object types held by external variable, i.e. any /* engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); RegisterScriptAny(engine); engine->BeginConfigGroup("group1"); r = engine->RegisterObjectType("mytype", sizeof(int), asOBJ_PRIMITIVE); any = (CScriptAny*)engine->CreateScriptObject(engine->GetTypeIdByDecl(0, "any")); r = engine->RegisterGlobalProperty("any g_any", any); engine->EndConfigGroup(); mod->AddScriptSection(0, TESTNAME, script10, strlen(script10), 0); engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); r = mod->Build(0); if( r < 0 ) fail = true; r = engine->ExecuteString(0, "Test()"); if( r != asEXECUTION_FINISHED ) { fail = true; } engine->Discard(0); engine->GarbageCollect(); asIScriptArray *array = 0; any->Retrieve(&array, engine->GetTypeIdByDecl(0, "mytype[]@")); if( array == 0 ) fail = true; else array->Release(); engine->GarbageCollect(); // The mytype variable is still stored in the any variable so we shouldn't be allowed to remove it's configuration group r = engine->RemoveConfigGroup("group1"); assert( r < 0 ); any->Release(); engine->GarbageCollect(); // Now it should be possible to remove the group r = engine->RemoveConfigGroup("group1"); assert( r >= 0 ); engine->Release(); */ //------------------- // Test references between config groups engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); engine->BeginConfigGroup("group1"); r = engine->RegisterObjectType("mytype", sizeof(int), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_PRIMITIVE); assert( r >= 0 ); engine->EndConfigGroup(); engine->BeginConfigGroup("group2"); r = engine->RegisterGlobalFunction("void func(mytype)", asFUNCTION(0), asCALL_GENERIC); assert( r >= 0 ); engine->EndConfigGroup(); r = engine->RemoveConfigGroup("group1"); assert( r == asCONFIG_GROUP_IS_IN_USE ); r = engine->RemoveConfigGroup("group2"); assert( r <= 0 ); r = engine->RemoveConfigGroup("group1"); assert( r <= 0 ); engine->Release(); //-------------------- // Test situation where the default group references a dynamic group. It will then be impossible // to remove the dynamic group, but the application must still be able to release the engine. engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); engine->BeginConfigGroup("group1"); r = engine->RegisterObjectType("mytype", sizeof(int), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_PRIMITIVE); assert( r >= 0 ); engine->EndConfigGroup(); r = engine->RegisterGlobalFunction("void func(mytype)", asFUNCTION(0), asCALL_GENERIC); assert( r >= 0 ); r = engine->RemoveConfigGroup("group1"); assert( r == asCONFIG_GROUP_IS_IN_USE ); engine->Release(); //---------------------- // Test that it is possible to repeat the registration of the config group engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); r = engine->BeginConfigGroup("g1"); assert( r >= 0 ); RegisterScriptString_Generic(engine); r = engine->EndConfigGroup(); assert( r >= 0 ); r = engine->ExecuteString(0, "string a = \"test\""); assert( r == asEXECUTION_FINISHED ); r = engine->DiscardModule(0); assert( r >= 0 ); r = engine->GarbageCollect(); assert( r >= 0 ); r = engine->RemoveConfigGroup("g1"); assert( r >= 0 ); // again.. r = engine->BeginConfigGroup("g1"); assert( r >= 0 ); RegisterScriptString_Generic(engine); r = engine->EndConfigGroup(); assert( r >= 0 ); r = engine->ExecuteString(0, "string a = \"test\""); assert( r == asEXECUTION_FINISHED ); r = engine->DiscardModule(0); assert( r >= 0 ); r = engine->GarbageCollect(); assert( r >= 0 ); r = engine->RemoveConfigGroup("g1"); assert( r >= 0 ); engine->Release(); //----------------------------- // Test that it isn't possible to register the sample property in two different groups engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); engine->BeginConfigGroup("a"); r = engine->RegisterGlobalProperty("int a", 0); assert( r >= 0 ); engine->EndConfigGroup(); r = engine->RegisterGlobalProperty("int a", 0); assert( r < 0 ); engine->Release(); //------------------------------ // Test that ExecuteString doesn't lock dynamic config groups engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); r = engine->BeginConfigGroup("g1"); assert( r >= 0 ); RegisterScriptString_Generic(engine); r = engine->EndConfigGroup(); assert( r >= 0 ); r = engine->ExecuteString(0, "string a = \"test\""); assert( r == asEXECUTION_FINISHED ); // Garbage collect and remove config group before discarding module r = engine->GarbageCollect(); assert( r >= 0 ); r = engine->RemoveConfigGroup("g1"); assert( r >= 0 ); engine->Release(); // Success return fail; }
bool Test() { bool fail = Test2(); int r; asIScriptModule *mod = 0; asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); RegisterScriptString_Generic(engine); engine->RegisterGlobalFunction("void Assert(bool)", asFUNCTION(Assert), asCALL_GENERIC); COutStream out; CBufferedOutStream bout; engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script1); r = mod->Build(); if( r < 0 ) fail = true; // Verify that GetObjectTypeByIndex recognizes the script class if( mod->GetObjectTypeCount() != 1 ) fail = true; asIObjectType *type = mod->GetObjectTypeByIndex(0); if( strcmp(type->GetName(), "Test") != 0 ) fail = true; asIScriptContext *ctx = 0; r = engine->ExecuteString(0, "TestStruct()", &ctx); if( r != asEXECUTION_FINISHED ) { if( r == asEXECUTION_EXCEPTION ) PrintException(ctx); fail = true; } if( ctx ) ctx->Release(); bout.buffer = ""; mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script2); engine->SetMessageCallback(asMETHOD(CBufferedOutStream,Callback), &bout, asCALL_THISCALL); r = mod->Build(); if( r >= 0 || bout.buffer != "TestScriptStruct (3, 4) : Error : Class properties cannot be declared as const\n" ) fail = true; mod->AddScriptSection(TESTNAME, script3); engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); r = mod->Build(); if( r < 0 ) fail = true; r = engine->ExecuteString(0, "TestArrayInStruct()"); if( r != 0 ) fail = true; mod->AddScriptSection(TESTNAME, script4, strlen(script4), 0); r = mod->Build(); if( r < 0 ) fail = true; r = engine->ExecuteString(0, "Test()"); if( r != 0 ) fail = true; bout.buffer = ""; mod->AddScriptSection(TESTNAME, script5, strlen(script5), 0); engine->SetMessageCallback(asMETHOD(CBufferedOutStream,Callback), &bout, asCALL_THISCALL); r = mod->Build(); if( r >= 0 || bout.buffer != "TestScriptStruct (2, 7) : Error : Name conflict. 'A' is a class.\n" "TestScriptStruct (6, 9) : Error : Name conflict. 'a' is an object property.\n" ) fail = true; bout.buffer = ""; mod->AddScriptSection(TESTNAME, script6, strlen(script6), 0); r = mod->Build(); if( r >= 0 || bout.buffer != "TestScriptStruct (1, 7) : Error : Illegal member type\n" "TestScriptStruct (5, 7) : Error : Illegal member type\n" ) fail = true; mod->AddScriptSection(TESTNAME, script7, strlen(script7), 0); engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); r = mod->Build(); if( r < 0 ) fail = true; r = engine->ExecuteString(0, "TestHandleInStruct()", &ctx); if( r != 0 ) { if( r == asEXECUTION_EXCEPTION ) { printf("%s\n", ctx->GetExceptionString()); } fail = true; } if( ctx ) ctx->Release(); mod->AddScriptSection(TESTNAME, script8, strlen(script8), 0); r = mod->Build(); if( r < 0 ) fail = true; r = engine->ExecuteString(0, "TestHandleInStruct2()"); if( r != 0 ) fail = true; mod->AddScriptSection(TESTNAME, script9, strlen(script9), 0); r = mod->Build(); if( r < 0 ) fail = true; r = engine->ExecuteString(0, "Test()"); if( r != 0 ) fail = true; bout.buffer = ""; mod->AddScriptSection(TESTNAME, script10, strlen(script10), 0); engine->SetMessageCallback(asMETHOD(CBufferedOutStream,Callback), &bout, asCALL_THISCALL); r = mod->Build(); if( r >= 0 ) fail = true; if( bout.buffer != "TestScriptStruct (1, 7) : Error : Illegal member type\n" ) fail = true; bout.buffer = ""; mod->AddScriptSection(TESTNAME, script11, strlen(script11), 0); r = mod->Build(); if( r >= 0 ) fail = true; if( bout.buffer != "TestScriptStruct (5, 1) : Info : Compiling void Test()\nTestScriptStruct (9, 11) : Error : Reference is read-only\n" ) fail = true; mod->AddScriptSection(TESTNAME, script12, strlen(script12), 0); mod->AddScriptSection(TESTNAME, script13, strlen(script13), 0); engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); r = mod->Build(); if( r < 0 ) fail = true; // The garbage collection doesn't have to be invoked immediately. Modules // can even be discarded before calling the garbage collector. engine->GarbageCollect(); // Make sure it is possible to copy a script class that contains an object handle mod->AddScriptSection(TESTNAME, script14, strlen(script14), 0); r = mod->Build(); if( r < 0 ) fail = true; r = engine->ExecuteString(0, "A a; B b; @a.b = @b; b.val = 1; A a2; a2 = a; Assert(a2.b.val == 1);"); if( r != asEXECUTION_FINISHED ) fail = true; // Make sure it is possible to copy a script class that contains an array const char *script15 = "class Some \n" "{ \n" " int[] i; // need be array \n" "} \n" "void main() \n" "{ \n" " Some e; \n" " e=some(e); // crash \n" "} \n" "Some@ some(Some@ e) \n" "{ \n" " return e; \n" "} \n"; mod->AddScriptSection(TESTNAME, script15); r = mod->Build(); if( r < 0 ) fail = true; r = engine->ExecuteString(0, "main()"); if( r != asEXECUTION_FINISHED ) fail = true; engine->Release(); // Success return fail; }
bool Test() { bool fail = false; int r; asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); RegisterScriptArray(engine, true); RegisterScriptString_Generic(engine); engine->RegisterGlobalFunction("void Assert(bool)", asFUNCTION(Assert), asCALL_GENERIC); engine->RegisterGlobalFunction("double atof(const string &in)",asFUNCTION(StringToDouble),asCALL_GENERIC); COutStream out; asIScriptModule *mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script1, strlen(script1), 0); engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); r = mod->Build(); if( r < 0 ) { TEST_FAILED; PRINTF("%s: Failed to compile the script\n", TESTNAME); } asIScriptContext *ctx = engine->CreateContext(); r = ExecuteString(engine, "TestArrayHandle()", mod, ctx); if( r != asEXECUTION_FINISHED ) { if( r == asEXECUTION_EXCEPTION ) PrintException(ctx); PRINTF("%s: Failed to execute script\n", TESTNAME); TEST_FAILED; } if( ctx ) ctx->Release(); mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script2, strlen(script2), 0); engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); r = mod->Build(); if( r < 0 ) { TEST_FAILED; PRINTF("%s: Failed to compile the script\n", TESTNAME); } ctx = engine->CreateContext(); r = ExecuteString(engine, "TestArrayHandle2()", mod, ctx); if( r != asEXECUTION_FINISHED ) { if( r == asEXECUTION_EXCEPTION ) PrintException(ctx); PRINTF("%s: Failed to execute script\n", TESTNAME); TEST_FAILED; } if( ctx ) ctx->Release(); engine->Release(); // { engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); RegisterScriptArray(engine, true); engine->RegisterGlobalFunction("void assert(bool)", asFUNCTION(Assert), asCALL_GENERIC); engine->SetEngineProperty(asEP_OPTIMIZE_BYTECODE, false); const char *script = "class Node \n" "{ \n" " Node@[]@ GetSubnodes() { return subNodes; } \n" " Node@[] subNodes; \n" " int member; \n" "} \n" "void TestFunc(Node@ input) \n" "{ \n" " Node@[]@ nodearray; \n" " Node@ subnode; \n" " // Case 1. Works as expected \n" " @nodearray = @input.GetSubnodes(); \n" " @subnode = @nodearray[0]; \n" " int value1 = subnode.member; // <- ok \n" " assert( value1 == 42 ); \n" " // Case 2. Wrong address sent to following operations on 'subnode' \n" " @subnode = @input.GetSubnodes()[0]; \n" " int value2 = subnode.member; // <- weird behavior \n" " assert( value2 == 42 ); \n" "} \n"; mod = engine->GetModule("mod", asGM_ALWAYS_CREATE); mod->AddScriptSection("script", script); r = mod->Build(); if( r < 0 ) { TEST_FAILED; } else { asIScriptContext *ctx = engine->CreateContext(); r = ExecuteString(engine, "Node n; \n" "n.subNodes.resize(1); \n" "@n.subNodes[0] = @Node(); \n" "n.subNodes[0].member = 42; \n" "TestFunc(n); \n", mod, ctx); if( r != asEXECUTION_FINISHED ) { TEST_FAILED; if( r == asEXECUTION_EXCEPTION ) PrintException(ctx); } ctx->Release(); } engine->Release(); } // Success return fail; }
bool Test() { bool fail = Test2(); int r; COutStream out; asIScriptContext *ctx; asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); RegisterScriptString_Generic(engine); engine->RegisterGlobalFunction("void Assert(bool)", asFUNCTION(Assert), asCALL_GENERIC); asIScriptModule *mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script1, strlen(script1), 0); r = mod->Build(); if( r < 0 ) { fail = true; printf("%s: Failed to compile the script\n", TESTNAME); } r = engine->ExecuteString(0, "TestArray()", &ctx); if( r != asEXECUTION_FINISHED ) { if( r == asEXECUTION_EXCEPTION ) PrintException(ctx); printf("%s: Failed to execute script\n", TESTNAME); fail = true; } if( ctx ) ctx->Release(); mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script2, strlen(script2), 0); r = mod->Build(); if( r < 0 ) { fail = true; printf("%s: Failed to compile the script\n", TESTNAME); } r = engine->ExecuteString(0, "TestArrayException()"); if( r != asEXECUTION_EXCEPTION ) { printf("%s: No exception\n", TESTNAME); fail = true; } mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script3, strlen(script3), 0); r = mod->Build(); if( r < 0 ) { fail = true; printf("%s: Failed to compile the script\n", TESTNAME); } r = engine->ExecuteString(0, "TestArrayMulti()", &ctx); if( r != asEXECUTION_FINISHED ) { printf("%s: Failure\n", TESTNAME); fail = true; } if( r == asEXECUTION_EXCEPTION ) { PrintException(ctx); } if( ctx ) ctx->Release(); ctx = 0; mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script4, strlen(script4), 0); r = mod->Build(); if( r < 0 ) { fail = true; printf("%s: Failed to compile the script\n", TESTNAME); } r = engine->ExecuteString(0, "TestArrayChar()", &ctx); if( r != asEXECUTION_FINISHED ) { printf("%s: Failure\n", TESTNAME); fail = true; } if( r == asEXECUTION_EXCEPTION ) { PrintException(ctx); } if( ctx ) ctx->Release(); mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script5, strlen(script5), 0); r = mod->Build(); if( r < 0 ) fail = true; r = engine->ExecuteString(0, "TestArrayInitList()", &ctx); if( r != asEXECUTION_FINISHED ) fail = true; if( r == asEXECUTION_EXCEPTION ) PrintException(ctx); if( ctx ) ctx->Release(); CBufferedOutStream bout; engine->SetMessageCallback(asMETHOD(CBufferedOutStream,Callback), &bout, asCALL_THISCALL); mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script6, strlen(script6), 0); r = mod->Build(); if( r >= 0 ) fail = true; if( bout.buffer != "TestArray (1, 1) : Info : Compiling void Test()\n" "TestArray (3, 15) : Error : Initialization lists cannot be used with 'int[]@'\n" "TestArray (4, 16) : Error : Initialization lists cannot be used with 'int'\n" ) fail = true; // Array object must call default constructor of the script classes engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script7, strlen(script7), 0); r = mod->Build(); if( r < 0 ) fail = true; r = engine->ExecuteString(0, "Test()"); if( r != asEXECUTION_FINISHED ) fail = true; // Test bool[] on Mac OS X with PPC CPU // Submitted by Edward Rudd const char *script8 = "bool[] f(10); \n" "for (int i=0; i<10; i++) { \n" " f[i] = false; \n" "} \n" "Assert(f[0] == false); \n" "Assert(f[1] == false); \n" "f[0] = true; \n" "Assert(f[0] == true); \n" "Assert(f[1] == false); \n"; r = engine->ExecuteString(0, script8); if( r != asEXECUTION_FINISHED ) fail = true; // Make sure it is possible to do multiple assignments with the array type r = engine->ExecuteString(0, "int[] a, b, c; a = b = c;"); if( r < 0 ) fail = true; engine->Release(); // Success return fail; }
bool Test() { bool fail = false; int number = 0; int r; asIScriptEngine *engine = 0; COutStream out; // Test 1 // Importing a function from another module engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); RegisterScriptString_Generic(engine); engine->RegisterGlobalProperty("int number", &number); asIScriptModule *mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(":1", script1, strlen(script1), 0); mod->Build(); mod = engine->GetModule("DynamicModule", asGM_ALWAYS_CREATE); mod->AddScriptSection(":2", script2, strlen(script2), 0); mod->Build(); // Bind all functions that the module imports r = engine->GetModule(0)->BindAllImportedFunctions(); assert( r >= 0 ); ExecuteString(engine, "main()", engine->GetModule(0)); engine->Release(); if( number != 1234567890 ) { printf("%s: Failed to set the number as expected\n", TESTNAME); fail = true; } // Test 2 // Two identical structures declared in different modules are not the same engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); RegisterScriptString_Generic(engine); mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(":3", script3, strlen(script3), 0); r = mod->Build(); assert( r >= 0 ); mod = engine->GetModule("DynamicModule", asGM_ALWAYS_CREATE); mod->AddScriptSection(":4", script4, strlen(script4), 0); r = mod->Build(); assert( r >= 0 ); // Bind all functions that the module imports r = engine->GetModule(0)->BindAllImportedFunctions(); assert( r < 0 ); { const char *script = "import int test(void) from 'mod1'; \n" "void main() \n" "{ \n" " int str; \n" " str = test(); \n" "}\n"; mod->AddScriptSection("4", script); r = mod->Build(); if( r < 0 ) fail = true; } engine->Release(); // Success return fail; }