bool Test()
{
	bool fail = false;

	int r;

 	asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);

	r = engine->RegisterObjectType("obj", 4, asOBJ_VALUE | asOBJ_POD | asOBJ_APP_PRIMITIVE); assert( r >= 0 );
//  r = engine->RegisterObjectBehaviour("obj", asBEHAVE_ALLOC, "obj &f(uint)", asFUNCTION(MyAlloc), asCALL_CDECL); assert( r >= 0 );
//  r = engine->RegisterObjectBehaviour("obj", asBEHAVE_FREE, "void f(obj &in)", asFUNCTION(MyFree), asCALL_CDECL); assert( r >= 0 );
	if( !strstr(asGetLibraryOptions(),"AS_MAX_PORTABILITY") )
	{
		r = engine->RegisterGlobalFunction("obj retObj()", asFUNCTION(ReturnObj), asCALL_CDECL); assert( r >= 0 );
	}
	r = engine->RegisterGlobalFunction("obj retObj2(obj)", asFUNCTION(ReturnObjGeneric), asCALL_GENERIC); assert( r >= 0 );

	COutStream out;
	engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL);
	engine->ExecuteString(0, "obj o");

	if( !strstr(asGetLibraryOptions(),"AS_MAX_PORTABILITY") )
		engine->ExecuteString(0, "retObj()");

	engine->ExecuteString(0, "obj o; retObj2(o)");

	engine->ExecuteString(0, "obj[] o(2)");

	asIScriptModule *mod = engine->GetModule(0, asGM_ALWAYS_CREATE);
	mod->AddScriptSection(0, script, strlen(script));
	mod->Build();
	asIScriptContext *ctx = engine->CreateContext();
	ctx->Prepare(engine->GetModule(0)->GetFunctionIdByName("test"));
	int v = 0;
	ctx->SetArgObject(0, &v);
	ctx->Execute();
	ctx->Release();

	engine->Release();

	if( objectsAllocated )
	{
		printf("%s: Failed\n", TESTNAME);
		fail = true;
	}

	// Success
	return fail;
}
Esempio n. 2
0
bool TestExecuteMixedArgs()
{
	bool fail = false;

	asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
	if( strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY") )
		engine->RegisterGlobalFunction("void cfunction(int, float, double, int)", asFUNCTION(cfunction_gen), asCALL_GENERIC);
	else
		engine->RegisterGlobalFunction("void cfunction(int, float, double, int)", asFUNCTION(cfunction), asCALL_CDECL);

	ExecuteString(engine, "cfunction(10, 1.92f, 3.88, 97)");
	
	if (!called) {
		printf("\n%s: cfunction not called from script\n\n", TESTNAME);
		TEST_FAILED;
	} else if (!testVal) {
		printf("\n%s: testVal is not of expected value. Got (%d, %f, %f, %c), expected (%d, %f, %f, %c)\n\n", TESTNAME, t1, t2, t3, t4, 10, 1.92f, 3.88, 97);
		TEST_FAILED;
	}

	if( !strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY") )
	{
		called = false;
		testVal = false;
		
		COutStream out;
		engine->SetMessageCallback(asMETHOD(COutStream, Callback), &out, asCALL_THISCALL);
		engine->RegisterGlobalFunction("void cfunction2(int64, float, int8, int)", asFUNCTION(cfunction2), asCALL_CDECL);
		
		ExecuteString(engine, "cfunction2(0x102030405, 3, 24, 128)");
		
		if( !called )
		{
			printf("%s: cfunction2 not called\n", TESTNAME);
			TEST_FAILED;
		}
		else if( !testVal )
		{
			printf("%s: testVal not of expected value. Got(%lld, %g, %d, %d)\n", TESTNAME, g1, g2, g3, g4);
			TEST_FAILED;
		}
	}

	engine->Release();
	engine = NULL;

	return fail;
}
bool TestExecute2Args()
{
	bool fail = false;

 	asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
	if( strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY") )
		engine->RegisterGlobalFunction("void cfunction(int, int)", asFUNCTION(cfunction_gen), asCALL_GENERIC);
	else
		engine->RegisterGlobalFunction("void cfunction(int, int)", asFUNCTION(cfunction), asCALL_CDECL);

	ExecuteString(engine, "cfunction(5, 9)");

	if( !called ) 
	{
		// failure
		printf("\n%s: cfunction not called from script\n\n", TESTNAME);
		TEST_FAILED;
	} 
	else if( testVal != (5 + 9) ) 
	{
		// failure
		printf("\n%s: testVal is not of expected value. Got %d, expected %d\n\n", TESTNAME, testVal, (5 + 9));
		TEST_FAILED;
	}

	engine->Release();
	
	// Success
	return fail;
}
Esempio n. 4
0
void ConfigureEngine(asIScriptEngine *engine)
{
	int r;

	// Register the script string type
	// Look at the implementation for this function for more information  
	// on how to register a custom string type, and other object types.
	RegisterStdString(engine);

	if( !strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY") )
	{
		// Register the functions that the scripts will be allowed to use.
		// Note how the return code is validated with an assert(). This helps
		// us discover where a problem occurs, and doesn't pollute the code
		// with a lot of if's. If an error occurs in release mode it will
		// be caught when a script is being built, so it is not necessary
		// to do the verification here as well.
		r = engine->RegisterGlobalFunction("void print(const string &in)", asFUNCTION(PrintString), asCALL_CDECL); assert( r >= 0 );
	}


	// It is possible to register the functions, properties, and types in 
	// configuration groups as well. When compiling the scripts it then
	// be defined which configuration groups should be available for that
	// script. If necessary a configuration group can also be removed from
	// the engine, so that the engine configuration could be changed 
	// without having to recompile all the scripts.
}
bool TestReturnD()
{
	bool fail = false;

 	asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
	engine->RegisterGlobalProperty("double returnValue_d", &returnValue_d);
	if( strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY") )
		engine->RegisterGlobalFunction("double cfunction_d()", asFUNCTION(cfunction_d_gen), asCALL_GENERIC);
	else
		engine->RegisterGlobalFunction("double cfunction_d()", asFUNCTION(cfunction_d), asCALL_CDECL);

	int r = ExecuteString(engine, "returnValue_d = cfunction_d()");
	if( r != asEXECUTION_FINISHED ) TEST_FAILED;

	if( returnValue_d != 88.32 ) 
	{
		printf("\n%s: cfunction didn't return properly. Expected %f, got %f\n\n", TESTNAME, 88.32, returnValue_d);
		TEST_FAILED;
	}

	engine->Release();
	
	// Success
	return fail;
}
bool TestExecute()
{
	bool ret = false;

	asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
	if( strstr(asGetLibraryOptions(),"AS_MAX_PORTABILITY") )
	{
		int r = engine->RegisterGlobalFunction("void cfunction()", asFUNCTION(cfunction_generic), asCALL_GENERIC); assert( r >= 0 );
	}
	else
	{
		int r = engine->RegisterGlobalFunction("void cfunction()", asFUNCTION(cfunction), asCALL_CDECL); assert( r >= 0 );
	}
	engine->ExecuteString(0, "cfunction()");

	if (!called) {
		printf("\n%s: cfunction not called from script\n\n", TESTNAME);
		ret = true;
	}

	
	asIScriptContext *ctx = engine->CreateContext();
	assert(ctx->SetUserData((void*)(size_t)0xDEADF00D) == 0);
	assert(ctx->GetUserData() == (void*)(size_t)0xDEADF00D);
	assert(ctx->SetUserData(0) == (void*)(size_t)0xDEADF00D);
	ctx->Release();

	engine->Release();
	engine = NULL;

	return ret;
}
bool TestExecute4Argsf()
{
	bool ret = false;

 	asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
	if( strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY") )
		engine->RegisterGlobalFunction("void cfunction(float, float, double, float)", asFUNCTION(cfunction_gen), asCALL_GENERIC);
	else
		engine->RegisterGlobalFunction("void cfunction(float, float, double, float)", asFUNCTION(cfunction), asCALL_CDECL);

	COutStream out;
	engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL);
	ExecuteString(engine, "cfunction(9.2f, 13.3f, 18.8, 3.1415f)");

	if( !called ) 
	{
		// failure
		printf("\n%s: cfunction not called from script\n\n", TESTNAME);
		ret = true;
	} 
	else if( !testVal ) 
	{
		// failure
		printf("\n%s: testVal is not of expected value. Got (%f, %f, %f, %f), expected (%f, %f, %f, %f)\n\n", TESTNAME, t1, t2, t3, t4, 9.2f, 13.3f, 18.8, 3.1415f);
		ret = true;
	}

	engine->Release();
	
	// Success
	return ret;
}
bool TestHelper()
{
	if( strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY") )
	{
		// Skipping this due to not supporting native calling conventions
		printf("Skipped due to AS_MAX_PORTABILITY\n");
		return false;
	}

	bool fail = false;

	asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);

	RegisterScriptString(engine);

	// TODO: Add validation of return type

	RegisterGlobalFunction(engine, "void func1(int)", func1, asCALL_CDECL);
	RegisterGlobalFunction(engine, "void func2(string &in)", func2, asCALL_CDECL);
	RegisterGlobalFunction(engine, "void func3(string @)", func3, asCALL_CDECL);
	RegisterGlobalFunction(engine, "void func4(int &in)", func4, asCALL_CDECL);
	RegisterGlobalFunction(engine, "void func5(int &out)", func5, asCALL_CDECL);
	RegisterGlobalFunction(engine, "void func6(string @&out)", func6, asCALL_CDECL);
	RegisterGlobalFunction(engine, "void func7(string @&out)", func7, asCALL_CDECL);
	RegisterGlobalFunction(engine, "void func8(int, string &)", func8, asCALL_CDECL);
	RegisterGlobalFunction(engine, "void func9(string &, int)", func9, asCALL_CDECL);

	engine->Release();

	return fail;
}
bool TestExecuteMixedArgs()
{
	bool ret = false;

	asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
	if( strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY") )
		engine->RegisterGlobalFunction("void cfunction(int, float, double, int)", asFUNCTION(cfunction_gen), asCALL_GENERIC);
	else
		engine->RegisterGlobalFunction("void cfunction(int, float, double, int)", asFUNCTION(cfunction), asCALL_CDECL);

	engine->ExecuteString(0, "cfunction(10, 1.92f, 3.88, 97)");
	
	if (!called) {
		printf("\n%s: cfunction not called from script\n\n", TESTNAME);
		ret = true;
	} else if (!testVal) {
		printf("\n%s: testVal is not of expected value. Got (%d, %f, %f, %c), expected (%d, %f, %f, %c)\n\n", TESTNAME, t1, t2, t3, t4, 10, 1.92f, 3.88, 97);
		ret = true;
	}

	engine->Release();
	engine = NULL;

	return ret;
}
bool TestNegateOperator()
{
	bool fail = false;

 	asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
	engine->RegisterObjectType("obj", sizeof(int), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_PRIMITIVE);
	if( strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY") )
	{
		engine->RegisterObjectMethod("obj", "obj opNeg()", asFUNCTION(negate_gen), asCALL_GENERIC);
		engine->RegisterObjectMethod("obj", "obj opSub(obj &in)", asFUNCTION(minus_gen), asCALL_GENERIC);
	}
	else
	{
		engine->RegisterObjectMethod("obj", "obj opNeg()", asFUNCTION(negate), asCALL_CDECL_OBJLAST);
		engine->RegisterObjectMethod("obj", "obj opSub(obj &in)", asFUNCTION(minus), asCALL_CDECL_OBJFIRST);
	}
	engine->RegisterGlobalProperty("obj testVal", &testVal);

	testVal = 1000;

	COutStream obj;
	engine->SetMessageCallback(asMETHOD(COutStream,Callback), &obj, asCALL_THISCALL);
	ExecuteString(engine, "testVal = -testVal");

	if( !called ) 
	{
		// failure
		printf("\n%s: behaviour function was not called from script\n\n", TESTNAME);
		TEST_FAILED;
	} 
	else if( testVal != -1000 ) 
	{
		// failure
		printf("\n%s: testVal is not of expected value. Got %d, expected %d\n\n", TESTNAME, testVal, -1000);
		TEST_FAILED;
	}

	called = false;
	ExecuteString(engine, "testVal = testVal - testVal");

	if( !called ) 
	{
		// failure
		printf("\n%s: behaviour function was not called from script\n\n", TESTNAME);
		TEST_FAILED;
	} 
	else if( testVal != 0 ) 
	{
		// failure
		printf("\n%s: testVal is not of expected value. Got %d, expected %d\n\n", TESTNAME, testVal, 0);
		TEST_FAILED;
	}
	

	engine->Release();
	
	// Success
	return fail;
}
Esempio n. 11
0
bool TestFuncOverload()
{
	if( strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY") )
	{
		printf("%s: Skipped due to AS_MAX_PORTABILITY\n", TESTNAME);
		return false;
	}
	// TODO: Add Test2 again
	bool fail = false; //Test2();
	COutStream out;

	asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
	engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL);
	RegisterScriptString(engine);

	engine->RegisterObjectType("Data", sizeof(void*), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_PRIMITIVE);

	engine->RegisterObjectType("Obj", sizeof(Obj), asOBJ_REF | asOBJ_NOHANDLE);
	engine->RegisterObjectMethod("Obj", "Data &Value()", asMETHOD(Obj, Value), asCALL_THISCALL);
	engine->RegisterObjectMethod("Obj", "void Set(string &in, Data &in)", asMETHOD(Obj, Set), asCALL_THISCALL);
	engine->RegisterObjectMethod("Obj", "void Set(string &in, string &in)", asMETHOD(Obj, Set), asCALL_THISCALL);
	engine->RegisterGlobalProperty("Obj TX", &o);

	engine->RegisterGlobalFunction("void func()", asFUNCTION(FuncVoid), asCALL_CDECL);
	engine->RegisterGlobalFunction("void func(int)", asFUNCTION(FuncInt), asCALL_CDECL);

	asIScriptModule *mod = engine->GetModule(0, asGM_ALWAYS_CREATE);
	mod->AddScriptSection(TESTNAME, script1, strlen(script1), 0);
	int r = mod->Build();
	if( r < 0 )
		fail = true;

	ExecuteString(engine, "func(func(3));", mod);

	CBufferedOutStream bout;
	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 )
		fail = true;
	if( bout.buffer != "TestFuncOverload (1, 1) : Info    : Compiling void ScriptFunc(void)\n"
                       "TestFuncOverload (1, 17) : Error   : Parameter type can't be 'void'\n" )
	{
		printf("%s", bout.buffer.c_str());
		fail = true;
	}

	// Permit void parameter list
	r = engine->RegisterGlobalFunction("void func2(void)", asFUNCTION(FuncVoid), asCALL_CDECL); assert( r >= 0 );

	// Don't permit void parameters
	r = engine->RegisterGlobalFunction("void func3(void n)", asFUNCTION(FuncVoid), asCALL_CDECL); assert( r < 0 );

	engine->Release();

	return fail;
}
Esempio n. 12
0
bool Test()
{
	if( strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY") )
	{
		// Skipping this due to not supporting native calling conventions
		printf("Skipped due to AS_MAX_PORTABILITY\n");
		return false;
	}

	bool fail = false;
	int r;
	COutStream out;

 	asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
	engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL);
	engine->SetEngineProperty(asEP_ALLOW_IMPLICIT_HANDLE_TYPES, true);
	RegisterScriptString(engine);

	r = engine->RegisterGlobalFunction("void assert(bool)", asFUNCTION(Assert), asCALL_GENERIC); assert( r >= 0 );
	r = engine->RegisterGlobalFunction("void print(const string &in)", asFUNCTION(print), asCALL_CDECL); assert( r >= 0 );

	asIScriptModule *mod = engine->GetModule(0, asGM_ALWAYS_CREATE);
	mod->AddScriptSection("script", script1, strlen(script1), 0);
	r = mod->Build();
	if( r < 0 )
	{
		TEST_FAILED;
		printf("Failed to compile the script\n");
	}

	r = ExecuteString(engine, "main()", mod);
	if( r != asEXECUTION_FINISHED )
	{
		TEST_FAILED;
		printf("Execution failed\n");
	}

	if( output != "Hello!\nCreated\n---\n7\n---\n7\n" )
	{
		TEST_FAILED;
		printf("Got: \n%s", output.c_str());
	}

	
	// TODO: The equality operator shouldn't perform handle comparison
	/*
	r = engine->ExecuteString(0, "MyClass a; assert( a == null );");
	if( r >= 0 )
	{
		TEST_FAILED;
	}
	*/

	engine->Release();

	// Success
	return fail;
}
Esempio n. 13
0
void RegisterFont()
{
    int r;

	if (strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY") == 0)
	{
		///class:Font
		r = ScriptManager::Get().engine->RegisterObjectType("Font", 0, asOBJ_REF);
		SDL_assert(r >= 0);

		r = ScriptManager::Get().engine->RegisterObjectBehaviour("Font",
			asBEHAVE_FACTORY, "Font@ f()", asFUNCTION(Font_Factory), asCALL_CDECL);
		SDL_assert(r >= 0);

		r = ScriptManager::Get().engine->RegisterObjectBehaviour("Font", asBEHAVE_ADDREF,
			"void f()", asMETHOD(Font, AddRef), asCALL_THISCALL);
		SDL_assert(r >= 0);

		r = ScriptManager::Get().engine->RegisterObjectBehaviour("Font",
			asBEHAVE_RELEASE, "void f()", asMETHOD(Font, Release), asCALL_THISCALL);
		SDL_assert(r >= 0);

		r = ScriptManager::Get().engine->RegisterObjectMethod("Font",
			"void Load(string &in _name,int _size,int _flags=13)", asMETHOD(Font, Load), asCALL_THISCALL);
		SDL_assert(r >= 0);

		r = ScriptManager::Get().engine->RegisterObjectMethod("Font",
			"void UnLoad()", asMETHOD(Font, UnLoad), asCALL_THISCALL);
		SDL_assert(r >= 0);
	}
	else
	{
		r = ScriptManager::Get().engine->RegisterObjectType("Font", 0, asOBJ_REF);
		SDL_assert(r >= 0);

		r = ScriptManager::Get().engine->RegisterObjectBehaviour("Font",
			asBEHAVE_FACTORY, "Font@ f()", WRAP_FN(Font_Factory), asCALL_GENERIC);
		SDL_assert(r >= 0);

		r = ScriptManager::Get().engine->RegisterObjectBehaviour("Font", asBEHAVE_ADDREF,
			"void f()", WRAP_MFN(Font, AddRef), asCALL_GENERIC);
		SDL_assert(r >= 0);

		r = ScriptManager::Get().engine->RegisterObjectBehaviour("Font",
			asBEHAVE_RELEASE, "void f()", WRAP_MFN(Font, Release), asCALL_GENERIC);
		SDL_assert(r >= 0);

		r = ScriptManager::Get().engine->RegisterObjectMethod("Font",
			"void Load(string &in _name,int _size,int _flags=13)", WRAP_MFN(Font, Load), asCALL_GENERIC);
		SDL_assert(r >= 0);

		r = ScriptManager::Get().engine->RegisterObjectMethod("Font",
			"void UnLoad()", WRAP_MFN(Font, UnLoad), asCALL_GENERIC);
		SDL_assert(r >= 0);
	}

}
Esempio n. 14
0
int qasCreateScriptEngine( qboolean *as_max_portability )
{
    enginehandle_t *eh;
    asIScriptEngine *engine;

    // register the global memory allocation and deallocation functions
    asSetGlobalMemoryFunctions( qasAlloc, qasFree );

    // always new

    // ask for angelscript initialization and script engine creation
    engine = asCreateScriptEngine( ANGELSCRIPT_VERSION );
    if( !engine )
        return -1;

    eh = ( enginehandle_t * )QAS_Malloc( sizeof( enginehandle_t ) );
    eh->handle = numRegisteredEngines++;
    eh->next = engineHandlesHead;
    engineHandlesHead = eh;

    eh->engine = engine;
    eh->max_portability = qfalse;

    if( strstr( asGetLibraryOptions(), "AS_MAX_PORTABILITY" ) )
    {
        QAS_Printf( "* angelscript library with AS_MAX_PORTABILITY detected\n" );
        eh->max_portability = qtrue;
    }

    if( as_max_portability )
        *as_max_portability = eh->max_portability;

    // The script compiler will write any compiler messages to the callback.
    eh->engine->SetMessageCallback( asFUNCTION( qasGenericMessageCallback ), 0, asCALL_CDECL );

    PreRegisterMathAddon( engine );
    PreRegisterScriptArrayAddon( engine, true );
    PreRegisterStringAddon( engine );
    PreRegisterDictionaryAddon( engine );
    PreRegisterTimeAddon( engine );
    PreRegisterScriptAny( engine );
    PreRegisterVec3Addon( engine );
    PreRegisterCvarAddon( engine );
    PreRegisterStringUtilsAddon( engine );

    RegisterMathAddon( engine );
    RegisterScriptArrayAddon( engine, true );
    RegisterStringAddon( engine );
    RegisterDictionaryAddon( engine );
    RegisterTimeAddon( engine );
    RegisterScriptAny( engine );
    RegisterVec3Addon( engine );
    RegisterCvarAddon( engine );
    RegisterStringUtilsAddon( engine );

    return eh->handle;
}
Esempio n. 15
0
bool Test()
{
	if( strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY") )
	{
		printf("%s: This test has not been adapted for AS_MAX_PORTABILITY\n", TESTNAME);
		return false;
	}

	bool fail = false;
	int r;

	asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
	r = engine->RegisterObjectType("Point", sizeof(Point), asOBJ_REF); assert( r >= 0 );
	r = engine->RegisterObjectProperty("Point", "int x", asOFFSET(Point, x)); assert( r >= 0 );
	r = engine->RegisterObjectProperty("Point", "int y", asOFFSET(Point, y)); assert( r >= 0 );
	r = engine->RegisterObjectMethod("Point", "void Add(Point&in)", asFUNCTION(Point_Add), asCALL_CDECL_OBJFIRST); assert( r >= 0 );
	r = engine->RegisterObjectBehaviour("Point", asBEHAVE_FACTORY, "Point@ f()", asFUNCTION(Point_Factory), asCALL_CDECL); assert( r >= 0 );
	r = engine->RegisterObjectMethod("Point", "Point &opAssign(Point &in)", asFUNCTION(Point_Assign), asCALL_CDECL_OBJFIRST); assert( r >= 0 );
	r = engine->RegisterObjectMethod("Point", "int &opIndex(int)", asFUNCTION(Point_Index), asCALL_CDECL_OBJFIRST); assert( r >= 0 );
	r = engine->RegisterObjectBehaviour("Point", asBEHAVE_ADDREF, "void f()", asFUNCTION(Point_AddRef), asCALL_CDECL_OBJFIRST); assert( r >= 0 );
	r = engine->RegisterObjectBehaviour("Point", asBEHAVE_RELEASE, "void f()", asFUNCTION(Point_Release), asCALL_CDECL_OBJFIRST); assert( r >= 0 );

	COutStream out;
	asIScriptModule *mod = engine->GetModule(0, asGM_ALWAYS_CREATE);
	mod->AddScriptSection(TESTNAME, script, strlen(script));
	engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL);
	r = mod->Build();
	if( r < 0 )
	{
		printf("%s: Failed to build\n", TESTNAME);
		TEST_FAILED;
	}
	else
	{
		// Internal return
		asIScriptFunction *func = engine->GetModule(0)->GetFunctionByName("AddPoints");
		asIScriptContext *ctx = engine->CreateContext();
		ctx->Prepare(func);
		Point a, b, c;
		a.x = 1; a.y = 1;
		b.x = 2; b.y = 2;
		ctx->SetArgObject(0, &a);
		ctx->SetArgObject(1, &b);
		r = ctx->Execute();
		if( r != asEXECUTION_FINISHED )
			TEST_FAILED;
		Point *ret = (Point*)ctx->GetReturnObject();
		c = *ret;
		ctx->Release();
	}

	engine->Release();

	return fail;
}
Esempio n. 16
0
bool CScriptEngine::Initialize()
{
    // register custom memory management
    //asSetGlobalMemoryFunctions()

    m_vm = asCreateScriptEngine(ANGELSCRIPT_VERSION);
    m_vm->SetEngineProperty(asEP_USE_CHARACTER_LITERALS, true); // treat 'a' as character literal of type uint8
    if( m_vm == 0 )
    {
        CON( MSG_ERR, _W("Failed to create script engine!") );
        return false;
    }

    // set compiler message callback
    m_vm->SetMessageCallback(asFUNCTION(ScriptMessageCallback), 0, asCALL_CDECL);

    // write version info
    CON( MSG_INFO, _W(" AngelScript version %s successfuly initialized."), _A2W( asGetLibraryVersion() ) );
    CON( MSG_INFO, _W(" Build flags: %s"), _A2W( asGetLibraryOptions() ) );

    // register basic types
    RegisterBasicTypesToScript(m_vm);

    // Script UnitTest
    LoadScriptString(\
                     "void UnitTest()\n"\
                     "{\n"\
                     "Log(\"--- Script engine unit test ---\");\n"\

                     "\n"\
                     "Log( \"String comparison: \" + ( (\"str\"==\"str\") ? \"OK\" : \"ERROR\" ) );\n"\

                     "\n"\
                     "String float2str = 0.123f;\n"\
                     "Log(\"Float-to-String: \" + float2str);\n"\
                     "String strTrue = true; String strFalse = false;\n"\
                     "Log(\"Bool-to-String: \" + ( (strTrue == \"True\") && (strFalse == \"False\") ? \"OK\" : \"ERROR\" ) );\n"\
                     "Log(\"String index operator: \" + ( (\"str\"[2]=='r') ? \"OK\" : \"ERROR\") );\n"\
                     "Log(\"String length(): \" + ( (\"str\".length()==3) ? \"OK\" : \"ERROR\") );\n"\

                     "\n"\
                     "float f = 0.123f;\n"\
                     "float f2 = sin(f);\n"\
                     "Log(\"sin(\" + f + \") = \" + f2 );\n"\

                     "\n"\
                     "Log(\"rand(0.1f, 0.7f) = \" + rand(0.1f, 0.7f) );\n"\
                     "}\n"\
                     ,0,"UnitTestSection");

    ExecuteString("UnitTest();");

    return true;
}
Esempio n. 17
0
bool TestReturn()
{
	bool ret = false;

	asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
	engine->RegisterGlobalFunction("void assert(bool)", asFUNCTION(Assert), asCALL_GENERIC);
	engine->RegisterGlobalProperty("bool returned", &returned);
	if( strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY") )
	{
		engine->RegisterGlobalFunction("bool cfunction()", asFUNCTION(cfunction_gen), asCALL_GENERIC);
		engine->RegisterGlobalFunction("bool retfalse()", asFUNCTION(retfalse_gen), asCALL_GENERIC);
		engine->RegisterGlobalFunction("bool retfalse2()", asFUNCTION(retfalse_fake_gen), asCALL_GENERIC);
	}
	else
	{
		engine->RegisterGlobalFunction("bool cfunction()", asFUNCTION(cfunction), asCALL_CDECL);
		engine->RegisterGlobalFunction("bool retfalse()", asFUNCTION(retfalse), asCALL_CDECL);
		engine->RegisterGlobalFunction("bool retfalse2()", asFUNCTION(retfalse_fake), asCALL_CDECL);
		engine->RegisterGlobalFunction("int64 reti64()", asFUNCTION(reti64), asCALL_CDECL);
		
		engine->ExecuteString(0, "assert(reti64() == 0x102030405)");
	}

	engine->ExecuteString(0, "returned = cfunction()");
	if (!returned) 
	{
		printf("\nTestReturn: cfunction didn't return properly\n\n");
		ret = true;
	}

	engine->ExecuteString(0, "Assert(!retfalse() == cfunction())");
	engine->ExecuteString(0, "Assert(retfalse() == false)");
	engine->ExecuteString(0, "returned = retfalse()");
	if( returned )
	{
		printf("\nTestReturn: retfalse didn't return properly\n\n");
		ret = true;
	}

	engine->ExecuteString(0, "Assert(!retfalse2() == cfunction())");
	engine->ExecuteString(0, "Assert(retfalse2() == false)");
	engine->ExecuteString(0, "returned = retfalse2()");
	if( returned )
	{
		printf("\nTestReturn: retfalse2 didn't return properly\n\n");
		ret = true;
	}

	engine->Release();
	engine = NULL;

	return ret;
}
Esempio n. 18
0
bool Test()
{
	if( strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY") )
	{
		printf("%s: Skipped due to AS_MAX_PORTABILITY\n", TESTNAME);
		return false;
	}
	bool fail = false;
	int r;

 	asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
	COutStream out;
	engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL);

	RegisterStdString(engine);

	engine->RegisterGlobalFunction("void Assert(bool)", asFUNCTION(Assert), asCALL_GENERIC);

	engine->RegisterObjectType("Dict", sizeof(CDict), asOBJ_VALUE | asOBJ_APP_CLASS_CDA);	
	engine->RegisterObjectBehaviour("Dict", asBEHAVE_CONSTRUCT, "void f()", asFUNCTION(Construct), asCALL_CDECL_OBJLAST);
	engine->RegisterObjectBehaviour("Dict", asBEHAVE_DESTRUCT, "void f()", asFUNCTION(Destruct), asCALL_CDECL_OBJLAST);
	engine->RegisterObjectMethod("Dict", "Dict &opAssign(const Dict &in)", asMETHOD(CDict,operator=), asCALL_THISCALL);

	engine->RegisterObjectMethod("Dict", "Dict &opIndex(string)", asMETHOD(CDict, operator[]), 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;
		printf("%s: Failed to compile the script\n", TESTNAME);
	}

	asIScriptContext *ctx = engine->CreateContext();
	r = ExecuteString(engine, "TestDict()", 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();

	// Success
	return fail;
}
Esempio n. 19
0
bool Test()
{
	if( strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY") )
	{
		printf("%s: Skipped due to AS_MAX_PORTABILITY\n", TESTNAME);
		return false;
	}

	bool fail = false;
	int r;

	asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);

	COutStream out;
	engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL);
	RegisterScriptString(engine);

	// register the factory
	engine->RegisterObjectType( "MyFactory", 0, asOBJ_REF | asOBJ_NOHANDLE );
	engine->RegisterGlobalProperty( "MyFactory myFactory", &MyFactory::Get() );
	engine->RegisterObjectMethod( "MyFactory", "void Test(const string &in, int x, int y, uint z)", asFUNCTION(TestManager), asCALL_CDECL_OBJLAST );

	// test 1
	MyFactory::Get().Reset();
	r = ExecuteString(engine, "int x = 20; int x2 = 30; int y = 50; myFactory.Test(\"testing\", x - -x2, y, 0x000000FF);");
	if( r != asEXECUTION_FINISHED ) TEST_FAILED;
	if( MyFactory::Get().IsError() ) TEST_FAILED;

	// test 2 - without bytecode optimization
	engine->SetEngineProperty(asEP_OPTIMIZE_BYTECODE, false);
	MyFactory::Get().Reset();
	r = ExecuteString(engine, "int x = 20; int x2 = 30; int y = 50; myFactory.Test(\"testing\", x + x2, y, 0x000000FF);");
	if( r != asEXECUTION_FINISHED ) TEST_FAILED;
	if( MyFactory::Get().IsError() ) TEST_FAILED;

	// test 3 - with bytecode optimization 
	engine->SetEngineProperty(asEP_OPTIMIZE_BYTECODE, true);
	MyFactory::Get().Reset();
	r = ExecuteString(engine, "int x = 20; int x2 = 30; int y = 50; myFactory.Test(\"testing\", x + x2, y, 0x000000FF);");
	if( r != asEXECUTION_FINISHED ) TEST_FAILED;
	if( MyFactory::Get().IsError() ) TEST_FAILED;

	// release the engine
	engine->Release();

	// release the factory
	MyFactory::Release();

	return fail;
}
Esempio n. 20
0
asIScriptEngine *qasCreateEngine( bool *asMaxPortability )
{
	asIScriptEngine *engine;

	// register the global memory allocation and deallocation functions
	asSetGlobalMemoryFunctions( qasAlloc, qasFree );

	// always new

	// ask for angelscript initialization and script engine creation
	engine = asCreateScriptEngine( ANGELSCRIPT_VERSION );
	if( !engine )
		return NULL;

	if( strstr( asGetLibraryOptions(), "AS_MAX_PORTABILITY" ) )
	{
		QAS_Printf( "* angelscript library with AS_MAX_PORTABILITY detected\n" );
		engine->Release();
		return NULL;
	}

	*asMaxPortability = false;

	// The script compiler will write any compiler messages to the callback.
	engine->SetMessageCallback( asFUNCTION( qasMessageCallback ), 0, asCALL_CDECL );
	engine->SetEngineProperty( asEP_ALWAYS_IMPL_DEFAULT_CONSTRUCT, 1 );

	PreRegisterMathAddon( engine );
	PreRegisterScriptArray( engine, true );
	PreRegisterStringAddon( engine );
	PreRegisterScriptDictionary( engine );
	PreRegisterTimeAddon( engine );
	PreRegisterScriptAny( engine );
	PreRegisterVec3Addon( engine );
	PreRegisterCvarAddon( engine );
	PreRegisterStringUtilsAddon( engine );

	RegisterMathAddon( engine );
	RegisterScriptArray( engine, true );
	RegisterStringAddon( engine );
	RegisterScriptDictionary( engine );
	RegisterTimeAddon( engine );
	RegisterScriptAny( engine );
	RegisterVec3Addon( engine );
	RegisterCvarAddon( engine );
	RegisterStringUtilsAddon( engine );

	return engine;
}
bool Test()
{
	bool fail = false;

 	asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);

	engine->RegisterObjectType("CLR", sizeof(asDWORD), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_PRIMITIVE);
	if( strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY") )
		engine->RegisterObjectMethod("CLR", "CLR &opAssign(CLR &in)", asFUNCTION(Assign_gen), asCALL_GENERIC);
	else
		engine->RegisterObjectMethod("CLR", "CLR &opAssign(CLR &in)", asFUNCTION(Assign), asCALL_CDECL_OBJLAST);


	engine->RegisterGlobalProperty("CLR a", &a);
	engine->RegisterGlobalProperty("CLR b", &b);
	engine->RegisterGlobalProperty("CLR c", &c);
	engine->RegisterGlobalProperty("CLR d", &d);
	engine->RegisterGlobalProperty("CLR clr", &clr);

	a = b = c = d = 0;
	clr = 0x12345678;

	COutStream out;
	asIScriptModule *mod = engine->GetModule(0, asGM_ALWAYS_CREATE);
	mod->AddScriptSection(TESTNAME, script, strlen(script), 0);
	engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL);
	mod->Build();

	ExecuteString(engine, "Init();", mod);

	if( a != 0x12345678 || b != 0x12345678 || c != 0x12345678 || d != 0x12345678 )
	{
		TEST_FAILED;
		printf("%s: Failed to assign all objects equally\n", TESTNAME);
	}

	if( clr != 0x12345678 )
	{
		TEST_FAILED;
		printf("%s: Src object changed during operation\n", TESTNAME);
	}

	engine->Release();


	// Success
	return fail;
}
Esempio n. 22
0
        void registerScriptFunctions(asIScriptEngine *engine)
        {
            engine->SetDefaultNamespace("GUI");
            
            bool mp = strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY");
            asDWORD call_conv = mp ? asCALL_GENERIC : asCALL_CDECL;
            int r; // of type asERetCodes
            
            r = engine->RegisterGlobalFunction("void displayModalMessage(const string &in)", 
                                               mp ? WRAP_FN(displayModalMessage) : asFUNCTION(displayModalMessage), 
                                               call_conv); assert(r >= 0);
                                               
            r = engine->RegisterGlobalFunction("void displayOverlayMessage(const string &in)", 
                                               mp ? WRAP_FN(displayOverlayMessage) : asFUNCTION(displayOverlayMessage), 
                                               call_conv); assert(r >= 0);
                                               
            r = engine->RegisterGlobalFunction("void clearOverlayMessages()", 
                                               mp ? WRAP_FN(clearOverlayMessages) : asFUNCTION(clearOverlayMessages), 
                                               call_conv); assert(r >= 0);
                                               
            r = engine->RegisterGlobalFunction("string getKeyBinding(int input)", 
                                               mp ? WRAP_FN(getKeyBinding) : asFUNCTION(getKeyBinding), 
                                               call_conv); assert(r >= 0);
                                               
            r = engine->RegisterGlobalFunction("string translate(const string &in)", 
                                               mp ? WRAP_FN(proxy_translate) : asFUNCTION(proxy_translate), 
                                               call_conv); assert(r >= 0);
                                               
            r = engine->RegisterGlobalFunction("string translate(const string &in, const string &in)", 
                                               mp ? WRAP_FN(proxy_translateAndInsertValues1) 
                                                  : asFUNCTION(proxy_translateAndInsertValues1), 
                                               call_conv); assert(r >= 0);
                                               
            r = engine->RegisterGlobalFunction("string translate(const string &in, const string &in, const string &in)", 
                                               mp ? WRAP_FN(proxy_translateAndInsertValues2) 
                                                  : asFUNCTION(proxy_translateAndInsertValues2), 
                                               call_conv); assert(r >= 0);
                                               
            r = engine->RegisterGlobalFunction("string translate(const string &in, const string &in, const string &in, const string &in)", 
                                               mp ? WRAP_FN(proxy_translateAndInsertValues3) 
                                                  : asFUNCTION(proxy_translateAndInsertValues3), 
                                               call_conv); assert(r >= 0);

        }
Esempio n. 23
0
bool Test()
{
	if( !strstr(asGetLibraryOptions(), "AS_ALLOW_UNSAFE_REFERENCES") )
	{
		printf("%s: This test is only valid with AS_ALLOW_UNSAFE_REFERENCES\n", TESTNAME);
		return false;
	}

	bool fail = false;
	int r;

	COutStream out;

 	asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
	engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL);

	RegisterScriptString(engine);

	r = engine->RegisterGlobalFunction("void Assert(bool)", asFUNCTION(Assert), asCALL_GENERIC); assert( r >= 0 );

	engine->AddScriptSection(0, TESTNAME, script1, strlen(script1), 0);
	r = engine->Build(0);
	if( r < 0 )
	{
		fail = true;
		printf("%s: Failed to compile the script\n", TESTNAME);
	}
	asIScriptContext *ctx = 0;
	r = engine->ExecuteString(0, "Test()", &ctx);
	if( r != asEXECUTION_FINISHED )
	{
		fail = true;
		printf("%s: Execution failed: %d\n", TESTNAME, r);
	}

	if( ctx ) ctx->Release();


	engine->Release();

	// Success
	return fail;
}
Esempio n. 24
0
bool TestReturnStruct()
{
	if( strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY") )
	{
		// Skipping this test for max portability
		return false;
	}

	bool fail = false;
	int r;

    asIScriptEngine *engine=asCreateScriptEngine(ANGELSCRIPT_VERSION);
    r = engine->RegisterObjectType("point", sizeof(asPoint), asOBJ_VALUE|asOBJ_POD|asOBJ_APP_CLASS|asOBJ_APP_CLASS_ALLFLOATS); assert( r >= 0 );
    r = engine->RegisterObjectType("rect", sizeof(asRect), asOBJ_VALUE|asOBJ_POD|asOBJ_APP_CLASS|asOBJ_APP_CLASS_ALLFLOATS); assert( r >= 0 );
    r = engine->RegisterGlobalFunction("point Point()",asFUNCTION(TestPoint),asCALL_CDECL); assert( r >= 0 );
    r = engine->RegisterGlobalFunction("rect Rect()",asFUNCTION(TestRect),asCALL_CDECL); assert( r >= 0 );
    asPoint p={0,0};
    asRect rc={{0,0},{0,0}};
    r = engine->RegisterGlobalProperty("point p",&p); assert( r >= 0 );
    r = engine->RegisterGlobalProperty("rect r",&rc); assert( r >= 0 );
    r = ExecuteString(engine,"p=Point();");
	if( r != asEXECUTION_FINISHED )
		TEST_FAILED;
	if( p.x != 1 || p.y != 2 )
		TEST_FAILED;
    r = ExecuteString(engine,"r=Rect();");
	if( r != asEXECUTION_FINISHED )
		TEST_FAILED;
	if( rc.tl.x != 3 || rc.tl.y != 4 || rc.br.x != 5 || rc.br.y != 6 )
	{
		TEST_FAILED;
		printf("Got {%f, %f, %f, %f}\n", rc.tl.x, rc.tl.y, rc.br.x, rc.br.y);
	}
    
    // at that point, 'p' should contain 1,2 while 'rc' should contain 3,4,5,6
    
    engine->Release();

	return fail;
}
Esempio n. 25
0
bool Test2()
{
	if( strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY") )
		return false;

	bool fail = false;
	COutStream out;
	int r;

	asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
	engine->SetMessageCallback(asMETHOD(COutStream, Callback), &out, asCALL_THISCALL);

	RegisterScriptString(engine);
	engine->RegisterGlobalFunction("void assert(bool)", asFUNCTION(Assert), asCALL_GENERIC);

	engine->RegisterGlobalFunction("void debugCall()", asFUNCTION(DebugCall), asCALL_CDECL);

	asIScriptModule *mod = engine->GetModule(0, asGM_ALWAYS_CREATE);

	const char *script = 
		"void func(string@ &out output) \n"
		"{ \n"
		"  debugCall(); \n"
		"  assert( output == 'test' ); \n"
		"} \n";

	mod->AddScriptSection("script", script);
	r = mod->Build();
	if( r < 0 )
		TEST_FAILED;

	r = ExecuteString(engine, "string @o; func(o); assert( o == 'test' );", mod);
	if( r != asEXECUTION_FINISHED )
		TEST_FAILED;

	engine->Release();

	return fail;
}
Esempio n. 26
0
bool TestReturn()
{
	bool ret = false;

	asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
	engine->RegisterGlobalProperty("bool returned", &returned);
	if( strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY") )
		engine->RegisterGlobalFunction("bool cfunction()", asFUNCTION(cfunction_gen), asCALL_GENERIC);
	else
		engine->RegisterGlobalFunction("bool cfunction()", asFUNCTION(cfunction), asCALL_CDECL);

	engine->ExecuteString(0, "returned = cfunction()");

	if (!returned) {
		printf("\nTestReturn: cfunction didn't return properly\n\n");
		ret = true;
	}

	engine->Release();
	engine = NULL;

	return ret;
}
Esempio n. 27
0
bool TestReturnD()
{
	bool ret = false;

 	asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
	engine->RegisterGlobalProperty("double returnValue", &returnValue);
	if( strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY") )
		engine->RegisterGlobalFunction("double cfunction()", asFUNCTION(cfunction_gen), asCALL_GENERIC);
	else
		engine->RegisterGlobalFunction("double cfunction()", asFUNCTION(cfunction), asCALL_CDECL);

	engine->ExecuteString(0, "returnValue = cfunction()");

	if( returnValue != 88.32 ) 
	{
		printf("\n%s: cfunction didn't return properly. Expected %f, got %f\n\n", TESTNAME, 88.32, returnValue);
		ret = true;
	}

	engine->Release();
	
	// Success
	return ret;
}
Esempio n. 28
0
bool Test()
{
	if( strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY") )
	{
		printf("Skipped due to AS_MAX_PORTABILITY\n");
		return false;
	}

	bool fail = false;
	int r;
	CBufferedOutStream bout;
	COutStream out;
	asIScriptModule *mod;
 	asIScriptEngine *engine;
	

	engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
	engine->SetMessageCallback(asMETHOD(CBufferedOutStream,Callback), &bout, asCALL_THISCALL);
	RegisterScriptArray(engine, true);
	RegisterScriptString(engine);
	engine->RegisterGlobalFunction("void assert(bool)", asFUNCTION(Assert), asCALL_GENERIC);

	mod = engine->GetModule(0, asGM_ALWAYS_CREATE);

	// The getter can return a handle while the setter takes a reference
	{
		const char *script = 
			"class Test \n"
			"{ \n"
			"  string @get_s() { return 'test'; } \n"
			"  void set_s(const string &in) {} \n"
			"} \n"
			"void func() \n"
			"{ \n"
			"  Test t; \n"
			"  string s = t.s; \n" 
			"  t.s = s; \n"
			"} \n";

		mod->AddScriptSection("script", script);
		bout.buffer = "";
		r = mod->Build();
		if( r < 0 )
		{
			TEST_FAILED;
			printf("Failed to compile the script\n");
		}

		r = ExecuteString(engine, "Test t; @t.s = 'test';", mod);
		if( r >= 0 )
		{
			TEST_FAILED;
			printf("Shouldn't be allowed\n");
		}
		if( bout.buffer != "ExecuteString (1, 14) : Error   : It is not allowed to perform a handle assignment on a non-handle property\n" )
		{
			printf("%s", bout.buffer.c_str());
			TEST_FAILED;
		}
	}

	// main1 and main2 should produce the same bytecode
	const char *script1 = 
		"class Test                            \n"
		"{                                     \n"
		"  int get_prop() { return _prop; }    \n"
		"  void set_prop(int v) { _prop = v; } \n"
        "  int _prop;                          \n"
		"}                                     \n"
		"void main1()                          \n"
		"{                                     \n"
		"  Test t;                             \n"
		"  t.set_prop(42);                     \n"
		"  assert( t.get_prop() == 42 );       \n"
		"}                                     \n"
		"void main2()                          \n"
		"{                                     \n"
		"  Test t;                             \n"
		"  t.prop = 42;                        \n"
		"  assert( t.prop == 42 );             \n"
		"}                                     \n";
		
	mod->AddScriptSection("script", script1);
	bout.buffer = "";
	r = mod->Build();
	if( r < 0 )
	{
		TEST_FAILED;
		printf("Failed to compile the script\n");
	}
	if( bout.buffer != "" )
	{
		printf("%s", bout.buffer.c_str());
		TEST_FAILED;
	}

	r = ExecuteString(engine, "main1()", mod);
	if( r != asEXECUTION_FINISHED )
	{
		TEST_FAILED;
	}

	r = ExecuteString(engine, "main2()", mod);
	if( r != asEXECUTION_FINISHED )
	{
		TEST_FAILED;
	}

	// Test compound assignment with accessors (not allowed)
	const char *script2 = 
		"class Test                            \n"
		"{                                     \n"
		"  void set_prop(int v) { _prop = v; } \n"
        "  int _prop;                          \n"
		"}                                     \n"
		"void main1()                          \n"
		"{                                     \n"
		"  Test t;                             \n"
		"  t.prop += 42;                       \n"
		"}                                     \n";

	mod->AddScriptSection("script", script2);
	bout.buffer = "";
	r = mod->Build();
	if( r >= 0 )
	{
		TEST_FAILED;
	}
	if( bout.buffer != "script (6, 1) : Info    : Compiling void main1()\n"
	                   "script (9, 10) : Error   : Compound assignments with property accessors are not allowed\n" )
	{
		printf("%s", bout.buffer.c_str());
		TEST_FAILED;
	}

	// Test get accessor with boolean operators
	const char *script3 = 
		"class Test                              \n"
		"{                                       \n"
		"  bool get_boolProp() { return true; }  \n"
		"}                                       \n"
		"void main1()                            \n"
		"{                                       \n"
		"  Test t;                               \n"
		"  if( t.boolProp ) {}                   \n"
		"  if( t.boolProp && true ) {}           \n"
		"  if( false || t.boolProp ) {}          \n"
		"  if( t.boolProp ^^ t.boolProp ) {}     \n"
		"  if( !t.boolProp ) {}                  \n"
		"  t.boolProp ? t.boolProp : t.boolProp; \n"
		"}                                       \n";

	mod->AddScriptSection("script", script3);
	bout.buffer = "";
	r = mod->Build();
	if( r < 0 )
	{
		TEST_FAILED;
		printf("Failed to compile the script\n");
	}
	if( bout.buffer != "" )
	{
		printf("%s", bout.buffer.c_str());
		TEST_FAILED;
	}

	// Test get accessor with math operators
	const char *script4 = 
		"class Test                              \n"
		"{                                       \n"
		"  float get_prop() { return 1.0f; }     \n"
		"}                                       \n"
		"void main1()                            \n"
		"{                                       \n"
		"  Test t;                               \n"
		"  float f = t.prop * 1;                 \n"
		"  f = (t.prop) + 1;                     \n"
		"  10 / t.prop;                          \n"
		"  -t.prop;                              \n"
		"}                                       \n";

	mod->AddScriptSection("script", script4);
	bout.buffer = "";
	r = mod->Build();
	if( r < 0 )
	{
		TEST_FAILED;
		printf("Failed to compile the script\n");
	}
	if( bout.buffer != "" )
	{
		printf("%s", bout.buffer.c_str());
		TEST_FAILED;
	}

	// Test get accessor with bitwise operators
	const char *script5 = 
		"class Test                              \n"
		"{                                       \n"
		"  uint get_prop() { return 1; }         \n"
		"}                                       \n"
		"void main1()                            \n"
		"{                                       \n"
		"  Test t;                               \n"
		"  t.prop << t.prop;                     \n"
		"  t.prop & t.prop;                      \n"
		"  ~t.prop;                              \n"
		"}                                       \n";

	mod->AddScriptSection("script", script5);
	bout.buffer = "";
	r = mod->Build();
	if( r < 0 )
	{
		TEST_FAILED;
		printf("Failed to compile the script\n");
	}
	if( bout.buffer != "" )
	{
		printf("%s", bout.buffer.c_str());
		TEST_FAILED;
	}

	// Test multiple get accessors for same property. Should give error
	// Test multiple set accessors for same property. Should give error
	const char *script6 = 
		"class Test                  \n"
		"{                           \n"
		"  uint get_p() {return 0;}  \n"
		"  float get_p() {return 0;} \n"
		"  void set_s(float) {}      \n"
		"  void set_s(uint) {}       \n"
		"}                           \n"
		"void main()                 \n"
		"{                           \n"
		"  Test t;                   \n"
		"  t.p;                      \n"
		"  t.s = 0;                  \n"
		"}                           \n";
	mod->AddScriptSection("script", script6);
	bout.buffer = "";
	r = mod->Build();
	if( r >= 0 )
	{
		TEST_FAILED;
		printf("Failed to compile the script\n");
	}
	if( bout.buffer != "script (8, 1) : Info    : Compiling void main()\n"
	                   "script (11, 4) : Error   : Found multiple get accessors for property 'p'\n"
	                   "script (11, 4) : Info    : uint Test::get_p()\n"
	                   "script (11, 4) : Info    : float Test::get_p()\n"
	                   "script (12, 4) : Error   : Found multiple set accessors for property 's'\n"
	                   "script (12, 4) : Info    : void Test::set_s(float)\n"
	                   "script (12, 4) : Info    : void Test::set_s(uint)\n" )
	{
		printf("%s", bout.buffer.c_str());
		TEST_FAILED;
	}

	// Test mismatching type between get accessor and set accessor. Should give error
	const char *script7 = 
		"class Test                  \n"
		"{                           \n"
		"  uint get_p() {return 0;}  \n"
		"  void set_p(float) {}      \n"
		"}                           \n"
		"void main()                 \n"
		"{                           \n"
		"  Test t;                   \n"
		"  t.p;                      \n"
		"}                           \n";
	mod->AddScriptSection("script", script7);
	bout.buffer = "";
	r = mod->Build();
	if( r >= 0 )
	{
		TEST_FAILED;
		printf("Failed to compile the script\n");
	}
	if( bout.buffer != "script (6, 1) : Info    : Compiling void main()\n"
                       "script (9, 4) : Error   : The property 'p' has mismatching types for the get and set accessors\n"
                       "script (9, 4) : Info    : uint Test::get_p()\n"
                       "script (9, 4) : Info    : void Test::set_p(float)\n" )
	{
		printf("%s", bout.buffer.c_str());
		TEST_FAILED;
	}

	// Test only set accessor for read expression
	// Test only get accessor for write expression
	const char *script8 = 
		"class Test                  \n"
		"{                           \n"
		"  uint get_g() {return 0;}  \n"
		"  void set_s(float) {}      \n"
		"}                           \n"
		"void main()                 \n"
		"{                           \n"
		"  Test t;                   \n"
		"  t.g = 0;                  \n"
        "  t.s + 1;                  \n"
		"}                           \n";
	mod->AddScriptSection("script", script8);
	bout.buffer = "";
	r = mod->Build();
	if( r >= 0 )
	{
		TEST_FAILED;
		printf("Failed to compile the script\n");
	}
	if( bout.buffer != "script (6, 1) : Info    : Compiling void main()\n"
					   "script (9, 7) : Error   : The property has no set accessor\n"
					   "script (10, 7) : Error   : The property has no get accessor\n" )
	{
		printf("%s", bout.buffer.c_str());
		TEST_FAILED;
	}

	// Test pre and post ++. Should fail, since the expression is not a variable
	const char *script9 = 
		"class Test                  \n"
		"{                           \n"
		"  uint get_p() {return 0;}  \n"
		"  void set_p(uint) {}       \n"
		"}                           \n"
		"void main()                 \n"
		"{                           \n"
		"  Test t;                   \n"
		"  t.p++;                    \n"
        "  --t.p;                    \n"
		"}                           \n";
	mod->AddScriptSection("script", script9);
	bout.buffer = "";
	r = mod->Build();
	if( r >= 0 )
	{
		TEST_FAILED;
		printf("Didn't fail to compile the script\n");
	}
	if( bout.buffer != "script (6, 1) : Info    : Compiling void main()\n"
					   "script (9, 6) : Error   : Invalid reference. Property accessors cannot be used in combined read/write operations\n"
				 	   "script (10, 3) : Error   : Invalid reference. Property accessors cannot be used in combined read/write operations\n" )
	{
		printf("%s", bout.buffer.c_str());
		TEST_FAILED;
	}

	// Test using property accessors from within class methods without 'this'
	// Test accessor where the object is a handle
	const char *script10 = 
		"class Test                 \n"
		"{                          \n"
		"  uint get_p() {return 0;} \n"
		"  void set_p(uint) {}      \n"
		"  void test()              \n"
		"  {                        \n"
		"    p = 0;                 \n"
		"    int a = p;             \n"
		"  }                        \n"
		"}                          \n"
		"void func()                \n"
		"{                          \n"
		"  Test @a = Test();        \n"
		"  a.p = 1;                 \n"
		"  int b = a.p;             \n"
		"}                          \n";
	mod->AddScriptSection("script", script10);
	bout.buffer = "";
	r = mod->Build();
	if( r < 0 )
	{
		TEST_FAILED;
		printf("Failed to compile the script\n");
	}
	if( bout.buffer != "" )
	{
		printf("%s", bout.buffer.c_str());
		TEST_FAILED;
	}
	r = ExecuteString(engine, "func()", mod);
	if( r != asEXECUTION_FINISHED )
	{
		TEST_FAILED;
	}

	// Test accessors with function arguments (by value, in ref, out ref)
	const char *script11 = 
		"class Test                 \n"
		"{                          \n"
		"  uint get_p() {return 0;} \n"
		"  void set_p(uint) {}      \n"
		"}                          \n"
		"void func()                \n"
		"{                          \n"
		"  Test a();                \n"
		"  byVal(a.p);              \n"
		"  inArg(a.p);              \n"
		"  outArg(a.p);             \n"
		"}                          \n"
		"void byVal(int v) {}       \n"
		"void inArg(int &in v) {}   \n"
		"void outArg(int &out v) {} \n";
	mod->AddScriptSection("script", script11);
	bout.buffer = "";
	r = mod->Build();
	if( r < 0 )
	{
		TEST_FAILED;
		printf("Failed to compile the script\n");
	}
	if( bout.buffer != "" )
	{
		printf("%s", bout.buffer.c_str());
		TEST_FAILED;
	}
	r = ExecuteString(engine, "func()", mod);
	if( r != asEXECUTION_FINISHED )
	{
		TEST_FAILED;
	}

	// When the property is an object type, then the set accessor should be 
	// used instead of the overloaded assignment operator to set the value. 
	// Properties of object properties, must allow having different 
	// types for get and set. IsEqualExceptConstAndRef should be used.
	const char *script12 = 
		"class Test                                   \n"
		"{                                            \n"
		"  string get_s() {return _s;}                \n"
		"  void set_s(const string &in n) {_s = n;}   \n"
		"  string _s;                                 \n"
		"}                                            \n"
		"void func()                \n"
		"{                          \n"
		"  Test t;                  \n"
		"  t.s = 'hello';           \n"
		"  assert(t.s == 'hello');  \n"
		"}                          \n";
	mod->AddScriptSection("script", script12);
	bout.buffer = "";
	r = mod->Build();
	if( r < 0 )
	{
		TEST_FAILED;
		printf("Failed to compile the script\n");
	}
	if( bout.buffer != "" )
	{
		printf("%s", bout.buffer.c_str());
		TEST_FAILED;
	}
	r = ExecuteString(engine, "func()", mod);
	if( r != asEXECUTION_FINISHED )
	{
		TEST_FAILED;
	}

	// Compound assignments for object properties will not be allowed
	r = ExecuteString(engine, "Test t; t.s += 'hello';", mod);
	if( r >= 0 )
	{
		TEST_FAILED;
	}
	if( bout.buffer != "ExecuteString (1, 13) : Error   : Compound assignments with property accessors are not allowed\n" )
	{
		printf("%s", bout.buffer.c_str());
		TEST_FAILED;
	}
	
	// Test @t.prop = @obj; Property is a handle, and the property is assigned a new handle. Should work
	const char *script13 = 
		"class Test                                   \n"
		"{                                            \n"
		"  string@ get_s() {return _s;}               \n"
		"  void set_s(string @n) {@_s = @n;}          \n"
		"  string@ _s;                                \n"
		"}                          \n"
		"void func()                \n"
		"{                          \n"
		"  Test t;                  \n"
		"  string s = 'hello';      \n"
		"  @t.s = @s;               \n" // handle assignment
		"  assert(t.s is s);        \n"
		"  t.s = 'other';           \n" // value assignment
		"  assert(s == 'other');    \n"
		"}                          \n";
	mod->AddScriptSection("script", script13);
	bout.buffer = "";
	r = mod->Build();
	if( r < 0 )
	{
		TEST_FAILED;
		printf("Failed to compile the script\n");
	}
	if( bout.buffer != "" )
	{
		printf("%s", bout.buffer.c_str());
		TEST_FAILED;
	}
	r = ExecuteString(engine, "func()", mod);
	if( r != asEXECUTION_FINISHED )
	{
		TEST_FAILED;
	}

	// Test accessing members of an object property
	const char *script14 = 
		"class Test                                   \n"
		"{                                            \n"
		"  string get_s() {return _s;}                \n"
		"  void set_s(string n) {_s = n;}             \n"
		"  string _s;                                 \n"
		"}                            \n"
		"void func()                  \n"
		"{                            \n"
		"  Test t;                    \n"
		"  t.s = 'hello';             \n" // value assignment
		"  assert(t.s == 'hello');    \n"
		"  assert(t.s.length() == 5); \n" // this should work as length is const
		"}                            \n";
	mod->AddScriptSection("script", script14);
	bout.buffer = "";
	r = mod->Build();
	if( r < 0 )
	{
		TEST_FAILED;
		printf("Failed to compile the script\n");
	}
	if( bout.buffer != "" )
	{
		printf("%s", bout.buffer.c_str());
		TEST_FAILED;
	}
	r = ExecuteString(engine, "func()", mod);
	if( r != asEXECUTION_FINISHED )
	{
		TEST_FAILED;
	}

	// Test accessing a non-const method on an object through a get accessor
	// Should at least warn since the object is just a temporary one
/*
	// This warning isn't done anymore as there are times when it is valid to call a non-const method on temporary objects, for example if a stream like object is implemented
	bout.buffer = "";
	r = ExecuteString(engine, "Test t; t.s.resize(4);", mod);
	if( r < 0 )
		TEST_FAILED;
	if( (sizeof(void*) == 4 &&
		 bout.buffer != "ExecuteString (1, 13) : Warning : A non-const method is called on temporary object. Changes to the object may be lost.\n"
		                "ExecuteString (1, 13) : Info    : void string::resize(uint)\n") ||
		(sizeof(void*) == 8 &&
		 bout.buffer != "ExecuteString (1, 13) : Warning : A non-const method is called on temporary object. Changes to the object may be lost.\n"
		                "ExecuteString (1, 13) : Info    : void string::resize(uint64)\n") )
	{
		printf("%s", bout.buffer.c_str());
		TEST_FAILED;
	}
*/

	// Test opNeg for object through get accessor
	const char *script15 = 
		"class Val { int opNeg() const { return -1; } } \n"
		"class Test                          \n"
		"{                                   \n"
		"  Val get_s() const {return Val();} \n"
		"}                                   \n"
		"void func()                  \n"
		"{                            \n"
		"  Test t;                    \n"
		"  assert( -t.s == -1 );      \n"
		"}                            \n";
	mod->AddScriptSection("script", script15);
	bout.buffer = "";
	r = mod->Build();
	if( r < 0 )
	{
		TEST_FAILED;
		printf("Failed to compile the script\n");
	}
	if( bout.buffer != "" )
	{
		printf("%s", bout.buffer.c_str());
		TEST_FAILED;
	}
	r = ExecuteString(engine, "func()", mod);
	if( r != asEXECUTION_FINISHED )
	{
		TEST_FAILED;
	}	

	// Test index operator for object through get accessor
	const char *script16 = 
		"class Test                          \n"
		"{                                   \n"
		"  int[] get_s() const { int[] a(1); a[0] = 42; return a; } \n"
		"}                                   \n"
		"void func()                  \n"
		"{                            \n"
		"  Test t;                    \n"
		"  assert( t.s[0] == 42 );    \n"
		"}                            \n";
	mod->AddScriptSection("script", script16);
	bout.buffer = "";
	r = mod->Build();
	if( r < 0 )
	{
		TEST_FAILED;
		printf("Failed to compile the script\n");
	}
	if( bout.buffer != "" )
	{
		printf("%s", bout.buffer.c_str());
		TEST_FAILED;
	}
	r = ExecuteString(engine, "func()", mod);
	if( r != asEXECUTION_FINISHED )
	{
		TEST_FAILED;
	}	

	// Test accessing normal properties for object through get accessor
	const char *script17 = 
		"class Val { int val; } \n"
		"class Test                          \n"
		"{                                   \n"
		"  Val get_s() const { Val v; v.val = 42; return v;} \n"
		"}                                   \n"
		"void func()                  \n"
		"{                            \n"
		"  Test t;                    \n"
		"  assert( t.s.val == 42 );   \n"
		"}                            \n";
	mod->AddScriptSection("script", script17);
	bout.buffer = "";
	r = mod->Build();
	if( r < 0 )
	{
		TEST_FAILED;
		printf("Failed to compile the script\n");
	}
	if( bout.buffer != "" )
	{
		printf("%s", bout.buffer.c_str());
		TEST_FAILED;
	}
	r = ExecuteString(engine, "func()", mod);
	if( r != asEXECUTION_FINISHED )
	{
		TEST_FAILED;
	}	

	// Test const/non-const get and set accessors
	const char *script18 = 
		"class Test                          \n"
		"{                                   \n"
		"  int get_p() { return 42; }        \n"
		"  int get_c() const { return 42; }  \n"
		"  void set_s(int) {}                \n"
		"}                                   \n"
		"void func()                  \n"
		"{                            \n"
		"  const Test @t = @Test();   \n"
		"  assert( t.p == 42 );       \n" // Fail
		"  assert( t.c == 42 );       \n" // Success
		"  t.s = 42;                  \n" // Fail
		"}                            \n";
	mod->AddScriptSection("script", script18);
	bout.buffer = "";
	r = mod->Build();
	if( r >= 0 )
		TEST_FAILED;
	if( bout.buffer != "script (7, 1) : Info    : Compiling void func()\n"
	                   "script (10, 15) : Error   : Non-const method call on read-only object reference\n"
	                   "script (10, 15) : Info    : int Test::get_p()\n"
					   "script (12, 7) : Error   : Non-const method call on read-only object reference\n"
	                   "script (12, 7) : Info    : void Test::set_s(int)\n" )
	{
		printf("%s", bout.buffer.c_str());
		TEST_FAILED;
	}

	// Test accessor with property of the same name
	const char *script19 = 
		"int direction; \n"
		"void set_direction(int val) { direction = val; } \n"
		"void test_set() \n"
		"{ \n"
		"  direction = 9; \n" // calls the set_direction property accessor
		"} \n"
		"void test_get() \n"
		"{ \n"
		"  assert( direction == 9 ); \n" // fails, since there is no get accessor
		"} \n";
	mod->AddScriptSection("script", script19);
	bout.buffer = "";
	r = mod->Build();
	if( r >= 0 )
		TEST_FAILED;
	if( bout.buffer != "script (7, 1) : Info    : Compiling void test_get()\n"
	                   "script (9, 21) : Error   : The property has no get accessor\n" )
	{
		printf("%s", bout.buffer.c_str());
		TEST_FAILED;
	}

	const char *script20 = 
		"class Test { \n"
		"  int direction; \n"
		"  void set_direction(int val) { direction = val; } \n"
		"} \n";
	mod->AddScriptSection("script", script20);
	bout.buffer = "";
	r = mod->Build();
	if( r < 0 )
		TEST_FAILED;
	if( bout.buffer != "" )
	{
		printf("%s", bout.buffer.c_str());
		TEST_FAILED;
	}
	r = ExecuteString(engine, "Test t; t.set_direction(3);", mod);
	if( r != asEXECUTION_FINISHED )
		TEST_FAILED;
	
	// Test accessing property of the same name on a member object
	const char *script21 =
		"class Test { \n"
		" int a; \n"
		" Test @member; \n"
		" int get_a() const { return a; } \n"
		" void set_a(int val) {a = val; if( member !is null ) member.a = val;} \n"
		"} \n";
	mod->AddScriptSection("script", script21);
	bout.buffer = "";
	r = mod->Build();
	if( r < 0 )
		TEST_FAILED;
	r = ExecuteString(engine, "Test t, s, u; @t.member = s; @s.member = u; t.set_a(3); assert( u.a == 3 );", mod);
	if( r != asEXECUTION_FINISHED )
		TEST_FAILED;
	if( bout.buffer != "" )
	{
		printf("%s", bout.buffer.c_str());
		TEST_FAILED;
	}


	// TODO: Test non-const get accessor for object type with const overloaded dual operator
	
	// TODO: Test get accessor that returns a reference (only from application func to start with)
		
	// TODO: Test property accessor with inout references. Shouldn't be allowed as the value is not a valid reference

	// TODO: Test set accessor with parameter declared as out ref (shouldn't be found)

	// TODO: What should be done with expressions like t.prop; Should the get accessor be called even though 
	//       the value is never used?

	// TODO: Accessing a class member from within the property accessor with the same name as the property 
	//       shouldn't call the accessor again. Instead it should access the real member. FindPropertyAccessor() 
	//       shouldn't find any if the function being compiler is the property accessor itself

	engine->Release();

	// Test property accessor on temporary object handle
	{
		engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
		engine->SetMessageCallback(asMETHOD(COutStream, Callback), &out, asCALL_THISCALL);
		RegisterStdString(engine);

		const char *script = "class Obj { void set_opacity(float v) {} }\n"
			                 "Obj @GetObject() { return @Obj(); } \n";

		asIScriptModule *mod = engine->GetModule(0, asGM_ALWAYS_CREATE);
		mod->AddScriptSection("script", script);
		r = mod->Build();
		if( r < 0 )
			TEST_FAILED;

		r = ExecuteString(engine, "GetObject().opacity = 1.0f;", mod);
		if( r != asEXECUTION_FINISHED )
			TEST_FAILED;

		engine->Release();
	}

	// Test bug reported by Scarabus2
	// The bug was an incorrect reusage of temporary variable by the  
	// property get accessor when compiling a binary operator
	{
		engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
		engine->SetMessageCallback(asMETHOD(COutStream, Callback), &out, asCALL_THISCALL);
		engine->RegisterGlobalFunction("void assert(bool)", asFUNCTION(Assert), asCALL_GENERIC);

		const char *script = 
			"class Object { \n"
			"  Object() {rot = 0;} \n"
			"  void set_rotation(float r) {rot = r;} \n"
			"  float get_rotation() const {return rot;} \n"
			"  float rot; } \n";

		asIScriptModule *mod = engine->GetModule(0, asGM_ALWAYS_CREATE);
		mod->AddScriptSection("script", script);
		r = mod->Build();
		if( r < 0 )
			TEST_FAILED;

		r = ExecuteString(engine, "Object obj; \n"
								  "float elapsed = 1.0f; \n"
								  "float temp = obj.rotation + elapsed * 1.0f; \n"
								  "obj.rotation = obj.rotation + elapsed * 1.0f; \n"
								  "assert( obj.rot == 1 ); \n", mod);
		if( r != asEXECUTION_FINISHED )
			TEST_FAILED;

		engine->Release();
	}

	// Test global property accessor
	{
		engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
		engine->SetMessageCallback(asMETHOD(COutStream, Callback), &out, asCALL_THISCALL);
		engine->RegisterGlobalFunction("void assert(bool)", asFUNCTION(Assert), asCALL_GENERIC);

		const char *script = 
			"int _s = 0;  \n"
			"int get_s() { return _s; } \n"
			"void set_s(int v) { _s = v; } \n";

		asIScriptModule *mod = engine->GetModule(0, asGM_ALWAYS_CREATE);
		mod->AddScriptSection("script", script);
		r = mod->Build();
		if( r < 0 )
			TEST_FAILED;

		r = ExecuteString(engine, "s = 10; assert( s == 10 );", mod);
		if( r != asEXECUTION_FINISHED )
			TEST_FAILED;

		engine->Release();

		// The global property accessors are available to initialize global 
		// variables, but can possibly throw an exception if used inappropriately.
		// This test also verifies that circular references between global 
		// properties and functions is properly resolved by the GC.
		engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
		engine->SetMessageCallback(asMETHOD(CBufferedOutStream, Callback), &bout, asCALL_THISCALL);
		RegisterStdString(engine);

		bout.buffer = "";

		script =
			"string _s = s; \n"
			"string get_s() { return _s; } \n";

		mod = engine->GetModule(0, asGM_ALWAYS_CREATE);
		mod->AddScriptSection("script", script);
		r = mod->Build();
		if( r != asINIT_GLOBAL_VARS_FAILED )
			TEST_FAILED;

		if( bout.buffer != "script (1, 13) : Error   : Failed to initialize global variable '_s'\n"
		                   "script (2, 0) : Info    : Exception 'Null pointer access' in 'string get_s()'\n" )
		{
			printf("%s", bout.buffer.c_str());
			TEST_FAILED;
		}

		engine->Release();
	}

	// Test property accessor for object in array
	{
		engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
		engine->SetMessageCallback(asMETHOD(COutStream, Callback), &out, asCALL_THISCALL);
		RegisterScriptArray(engine, true);
		engine->RegisterGlobalFunction("void assert(bool)", asFUNCTION(Assert), asCALL_GENERIC);

		const char *script = 
			"class MyObj { bool get_Active() { return true; } } \n";
			
		asIScriptModule *mod = engine->GetModule(0, asGM_ALWAYS_CREATE);
		mod->AddScriptSection("script", script);
		r = mod->Build();
		if( r < 0 )
			TEST_FAILED;

		r = ExecuteString(engine, "MyObj[] a(1); if( a[0].Active == true ) { } if( a[0].get_Active() == true ) { }", mod);
		if( r != asEXECUTION_FINISHED )
			TEST_FAILED;

		engine->Release();
	}

	// Test property accessor from within class method
	{
		engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
		engine->SetMessageCallback(asMETHOD(COutStream, Callback), &out, asCALL_THISCALL);

		const char *script = 
			"class Vector3 \n"
			"{ \n"
			"  float x; \n"
			"  float y; \n"
			"  float z; \n"
			"}; \n"
			"class Hoge \n"
			"{ \n"
			"    const Vector3 get_pos() { return mPos; } \n"
			"    const Vector3 foo() { return pos;  } \n"
			"    const Vector3 zoo() { return get_pos(); } \n"
			"    Vector3 mPos; \n"
			"}; \n"
			"void main() \n"
			"{ \n"
			"    Hoge h; \n"
			"    Vector3 vec; \n"
			"    vec = h.zoo(); \n" // ok
			"    vec = h.foo(); \n" // runtime exception
			"} \n";
			
		asIScriptModule *mod = engine->GetModule(0, asGM_ALWAYS_CREATE);
		mod->AddScriptSection("script", script);
		r = mod->Build();
		if( r < 0 )
			TEST_FAILED;

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

		engine->Release();
	}

	// Test property accessor in type conversion 
	{
		engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
		engine->SetMessageCallback(asMETHOD(COutStream, Callback), &out, asCALL_THISCALL);
		RegisterScriptArray(engine, true);

		const char *script = 
			"class sound \n"
			"{ \n"
			"  int get_pitch() { return 1; } \n"
			"  void set_pitch(int p) {} \n"
			"} \n"
			"void main() \n"
			"{ \n"
			"  sound[] sounds(1) ; \n"
			"  sounds[0].pitch = int(sounds[0].pitch)/2; \n"
			"} \n";


		asIScriptModule *mod = engine->GetModule(0, asGM_ALWAYS_CREATE);
		mod->AddScriptSection("script", script);
		r = mod->Build();
		if( r < 0 )
			TEST_FAILED;

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

		engine->Release();
	}

	// Test property accessor in type conversion (2)
	{
		engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
		engine->SetMessageCallback(asMETHOD(COutStream, Callback), &out, asCALL_THISCALL);

		const char *script = 
			"class sound \n"
			"{ \n"
			"  const int &get_id() const { return i; } \n"
			"  int i; \n"
			"} \n"
			"void main() \n"
			"{ \n"
			"  sound s; \n"
			"  if( s.id == 1 ) \n"
			"    return; \n"
			"} \n";


		asIScriptModule *mod = engine->GetModule(0, asGM_ALWAYS_CREATE);
		mod->AddScriptSection("script", script);
		r = mod->Build();
		if( r < 0 )
			TEST_FAILED;

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

		engine->Release();
	}

	// Test property accessors for opIndex
	{
		engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
		engine->SetMessageCallback(asMETHOD(COutStream, Callback), &out, asCALL_THISCALL);
		RegisterScriptArray(engine, false);
		RegisterScriptString(engine);
		engine->RegisterGlobalFunction("void assert(bool)", asFUNCTION(Assert), asCALL_GENERIC);

		const char *script = 
			"class CTest \n"
			"{ \n"
			"  CTest() { arr.resize(5); } \n"
			"  int get_opIndex(int i) const { return arr[i]; } \n"
			"  void set_opIndex(int i, int v) { arr[i] = v; } \n"
			"  array<int> arr; \n"
			"} \n"
			"void main() \n"
			"{ \n"
			"  CTest s; \n"
			"  s[0] = 42; \n"
			"  assert( s[0] == 42 ); \n"
			"  s[1] = 24; \n"
			"  assert( s[1] == 24 ); \n"
			"} \n";

		asIScriptModule *mod = engine->GetModule(0, asGM_ALWAYS_CREATE);
		mod->AddScriptSection("script", script);
		r = mod->Build();
		if( r < 0 )
			TEST_FAILED;

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

		engine->Release();
	}

	// Test global property accessors with index argument
	{
		engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
		engine->SetMessageCallback(asMETHOD(COutStream, Callback), &out, asCALL_THISCALL);
		RegisterScriptArray(engine, false);
		RegisterScriptString(engine);
		engine->RegisterGlobalFunction("void assert(bool)", asFUNCTION(Assert), asCALL_GENERIC);

		const char *script = 
			"  int get_arr(int i) { arr.resize(5); return arr[i]; } \n"
			"  void set_arr(int i, int v) { arr.resize(5); arr[i] = v; } \n"
			"  array<int> arr; \n"
			"void main() \n"
			"{ \n"
			"  arr[0] = 42; \n"
			"  assert( arr[0] == 42 ); \n"
			"  arr[1] = 24; \n"
			"  assert( arr[1] == 24 ); \n"
			"} \n";

		asIScriptModule *mod = engine->GetModule(0, asGM_ALWAYS_CREATE);
		mod->AddScriptSection("script", script);
		r = mod->Build();
		if( r < 0 )
			TEST_FAILED;

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

		engine->Release();
	}

	// Test member property accessors with index argument
	{
		engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
		engine->SetMessageCallback(asMETHOD(COutStream, Callback), &out, asCALL_THISCALL);
		RegisterScriptArray(engine, false);
		RegisterScriptString(engine);
		engine->RegisterGlobalFunction("void assert(bool)", asFUNCTION(Assert), asCALL_GENERIC);

		const char *script = 
			"class CTest \n"
			"{ \n"
			"  CTest() { arr.resize(5); } \n"
			"  int get_arr(int i) { return arr[i]; } \n"
			"  void set_arr(int i, int v) { arr[i] = v; } \n"
			"  private array<int> arr; \n"
			"  void test() \n"
			"  { \n"
			"    arr[0] = 42; \n"
			"    assert( arr[0] == 42 ); \n"
			"    arr[1] = 24; \n"
			"    assert( arr[1] == 24 ); \n"
			"  } \n"
			"} \n"
			"void main() \n"
			"{ \n"
			"  CTest s; \n"
			"  s.arr[0] = 42; \n"
			"  assert( s.arr[0] == 42 ); \n"
			"  s.arr[1] = 24; \n"
			"  assert( s.arr[1] == 24 ); \n"
			"  s.test(); \n"
			"} \n";

		asIScriptModule *mod = engine->GetModule(0, asGM_ALWAYS_CREATE);
		mod->AddScriptSection("script", script);
		r = mod->Build();
		if( r < 0 )
			TEST_FAILED;

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

		engine->Release();
	}

	// Test member property accessors with ++ where the set accessor takes a reference
	{
		engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
		engine->SetMessageCallback(asMETHOD(CBufferedOutStream, Callback), &bout, asCALL_THISCALL);

		bout.buffer = "";
		const char *script = 
			"class CTest \n"
			"{ \n"
			"  double _vol; \n"
			"  double get_vol() const { return _vol; } \n"
			"  void set_vol(double &in v) { _vol = v; } \n"
			"} \n"
			"CTest t; \n"
			"void main() \n"
			"{ \n"
			"  for( t.vol = 0; t.vol < 10; t.vol++ ); \n"
			"} \n";

		asIScriptModule *mod = engine->GetModule(0, asGM_ALWAYS_CREATE);
		mod->AddScriptSection("script", script);
		r = mod->Build();
		if( r >= 0 )
			TEST_FAILED;
		if( bout.buffer != "script (8, 1) : Info    : Compiling void main()\n"
		                   "script (10, 36) : Error   : Invalid reference. Property accessors cannot be used in combined read/write operations\n" )
		{
			printf("%s", bout.buffer.c_str());
			TEST_FAILED;
		}

		engine->Release();
	}

	// Test get property returning reference
	{
		engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
		engine->SetMessageCallback(asMETHOD(CBufferedOutStream, Callback), &bout, asCALL_THISCALL);

		engine->RegisterObjectType("LevelType", sizeof(CLevel), asOBJ_VALUE | asOBJ_POD);
		engine->RegisterObjectProperty("LevelType", "float attr", offsetof(CLevel, attr));
		engine->RegisterGlobalFunction("LevelType &get_Level()", asFUNCTION(get_Level), asCALL_CDECL);
		
		r = ExecuteString(engine, "Level.attr = 0.5f;");
		if( r != asEXECUTION_FINISHED ) 
			TEST_FAILED;

		if( g_level.attr != 0.5f )
			TEST_FAILED;

		engine->Release();
	}

	// Make sure it is possible to update properties of objects returned through getter
	{
		engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
		engine->SetMessageCallback(asMETHOD(COutStream, Callback), &out, asCALL_THISCALL);
		RegisterScriptMath3D(engine);
		engine->RegisterObjectType("node", 0, asOBJ_REF);
		engine->RegisterObjectBehaviour("node", asBEHAVE_FACTORY, "node @f()", asFUNCTION(CNode::CNodeFactory), asCALL_CDECL);
		engine->RegisterObjectBehaviour("node", asBEHAVE_ADDREF, "void f()", asMETHOD(CNode, AddRef), asCALL_THISCALL);
		engine->RegisterObjectBehaviour("node", asBEHAVE_RELEASE, "void f()", asMETHOD(CNode, Release), asCALL_THISCALL);
		engine->RegisterObjectMethod("node", "node @+ get_child()", asMETHOD(CNode, GetChild), asCALL_THISCALL);
		engine->RegisterObjectMethod("node", "void set_child(node @+)", asMETHOD(CNode, SetChild), asCALL_THISCALL);
		engine->RegisterObjectProperty("node", "vector3 vector", offsetof(CNode, vector));
		engine->RegisterObjectProperty("node", "float x", offsetof(CNode, vector));

		r = ExecuteString(engine, "node @a = node(); \n"
								  "@a.child = node(); \n"
								  "a.child.x = 0; \n"
								  "a.child.vector = vector3(0,0,0); \n");
		if( r != asEXECUTION_FINISHED )
			TEST_FAILED;

		engine->Release();
	}

	fail = Test2() || fail;

	// Success
	return fail;
}
Esempio n. 29
0
bool Test()
{
	if( strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY") )
	{
		printf("%s: Skipped due to AS_MAX_PORTABILITY\n", TESTNAME);
		return false;
	}
	bool fail = false;
	int r;
	COutStream out;
	asIScriptEngine *engine;
	asIScriptModule *mod;
	asIScriptContext *ctx;

 	engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);

	RegisterScriptString(engine);

	r = engine->RegisterObjectType("refclass", sizeof(CRefClass), asOBJ_REF); assert(r >= 0);
	r = engine->RegisterObjectBehaviour("refclass", asBEHAVE_FACTORY, "refclass@ f()", asFUNCTION(Factory), asCALL_CDECL); assert(r >= 0);
	r = engine->RegisterObjectBehaviour("refclass", asBEHAVE_ADDREF, "void f()", asMETHOD(CRefClass, AddRef), asCALL_THISCALL); assert(r >= 0);
	r = engine->RegisterObjectBehaviour("refclass", asBEHAVE_RELEASE, "void f()", asMETHOD(CRefClass, Release), asCALL_THISCALL); assert(r >= 0);
	r = engine->RegisterObjectMethod("refclass", "refclass &opAssign(refclass &in)", asMETHOD(CRefClass, operator=), asCALL_THISCALL); assert(r >= 0);
	r = engine->RegisterObjectMethod("refclass", "refclass &Do()", asMETHOD(CRefClass,Do), asCALL_THISCALL); assert(r >= 0);
	r = engine->RegisterObjectMethod("refclass", "refclass &opAdd(refclass &in)", asFUNCTION(CRefClass::Add), asCALL_CDECL_OBJFIRST); assert(r >= 0);

	r = engine->RegisterGlobalFunction("void Assert(bool)", asFUNCTION(Assert), asCALL_GENERIC); assert( r >= 0 );

	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);
	}

	ctx = engine->CreateContext();
	r = ExecuteString(engine, "TestObjHandle()", mod, ctx);
	if( r != asEXECUTION_FINISHED )
	{
		if( r == asEXECUTION_EXCEPTION )
			PrintException(ctx);

		TEST_FAILED;
		printf("%s: Execution failed\n", TESTNAME);
	}
	if( ctx ) ctx->Release();

	// Call TestObjReturnHandle() from the application to verify that references are updated as necessary
	ctx = engine->CreateContext();
	ctx->Prepare(engine->GetModule(0)->GetFunctionIdByDecl("refclass@ TestObjReturnHandle(refclass@)"));
	CRefClass *refclass = new CRefClass();

	ctx->SetArgObject(0, refclass);

	r = ctx->Execute();
	if( r != asEXECUTION_FINISHED )
	{
		if( r == asEXECUTION_EXCEPTION )
			PrintException(ctx);

		TEST_FAILED;
		printf("%s: Execution failed\n", TESTNAME);
	}
	if( refclass->refCount != 2 )
	{
		TEST_FAILED;
		printf("%s: Ref count is wrong\n", TESTNAME);
	}

	refclass->Release();
	if( ctx ) ctx->Release();

	// Test returning a reference to the object from an object method
	r = engine->GarbageCollect();
	asUINT gcCurrentSize;
	engine->GetGCStatistics(&gcCurrentSize, 0, 0);
	assert( gcCurrentSize == 10 ); // The script class types and functions are also in the gc

	r = ExecuteString(engine, "refclass ref; ref.Do()");
	if( r != asEXECUTION_FINISHED )
	{
		TEST_FAILED;
	}

	engine->Release();

	//--------------------
	engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
	engine->SetMessageCallback(asMETHOD(COutStream, Callback), &out, asCALL_THISCALL);
	RegisterScriptArray(engine, true);
	r = engine->RegisterGlobalFunction("void Assert(bool)", asFUNCTION(Assert), asCALL_GENERIC); assert( r >= 0 );
	mod = engine->GetModule(0, asGM_ALWAYS_CREATE);
	mod->AddScriptSection(TESTNAME, 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();

	//----------------------
	// It should be allowed to have a global function return a handle to a const object
	engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
	engine->SetMessageCallback(asMETHOD(COutStream, Callback), &out, asCALL_THISCALL);
	const char *scriptC = "class T {} const T@ func() {return T();}";
	mod = engine->GetModule(0, asGM_ALWAYS_CREATE);
	mod->AddScriptSection("script", scriptC, strlen(scriptC));
	r = mod->Build();
	if( r < 0 ) TEST_FAILED;
	engine->Release();

	//---------------------
	// These tests are designed to make sure ambiguities with handles is avoided
	CBufferedOutStream bout;
	engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
	engine->SetMessageCallback(asMETHOD(CBufferedOutStream, Callback), &bout, asCALL_THISCALL);

	r = engine->RegisterObjectType("A", sizeof(CRefClass), asOBJ_REF); assert(r >= 0);
	r = engine->RegisterObjectBehaviour("A", asBEHAVE_FACTORY, "A@ f()", asFUNCTION(Factory), asCALL_CDECL); assert(r >= 0);
	r = engine->RegisterObjectBehaviour("A", asBEHAVE_ADDREF, "void f()", asMETHOD(CRefClass, AddRef), asCALL_THISCALL); assert(r >= 0);
	r = engine->RegisterObjectBehaviour("A", asBEHAVE_RELEASE, "void f()", asMETHOD(CRefClass, Release), asCALL_THISCALL); assert(r >= 0);
	r = engine->RegisterObjectMethod("A", "A &opAssign(const A &in)", asMETHOD(CRefClass, operator=), asCALL_THISCALL); assert(r >= 0);

	bout.buffer = "";
	r = ExecuteString(engine, "A a; a == null;");    // Should give warning
	if( r < 0 || bout.buffer == "" )
	{
		TEST_FAILED;
	}
	bout.buffer = "";
	r = ExecuteString(engine, "A a; null == a;");    // Should give warning
	if( r < 0 || bout.buffer == "" )
	{
		TEST_FAILED;
	}
	bout.buffer = "";
	r = ExecuteString(engine, "A a; @a == null;");   // OK
	if( r < 0 || bout.buffer != "" )
	{
		TEST_FAILED;
	}
	bout.buffer = "";
	r = ExecuteString(engine, "A a; null == @a;");   // OK
	if( r < 0 || bout.buffer != "" )
	{
		TEST_FAILED;
	}
	bout.buffer = "";
	r = ExecuteString(engine, "A a; @a == a;");      // Should give warning
	if( r < 0 || bout.buffer == "" )
	{
		TEST_FAILED;
	}
	bout.buffer = "";
	r = ExecuteString(engine, "A a; a == @a;");      // Should give warning
	if( r < 0 || bout.buffer == "" )
	{
		TEST_FAILED;
	}
	bout.buffer = "";
	r = ExecuteString(engine, "A a; @a == @a;");     // OK
	if( r < 0 || bout.buffer != "" )
	{
		TEST_FAILED;
	}
	bout.buffer = "";
	r = ExecuteString(engine, "A @a = null;");       // OK
	if( r < 0 || bout.buffer != "" )
	{
		TEST_FAILED;
	}
	bout.buffer = "";
	r = ExecuteString(engine, "A a; A @b = a;");     // OK
	if( r < 0 || bout.buffer != "" )
	{
		TEST_FAILED;
	}
	bout.buffer = "";
	r = ExecuteString(engine, "A a; A @b = @a;");    // OK
	if( r < 0 || bout.buffer != "" )
	{
		TEST_FAILED;
	}
	bout.buffer = "";
	r = ExecuteString(engine, "A a; A b = @b;");     // Should give error
	if( r >= 0 || bout.buffer == "" )
	{
		TEST_FAILED;
	}
	bout.buffer = "";
	r = ExecuteString(engine, "A @a, b; @a = @b;");  // OK
	if( r < 0 || bout.buffer != "" )
	{
		TEST_FAILED;
	}
	bout.buffer = "";
	r = ExecuteString(engine, "A @a, b; @a = b;");   // OK
	if( r < 0 || bout.buffer != "" )
	{
		TEST_FAILED;
	}
	bout.buffer = "";
	r = ExecuteString(engine, "A @a, b; a = @b;");   // Should give error
	if( r >= 0 || bout.buffer == "" )
	{
		TEST_FAILED;
	}

	bout.buffer = "";
	r = ExecuteString(engine, "A a; null is a;");    // OK
	if( r < 0 || bout.buffer != "" )
	{
		TEST_FAILED;
	}
	bout.buffer = "";
	r = ExecuteString(engine, "A a; a !is null;");    // OK
	if( r < 0 || bout.buffer != "" )
	{
		TEST_FAILED;
	}

	engine->Release();

	// Success
	return fail;
}
Esempio n. 30
0
bool TestExecute32MixedArgs()
{
	bool fail = false;

 	asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
	if( strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY") )
	{
		engine->RegisterGlobalFunction(		"void cfunction("
				"int, int, int, int,"
				"float, float, float, float,"
				"int, int, int, int,"
				"float, float, float, float,"
				"int, int, int, int,"
				"float, float, float, float,"
				"int, int, int, int,"
				"float, float, float, float"
			")", asFUNCTION(cfunction_gen), asCALL_GENERIC);
	}
	else
	{
		engine->RegisterGlobalFunction(		"void cfunction("
				"int, int, int, int,"
				"float, float, float, float,"
				"int, int, int, int,"
				"float, float, float, float,"
				"int, int, int, int,"
				"float, float, float, float,"
				"int, int, int, int,"
				"float, float, float, float"
			")", asFUNCTION(cfunction), asCALL_CDECL);
	}

	ExecuteString(engine, 
		"cfunction("
			" 1,  2,  3,  4,"
			" 5.0f,  6.0f,  7.0f,  8.0f,"
			" 9, 10, 11, 12,"
			"13.0f, 14.0f, 15.0f, 16.0f,"
			"17, 18, 19, 20,"
			"21.0f, 22.0f, 23.0f, 24.0f,"
			"25, 26, 27, 28,"
			"29.0f, 30.0f, 31.0f, 32.0f"
		")");

	if( !called ) 
	{
		// failure
		printf("\n%s: cfunction not called from script\n\n", TESTNAME);
		TEST_FAILED;
	} 
	else if( !testVal ) 
	{
		// failure
		printf("\n%s: testVal is not of expected value. Got:\n\n", TESTNAME);
		int pos = 0;
		for( int i = 0; i < 4; i++ ) 
		{
			int j;
			for( j = 0; j < 4; j++ ) 
				printf("ivalue[%d]: %d\n", pos+j, ivalues[pos+j]);
			for( j = 0; j < 4; j++ ) 
				printf("fvalue[%d]: %f\n", pos+j, fvalues[pos+j]);
			pos += 4;
		}
		TEST_FAILED;
	}

	engine->Release();
	
	// Success
	return fail;
}