Angelscript and Reflection

Started by
5 comments, last by SiS-Shadowman 13 years, 8 months ago
I'm currently integrating Angelscript into my engine editor and I want to expose angelscript's reflection feature to support syntax highlighting, as well as a fully featured debugger.

Some questions are popping into my mind:

1. Is it possible to build a module in thread a while a context might be executing in thread b (both created with the same asIScriptEngine object)?

2. Suppose I build a module.
If the build succeeded, does the asIScriptEngine object now know about all user defined types of that module?
What happens if I build the same module a second time? (Regarding asIObjectTypes and their ids)
Are those types gone when I release the module that defined them?

I thought of the following system (although it depends on your answers and is open to change):
Repeatedly build modules from the code the user types in the background.
Once the build has been finished, iterate over all registered types and expose that information to syntax highlighting (The same would be done for debugging).

Do you think this is a good approach for this problem?

*edit*
I'll also use this thread to post some suggestions:

Is there a reason I that asIScriptObject::GetAddressOfProperty has no const overloaded function that returns a const void*? I know this is no big deal, but I would like to pass a const void*, when creating a string representation of an object's value. It would be great if you could add the overload (if possible).

[Edited by - SiS-Shadowman on July 16, 2010 6:45:13 AM]
Advertisement
Quote:Original post by SiS-Shadowman
1. Is it possible to build a module in thread a while a context might be executing in thread b (both created with the same asIScriptEngine object)?


This is not supported. When a compilation is going on it will make updates to the internal states of the script engine, which may potentially cause the context to fail.

Quote:Original post by SiS-Shadowman
2. Suppose I build a module.
If the build succeeded, does the asIScriptEngine object now know about all user defined types of that module?


Yes.

Quote:Original post by SiS-Shadowman
What happens if I build the same module a second time? (Regarding asIObjectTypes and their ids)
Are those types gone when I release the module that defined them?


The original types are kept around as long as they are in use. The newly compiled types will co-exist with the original ones.

Quote:Original post by SiS-Shadowman
I thought of the following system (although it depends on your answers and is open to change):
Repeatedly build modules from the code the user types in the background.
Once the build has been finished, iterate over all registered types and expose that information to syntax highlighting (The same would be done for debugging).

Do you think this is a good approach for this problem?


This may work well. It would also allow you to highlight coding errors while the user is typing.

If you just want to find the declared types and their methods, then you could do something similar to what the CScriptBuilder does to find metadata for functions and classes.

The engine is used to parse the tokens, and the builder is simply looking for sequences of tokens that gives declarations new classes and types.

Quote:Original post by SiS-Shadowman
*edit*
I'll also use this thread to post some suggestions:

Is there a reason I that asIScriptObject::GetAddressOfProperty has no const overloaded function that returns a const void*? I know this is no big deal, but I would like to pass a const void*, when creating a string representation of an object's value. It would be great if you could add the overload (if possible).


I can certainly add the const overload. I'll add this 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 - Tower - free puzzle game

Quote:Original post by WitchLord
Quote:Original post by SiS-Shadowman
What happens if I build the same module a second time? (Regarding asIObjectTypes and their ids)
Are those types gone when I release the module that defined them?


The original types are kept around as long as they are in use. The newly compiled types will co-exist with the original ones.


How is as long as they are in use defined? Does releasing the module qualify for no longer in use?

Quote:Original post by WitchLord
Quote:Original post by SiS-Shadowman
I thought of the following system (although it depends on your answers and is open to change):
Repeatedly build modules from the code the user types in the background.
Once the build has been finished, iterate over all registered types and expose that information to syntax highlighting (The same would be done for debugging).

Do you think this is a good approach for this problem?


This may work well. It would also allow you to highlight coding errors while the user is typing.

If you just want to find the declared types and their methods, then you could do something similar to what the CScriptBuilder does to find metadata for functions and classes.

