Skip to main content
GameDev.net gamedev.net
🔒 Locked

User data

Started by SiCrane Oct 26, 2008 at 11:25 AM 25 replies 7.9k views
Original Post
SiCrane
SiCrane
A couple questions: is there an equivalent for SetUserData()/GetUserData() for asIScriptEngine? Also, for asIScriptContext, is there a way to register a function to cleanup user data when the context is destroyed?
WitchLord
WitchLord
No, there is currently no support for this.

However, these are good ideas that I'll add to the to-do list.
AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - <a href="http://www.angelcode.com/tower" rel
SiCrane
SiCrane
Sounds good, but I have another question: is there any way to map a type id from GetVarTypeId() to the actual type for primitives? Right now it seems like the type ids depend on what types show up first when scripts are compiled. To put things in context, I decided to see how using AngelScript from .NET would work out and for a proof on concept application I choose to make the world's most primitive debugger. So if I use this script:
int calc(int a, float b) {  print("Received: " + a + ", " + b + "\n");  return a * b;}void main() {  calc(3, 2);}

a shows up with type id of 1 and b shows up with a type id of 2. If I swap things around
int calc(float a, int b)

a shows up with a type id of 2 and b shows up with a type id of 1... until I restart the application, and then a becomes 1 and b becomes 2 again.

For reference, the MSVS 2008 solution for this project is available here. (It requires the addition of SetUserData()/GetUserData() to asIScriptEngine (included in the project) as well as Scintilla.NET.)
WitchLord
WitchLord
The idea is that you should compare the type id from GetVarTypeId with the result from GetTypeIdByDecl, alternatively call GetTypeDeclaration and compare the names of the types.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - <a href="http://www.angelcode.com/tower" rel
SiCrane
SiCrane
GetTypeDeclaration() looks like just what I needed. Thanks.
SiCrane
SiCrane
Ok, another question on this topic: is there any way to tell if a local variable has been constructed yet in a line callback or suspended thread?
WitchLord
WitchLord
AngelScript currently does not keep the scope of the variables in the functions, so there is no direct way of knowing if the variable has been constructed yet.

All object type variables are however null until they have been constructed, so that might help a bit.
AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - <a href="http://www.angelcode.com/tower" rel
SiCrane
SiCrane
Yeah, that should help. Thanks.
SiCrane
SiCrane
Last two for today, I promise: Is there an equivalent of GetVarTypeId() for globals or do I have to parse the result from GetGlobalVarDeclaration()? Also, if I have a type Object registered as a value type, why does GetVarPointer() return an Object ** instead of an Object *?
WitchLord
WitchLord
AngelScript is currently missing a GetGlobalVarTypeId. I just forgot to add this one, I'll do that for version 2.15.0.

You can however get the type by id by calling GetTypeIdByDecl(GetGlobalVarDeclaration()).

Currently AngelScript stores all registered types on the heap, whether they are value types or reference types. This is going to change in the near future (will improve both memory footprint and performance).

I'll also do with GetVarPointer what I did with GetGlobalVarPointer, i.e. deprecate it and create a GetAddressOfVar instead. GetAddressOfVar will return the address of the object directly, in the case of value types.
AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - <a href="http://www.angelcode.com/tower" rel
SiCrane
SiCrane
GetTypeIdByDecl() doesn't seem to be working for me. I've got a script with a global "int foo = 10;" so GetGlobalVarDeclaration() returns "int foo". If I pass that "int foo" to GetTypeIdByDecl() I get an asINVALID_TYPE error.
WitchLord
WitchLord
Hmm, I forgot about that. It returns asINVALID_TYPE because it's not expecting the variable name, only the data type.

Perhaps you'd like to add a method GetGlobalVarTypeId yourself, until version 2.15.0 comes out?

int asCModule::GetGlobalVarTypeId(int index){    if( index < 0 || index >= (int)scriptGlobals.GetLength() )        return asINVALID_ARG;    asCProperty *prop = scriptGlobals[index];    return engine->GetTypeIdFromDataType(prop->type);}


Regards,
Andreas
AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - <a href="http://www.angelcode.com/tower" rel
SiCrane
SiCrane
Is there a way to get at the asCModule directly or do I also need to add in a forwarding function in asIScriptEngine?
WitchLord
WitchLord
Until I expose the asIScriptModule interface you'll need a forwarding function in the script engine.
AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - <a href="http://www.angelcode.com/tower" rel
SiCrane
SiCrane
I think something funky is going on inside of asCScriptStruct. If I run a script that creates a script object the program crashes with an access violation on program exit inside asCThreadCriticalSection::Enter() during engine clean up. I can define script classes and it won't crash unless I actually create a variable of a script class type.

Unfortunately, I can't actually reproduce this with anything less than my full executable. Creating script classes in the script run by the tutorial sample doesn't cause it to crash. It also doesn't crash if recompile with AS_NO_THREADS.

