Sign in to follow this  

Contexts are not independent ?

Recommended Posts

I'm starting to play with AS and I have a question about contexts. My understanding of contexts is limited, and I was assuming that contexts were independent of each other, so that if the same script code was executed, the global variables could hold different values in different contexts. Let me explain quickly. Here's a simple script:
int x = 0;
void test()
Now in C++, I declare two contexts:
int func = pEngine->GetFunctionIDByDecl("dummy", "void test()");

asIScriptContext *ctx1 = pEngine->CreateContext();
res = ctx1->Prepare(func);
res = ctx1->Execute();

asIScriptContext *ctx2 = pEngine->CreateContext();
res = ctx2->Prepare(func);
res = ctx2->Execute();
The execute() call of ctx1 will print x with a value of 1, as expected. Now when I create the second context, I'm expecting x to be reset to 0, and the execute() call of ctx2 to display x with a value of 1 too. But it displays a value of 2, like if variables values were shared between contexts. Is this the expected behavior ? If so, is there any way to make the variables context dependent ? Thanks.. Y.

Share this post

Link to post
Share on other sites
I'm honored that you're looking into AS. I've been following your progress on Infinity for quite some time, and I'm in awe of what you've accomplished so far.

asIScriptContext is an unfortunate name, which commonly leads to this mistake. A better name would be asIScriptThread because that's what they are.

The global variables in a module are shared between all contexts executing scripts in that module. The best way of having separate variables for each context is to use script classes, and then call the class methods rather than the global functions.

It would be possible to duplicate the module, either by compiling the scripts again (slow) or by saving the already compiled bytecode to memory and then reloading it in another module. However, at the moment this will incur a rather large penalty in that all the bytecode is also duplicated. I'm working on improving this, but have not yet determined the best approach to it.

Let me know if you have any wishes for improvements to the library. The to-do list is already quite extensive, but I usually prioritize user requests if they are not too complicated.


Share this post

Link to post
Share on other sites

Thanks for your fast answer. I'm evaluating AS for a project different than Infinity (work related), but it will also serve as a study case to see if I can apply to Infinity.

I've been following AS's development for some time now, mostly lurking. I'm impressed by the quality of the lib so far, and the amount of dedication and support you've given to it, especially since it's all free. The fact that the project has been started many years ago (how long now ? 4?) and is still very active is one of the key points that lead me to seriously evaluate it.

Back on topic: yeah, I understand now. I also realized what I'm trying to achieve could be done with modules, by registering the same source code to modules of different names. I'm a bit worried of the build time with this approach though, as the idea is that modules would be assigned dynamically to different entities. Have you done any study on compilation times ? My scripts won't be too complicated initially, maybe a few hundred lines at most..

I wasn't aware you could call class methods from C++. The doc seems to be a bit lacking in that area (btw, more examples in the docs would be welcome, I spent hours to register my Vector3D class :)). I'm not sure if it will help though, but I will play with the idea next monday. Thanks!


Share this post

Link to post
Share on other sites
I've worked on AS for 5.5 years now, and I'm still dedicated to the continuous improvement of the library.

Compilation times are quite short, however if it is short enough for your needs is another matter. If you find compilations times to be too long, I'm willing to spend some time on optimizing it.

Of course, however much time I spend on optimizing the compiler, I won't be able to make it faster than avoiding the compilation all together. Duplicating modules via the Save/LoadByteCode functions is always going to be faster than compiling everything from scratch.

Yeah, documentation is perhaps the biggest flaw with AngelScript. Even though I've spend quite a lot of time on improving that the last months, there is still a lot to add.

The class methods are called much the same way as the global functions. You just need to pass the object pointer to the context.

// create an instance of the object (if you don't have one already)
// this will call the class' default constructor
int typeId = engine->GetTypeIdByDecl("module", "myclass");
asIScriptStruct *obj = (asIScriptStruct*)engine->CreateScriptObject(typeId);

// determine the method's function id
asIObjectType *objType = obj->GetObjectType();
int funcId = objType->GetMethodIdByDecl("void func()");

// call the class method
asIScriptContext *ctx = engine->CreateContext();

// Clean up


Share this post

Link to post
Share on other sites
And when calling "createScriptObject" from C++, is it possible to pass arguments to the constructor or does it only work with the default constructor ? If it's possible, how ? If not, I might have to delegate the construction to a "create" method.. Thanks,


Share this post

Link to post
Share on other sites
It's not possible to pass any arguments yet. Though if you need to create a copy of an object you can call CreateScriptObjectCopy() instead.

For creation of objects with any arguments it is easiest to implement a factory
function in the script and have the application call that.

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this