The engine is used to parse the tokens, and the builder is simply looking for sequences of tokens that gives declarations new classes and types.


It took me a while, but I think this might be a better solution than what I currently do:
I've written a small framework that executes tasks asynchronously amongst various threads and I'm using that to compile scripts. However currently I must ensure that I only execute one compilation task at a time, which is quite ugly.

If I were to go that way, I would like to combine collecting declarations and finding errors, but I think I would need to duplicate a lot of code in order to achieve both without invoking the engine, because after all, compilation errors also depend on the registered application interface.

It would be great if you could add an interface to the engine that allows parsing a script, collecting declarations, as well as errors. All that could be done without modifying the engine's state. I'm willing to help with that, if you're okay with it. I will need some time to study the code, involved in parsing the script, but I think I might be of help.

Quote:Original post by WitchLord
Quote:Original post by SiS-Shadowman
*edit*
I'll also use this thread to post some suggestions:

Is there a reason I that asIScriptObject::GetAddressOfProperty has no const overloaded function that returns a const void*? I know this is no big deal, but I would like to pass a const void*, when creating a string representation of an object's value. It would be great if you could add the overload (if possible).


I can certainly add the const overload. I'll add this to the to-do list.


Thanks.

Quote:Original post by SiS-Shadowman
How is as long as they are in use defined? Does releasing the module qualify for no longer in use?


Unless there is any active objects, or some objects in the garbage collector, then yes, releasing the module (or rebuilding it) is enough.

Quote:Original post by SiS-Shadowman
It would be great if you could add an interface to the engine that allows parsing a script, collecting declarations, as well as errors. All that could be done without modifying the engine's state. I'm willing to help with that, if you're okay with it. I will need some time to study the code, involved in parsing the script, but I think I might be of help.


How about you create a separate engine, just for this purpose?

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
How about you create a separate engine, just for this purpose?


Well, it would require me to duplicate a lot of your code, but I'm considering it. I could extract more information from the errors (especially which token is responsible for the error, so I can underline them, like VS does).


I'm currently trying to view the callstack, however there is something odd.
Imagine a script like the following:
void main(){   string test = "Hello World!";}

asIScriptContext::GetCallstackSize returns 0 when calling it inside the LineCallback (Although GetCurrentFunction returns the id of "void main()"). This would not be a problem on it's own, however I don't see how I can display the variables of the current function, since 0 is an invalid index for asIScriptContext::GetVarCount (because the callstack is empty).

Changing the script to
void main(){    string test = "Hello World!";    foo();}void foo(){    int n = 0;}

causes asIScriptContext::GetCallstackSize to return 1, when I'm inside foo(), however I can't inspect the variable 'n' in that case.

Do you have a suggestion what I can do inspect the variables of the current function?
I guess this is not very intuitive. I'll have to review this for a future version.

GetCallstackSize() returns the number of functions on the stack, besides the current function, i.e. if there is only one function on the stack it will return 0.

The variables in the current function is inspected by using the stackLevel -1 (default value) in the methods GetVarCount() etc.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

Thanks for the information.
I think it would be enough to add this to the documentation, I only noticed that the default is -1, but not what it actually stood for.

*edit*
I've got yet another small suggestion for the documentation.
My application kept crashing and I didn't figure out why, when I suddenly noticed that functions that return a reference counted object, like GetObjectTypeById, GetCurrentFunction, etc... do not increase the reference count of the object they return:
com_pointer<asIObjectType> type = m_engine->GetObjectTypeById();type->AddRef(); //< It didn't come to my mind to increase the ref count

This is obviously the solution, but it wasn't really apparent to me, since DirectX (always?) increases the reference count when return a pointer to something reference counted.
Changing that behaviour might not be an option, but it would be great if you could dedicate a small article to this "problem".

[Edited by - SiS-Shadowman on July 24, 2010 4:37:25 AM]

This topic is closed to new replies.

Advertisement