On an unrelated note, is there a good way to tell from a type id if the type is a script defined class? Right now I'm storing a list of types I register and assume everything else that's not a built-in type is defined in the script. Also, is there a reason that asIScriptStruct doesn't have a GetEngine() member function?
WitchLord
WitchLord
Looks to be the same bug that BornToCode mentioned here: http://www.gamedev.net/community/forums/topic.asp?topic_id=512108

I haven't been able to reproduce it though, so I don't know what it is. However, I just checked in some changes to implement atomic reference counters, instead of using critical sections. With any luck it has fixed the bug as well. Would you mind giving it a try?

To check if a type id is for a script declared class you can check the asTYPEID_SCRIPTSTRUCT bit. This is an undocumented feature, and I don't guarantee that it will continue to work (though I have no immediate intention to change it).

No, there is no real reason the asIScriptStruct doesn't have a GetEngine() method. I'll add it for 2.15. Thanks.
AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - <a href="http://www.angelcode.com/tower" rel
SiCrane
SiCrane
I'll give the new code a try in the morning. Thanks.
SiCrane
SiCrane
Ok, I think I figured out the problem (at least my problem, no guarantees that it's also BornToCode's problem too). ~asCScriptStruct() uses the asCScriptEngine object to perform cleanup. However, at least one asCScriptStruct object is getting destroyed after the asCScriptEngine is destroyed, so since the CRITICAL_SECTION has already been cleaned up, trying to enter it causes an access violation. Adding engine->AddRef() and engine->Release() calls to asCScriptStruct's constructor and destructor seems to prevent the access violation from occurring.

edit: and bizarrely somehow an asCContext() created with holdRef = false is also managing to outlive the engine.

[Edited by - SiCrane on October 29, 2008 10:45:13 AM]
WitchLord
WitchLord
I suspected it might be something like that. Do you have any idea where the last asCScriptStruct is being held? Is your application releasing the engine before releasing the script structs that it holds? Is it is the engine itself that somehow releases the script struct in its destructor?

Anyway, I'll look into this.
AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - <a href="http://www.angelcode.com/tower" rel
SiCrane
SiCrane
It looks like it's happening inside the asCScriptEngine destructor when the last engine reference is Released(), so it's not a asCScriptStruct object that my application is holding that's outliving the engine. The call stack looks like:
>	AngelScript.NET.dll!AngelScript::asCThreadCriticalSection::Enter() Line 232	C++ 	AngelScript.NET.dll!AngelScript::asCThreadManager::GetLocalData(unsigned int threadId = 0x4a4) Line 149	C++ 	AngelScript.NET.dll!AngelScript::asCThreadManager::GetLocalData() Line 177 + 0xc bytes	C++ 	AngelScript.NET.dll!AngelScript::asPushActiveContext(AngelScript::asIScriptContext* ctx = 0x06A337C0) Line 127 + 0xb bytes	C++ 	AngelScript.NET.dll!AngelScript::asCContext::Execute() Line 978	C++ 	AngelScript.NET.dll!AngelScript::asCScriptStruct::Release() Line 278 + 0x1b bytes	C++ 	AngelScript.NET.dll!AngelScript::asCScriptEngine::CallObjectMethod(void* obj = 0x06A30348, AngelScript::asSSystemFunctionInterface* func = 0x04C3CF40, AngelScript::asCScriptFunction* desc = 0x04C3E2A8) Line 3025	C++ 	AngelScript.NET.dll!AngelScript::asCScriptEngine::CallObjectMethod(void* obj = 0x06A30348, int func = 0x11) Line 2978	C++ 	AngelScript.NET.dll!AngelScript::asCModule::CallExit() Line 214	C++ 	AngelScript.NET.dll!AngelScript::asCModule::InternalReset() Line 241	C++ 	AngelScript.NET.dll!AngelScript::asCModule::~asCModule() Line 65	C++ 	AngelScript.NET.dll!<Module>.AngelScript.asCModule.__vecDelDtor(uint  = 0x00000000) + 0x6b bytes	 	AngelScript.NET.dll!AngelScript::asCScriptEngine::~asCScriptEngine() Line 295 + 0x69 bytes	C++ 	AngelScript.NET.dll!<Module>.AngelScript.asCScriptEngine.__vecDelDtor(uint  = 0x00000000) + 0x6b bytes	 	AngelScript.NET.dll!AngelScript::asCScriptEngine::Release() Line 374 + 0x26 bytes	C++ 	AngelScript.NET.dll!AngelScript::ScriptEngine::!ScriptEngine() Line 58 + 0x27 bytes	C++ 	AngelScript.NET.dll!AngelScript::ScriptEngine::Dispose(bool  = false) + 0x40 bytes	C++ 	AngelScript.NET.dll!AngelScript.ScriptEngine.Finalize() + 0x1f bytes	

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.