Advertisement

multiple contexts

Started by January 06, 2005 06:45 AM
6 comments, last by WitchLord 19 years, 10 months ago
i have one script tied to a 3d object. each object can appear multiple times in the screen, so each script instance is assigned a context upon creation. all these contexts will be stored so that it will be reused until the 3d object is to be removed from screen. only 1 engine is used. seems to have some random blocking when my player1 script calls FireEntity. but is what i am doing correct ? can angelscript support the creation of a new context when another context is still executing. the instances may grow even more when collision comes in. -------- c++ -------- FireEntity (string name) { AddObject (name); } AddObject (string name) { create new context *ctx; ctx->execute (init); } ------- angelscript player1.sc ------- void init() { } void move() { FireEntity ("bullet"); } -------- angelscript bullet.sc ------- void init() { } void move() { } -------- angelscript grenade.sc ------- void init() { } void move() { FireEntity ("explosion"); }
It ought to work perfectly well like this. Are you getting any error messages?

Are you using multithreading?

When a context is created the only thing that happens is that it increases the reference count on the engine. The engine also keeps a stack of currently executing contexts, where the topmost is the one returned by asGetActiveContext(). Other than that contexts are completely independent of each other. There is also no limit to how many contexts you can create, other than what your memory can handle.

Contexts use quite a lot of memory though, because each context allocates memory for the stack. You can however adjust the size of the stack with engine->SetDefaultContextStackSize().

It might be a better idea to use a set of pooled contexts, so that instead of keeping one context with each object a context is only used when you need to call a script function.

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

Advertisement
i am not using multi-threading.
but i encountered a hang when trying to use asGetActiveContext().

i always had this idea that each context got initialised with the instance of the script and cannot be reuse. so i am wrong.

by reusing contexts, i assume it will not affect the global variables.

btw, how much memory a Context will use by default ?

Interesting. Is the hang consistent? I.e. does it happen every time at the same location? It is possible that it is a bug in the library.

The global variables are stored with the modules, and are only released when the module is discarded.

Each context holds a stack for local function variables. By default the initial stack size is 1KB, and allowed to grow without limit. But you can adjust this by calling engine->SetDefaultContextStackSize(); before preparing the context.

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

wierd thing is that i get an assertion error when trying to use asGetActiveContext() to check for concurrency.

i also got an error of asContext_Active when i tried to prepare a new func to execute.

this happened when the move() calls a c++ code to move the object, but this object collided with another.

this event will call the collide(), and it comes back to the angel script while move() is still halfway.

at this point, the asGetActiveContext() disappeared and it know that both are the same contexts.

how to fix this ?



[Edited by - iram on January 8, 2005 7:07:34 PM]
Not sure what you meant with "trying to use asGetActiveContext() to check for concurrency". When Execute() is called on a context it is pushed on the active context stack, when Execute() returns the context is popped again. Therefore asGetActiveContext() will always return the innermost context that is currently executing.

You will get asCONTEXT_ACTIVE if you are calling Prepare() on a context that hasn't completed the execution first. It would seem that you are reusing contexts, and that you forgot to verify if the context was free to be reused.

Quote:
i have one script tied to a 3d object. each object can appear multiple times in the screen, so each script instance is assigned a context upon creation.


From what you said here, it would seem that you allocate one context for each 3D object. This will cause a conflict when you are executing both move() and collide() on the same object at the same time.

There is really no need to allocate one context for each 3D object. Instead you should use a pool of contexts that are allocated and released as you call script functions.

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

Advertisement
thanks for the suggestion on the context pool.
i'll look into it when i get my old code stable first.

i have a function that checks whether the context i am using now is the active one.

int checkConcurrency(*context) {
if (context == asGetActiveContext())
return (1);

return(0);
}

it will hangs when i call the function.

what i do now is to do a Prepare() with the context.
if i get asCONTEXT_ACTIVE, then i know the context is active.
- then i create a new context for this call
Your function would only return true if the context is the innermost context. It would be better to call GetState() on the context. Which would return one of:

const int asEXECUTION_FINISHED = 0;
const int asEXECUTION_SUSPENDED = 1;
const int asEXECUTION_ABORTED = 2;
const int asEXECUTION_EXCEPTION = 3;
const int asEXECUTION_PREPARED = 4;
const int asEXECUTION_UNINITIALIZED = 5;
const int asEXECUTION_ACTIVE = 6;

The context can be reused for the states 0, 2, 3, 4, and 5.

I think I've figured out why your application hangs when calling asGetActiveContext(). It's my mistake, I forgot to verify if the array is empty before getting the last entry. Please change the implementation of the function in as_context.cpp to:

AS_API asIScriptContext *asGetActiveContext(){	asCThreadLocalData *tld = threadManager.GetLocalData();	if( tld->activeContexts.GetLength() == 0 )		return 0;	return tld->activeContexts[tld->activeContexts.GetLength()-1];}


Thanks for helping me find and eliminate yet another bug in the library.

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