object handles references etc
I had indeed broken this functionality, but have already fixed it for WIP 4. There were quite a few minor changes to make it work again so I didn't post the changes here, I also thought it wasn't that urgent.
I also noticed another thing that I had to fix. The library wasn't consistent in the way it handled object handle references returned from application functions. For constructors it expected the reference count to be 1 already when returned, but for application functions that returned object handles it increased the reference itself. This could lead to problems, especially if the application implemented factory functions instead of constructors. The factory function were then supposed to return the object with a reference count of 0, which could cause a problem if there was no direct way of setting the reference counter.
My solution is that all application functions that return an object handle must also manually call the addref method on the object before returning it. Meaning that the application is responsible for counting the reference that is being returned. I've updated the source code for the CallSystemFunction() (in the post above) to not automatically increase the reference counter when calling functions that return object handles.
At a later time I might add a way to allow the application to tell the library to do the addref() call automatically.
I also noticed another thing that I had to fix. The library wasn't consistent in the way it handled object handle references returned from application functions. For constructors it expected the reference count to be 1 already when returned, but for application functions that returned object handles it increased the reference itself. This could lead to problems, especially if the application implemented factory functions instead of constructors. The factory function were then supposed to return the object with a reference count of 0, which could cause a problem if there was no direct way of setting the reference counter.
My solution is that all application functions that return an object handle must also manually call the addref method on the object before returning it. Meaning that the application is responsible for counting the reference that is being returned. I've updated the source code for the CallSystemFunction() (in the post above) to not automatically increase the reference counter when calling functions that return object handles.
At a later time I might add a way to allow the application to tell the library to do the addref() call automatically.
AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game
Quote: Original post by WitchLord
I also thought it wasn't that urgent.
No, no, I was just curious :)
Hey, I have another reference related bug/question. Check out the following test:
If this would have been object handles it would have worked fine to write "test(@ref)", but is the syntax for the script in this example correct? The compiler does not seem to understand "test(&ref)" or any ∈/out combination but without the amp it compiles. But then the test just ends with "Execution failed" (return code -1). What's the deal here?
(edit: test code updated)
[Edited by - quarn on January 14, 2005 3:05:37 PM]
#include "utils.h"namespace TestRefArgument{#define TESTNAME "TestRefArgument"static const char *script1 ="void TestObjHandle(refclass &in ref) \n""{ \n"" Assert(ref.id == 0xdeadc0de); \n"" test(ref); \n""} \n""void test(refclass &in ref) \n""{ \n"" Assert(ref.id == 0xdeadc0de); \n""}";class CRefClass{public: CRefClass() { id = 0xdeadc0de; } ~CRefClass() { } int id;};static void Assert(bool expr){ if( !expr ) { printf("Assert failed\n"); asIScriptContext *ctx = asGetActiveContext(); if( ctx ) { asIScriptEngine *engine = ctx->GetEngine(); printf("func: %s\n", engine->GetFunctionDeclaration(ctx->GetCurrentFunction())); printf("line: %d\n", ctx->GetCurrentLineNumber()); ctx->SetException("Assert failed"); } }}bool Test(){ bool fail = false; int r; asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); RegisterStdString(engine); r = engine->RegisterObjectType("refclass", 0, asOBJ_CLASS); assert(r >= 0); r = engine->RegisterObjectProperty("refclass", "int id", offsetof(CRefClass, id)); r = engine->RegisterGlobalFunction("void Assert(bool)", asFUNCTION(Assert), asCALL_CDECL); assert( r >= 0 ); COutStream out; engine->AddScriptSection(0, TESTNAME, script1, strlen(script1), 0); r = engine->Build(0, &out); if( r < 0 ) { fail = true; printf("%s: Failed to compile the script\n", TESTNAME); } asIScriptContext *ctx; engine->CreateContext(&ctx); int func = engine->GetFunctionIDByName(0, "TestObjHandle"); assert(r >= 0); CRefClass cref; r = ctx->Prepare(r); assert(r >= 0); ctx->SetArgObject(0, &cref); r = ctx->Execute(); assert(r >= 0); if( r != asEXECUTION_FINISHED ) { fail = true; printf("%s: Execution failed: %d\n", TESTNAME, r); } if( ctx ) ctx->Release(); engine->Release(); // Success return fail;}} // namespace
If this would have been object handles it would have worked fine to write "test(@ref)", but is the syntax for the script in this example correct? The compiler does not seem to understand "test(&ref)" or any ∈/out combination but without the amp it compiles. But then the test just ends with "Execution failed" (return code -1). What's the deal here?
(edit: test code updated)
[Edited by - quarn on January 14, 2005 3:05:37 PM]
I haven't had the time to run this test yet, but I noticed that your ExecuteString() is trying to call a function that doesn't exist (missing parameter). That would lead to a return code of -1 (because it will not be able to compile the string), hence "Execution failed".
The script syntax is correct as far as I can see.
Another thing: You registered the type as asOBJ_CLASS, but you should have used asOBJ_CLASS_CD. This shouldn't affect the result in this test, but I just thought I'd point it out as it could cause problems in other situations.
The script syntax is correct as far as I can see.
Another thing: You registered the type as asOBJ_CLASS, but you should have used asOBJ_CLASS_CD. This shouldn't affect the result in this test, but I just thought I'd point it out as it could cause problems in other situations.
AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game
Quote: Original post by WitchLord
I haven't had the time to run this test yet, but I noticed that your ExecuteString() is trying to call a function that doesn't exist (missing parameter). That would lead to a return code of -1 (because it will not be able to compile the string), hence "Execution failed".
Ah, how silly of me. I have fixed this in the code above now. The test does not pass for me. Acctually, I ran into this reference problem outside of this test before I wrote the first post asking about object handles. I didn't remember it until yesterday so I quickly cut'n'pasted together a test without looking through what it was I had written. Cut'n'paste can be evil sometimes :)
Quote: Another thing: You registered the type as asOBJ_CLASS, but you should have used asOBJ_CLASS_CD. This shouldn't affect the result in this test, but I just thought I'd point it out as it could cause problems in other situations.
Well, in my local copy I registered the type with a size of 0 and no constructor/destructor logic. This just to see that the reference is ok for this test. If I don't register the constructor/destructor behaviours, will registering asOBJ_CLASS give me anything different from when registering with asOBJ_CLASS_CD?
Is this for when objects are to be returned in memory or registers when calling system functions?
Still haven't gotten the time to test the code. Sorry about that. I'm quite busy at work at the moment.
I think that SetArgObject() doesn't work in this case (though it should, I'll have to take a look at this). As the parameter is expecting a direct reference you could use SetArgDWord() instead.
The asOBJ_??? flag for RegisterObjectType() should reflect the actual C++ object. Wether you register constructor/destructor behaviours doesn't have anything to do with this flag. The flag tells the library how the application handles the object when passing it to functions and/or returning it from functions.
If you register the type with a size of 0, it shouldn't matter what flag you use because the object cannot be passed around by value anyway.
I think that SetArgObject() doesn't work in this case (though it should, I'll have to take a look at this). As the parameter is expecting a direct reference you could use SetArgDWord() instead.
The asOBJ_??? flag for RegisterObjectType() should reflect the actual C++ object. Wether you register constructor/destructor behaviours doesn't have anything to do with this flag. The flag tells the library how the application handles the object when passing it to functions and/or returning it from functions.
If you register the type with a size of 0, it shouldn't matter what flag you use because the object cannot be passed around by value anyway.
AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game
Hehe, you don't have to apologize for actually doing your job when you are at work... ;)
SetArgDWord(0, (asDWORD) &cref) results in a segmentation fault.
Thanks for clearing up what the flags mean.
SetArgDWord(0, (asDWORD) &cref) results in a segmentation fault.
Thanks for clearing up what the flags mean.
The problem you're having with the argument reference is that the object was registered with the size of 0. These types cannot be passed by value nor by reference (only by handle), because the library cannot create copies of the objects.
I've corrected the compiler so that is outputs an error message in this situation.
Also SetArgDWord() for object references causes an error. The segmentation fault you got was because the library allowed Execute() to continue even though the argument was invalid. This too has been corrected.
I've completed all the code for AS 2.0.0 now, and will upload WIP 4 as soon as possible. The only thing missing before the final release is some needed updates to the documentation. Hopefully I should be able to finish that before the end of the week.
Regards,
Andreas
I've corrected the compiler so that is outputs an error message in this situation.
Also SetArgDWord() for object references causes an error. The segmentation fault you got was because the library allowed Execute() to continue even though the argument was invalid. This too has been corrected.
I've completed all the code for AS 2.0.0 now, and will upload WIP 4 as soon as possible. The only thing missing before the final release is some needed updates to the documentation. Hopefully I should be able to finish that before the end of the week.
Regards,
Andreas
AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement