I have been using AngelScript in my engine for a while and now I'm trying out its multithreading capabilities. There's not much documentation on this subject, so I'm struggling a bit. I'm trying to acheive a variable amount of threads, maybe 2 or 3, to be used to execute multiple scripts at a given time. The documentation says more than one engine can be used right? Can I only use one? Has anybody had any luck with multithreading with angelscript and does anyone have any sample code available?
I'm trying to keep it as simple as possible:
This is my execution function that my threads call:
int threadExecuteContext( void *data)
{
asIScriptContext *ctx = (asIScriptContext*)data;
int r = ctx->Execute();
if (r != asEXECUTION_FINISHED)
{
if (r == asEXECUTION_EXCEPTION)
std::cout << "An exception occurred while executing function on thread id " << SDL_ThreadID() << "." << std::endl;
if (r == asEXECUTION_ERROR)
std::cout << "An error occurred while executing function on thread id " << SDL_ThreadID() << "." << std::endl;
return asERROR;
}
else
{
ctx->Unprepare();
}
return 0;
}
This one prepares a function to be called and waits for a available thread:
int ScriptManager::ExecuteFunction( asIScriptFunction *func, asIScriptObject *obj)
{
asIScriptContext *ctx = GetContext();
if (ctx == NULL)
return asERROR;
if (ctx->Prepare( func) < 0)
{
std::cout << "Could not prepare script function" << std::endl;
return asERROR;
}
ctx->SetObject( obj);
SDL_Thread *th = NULL;
while (th == NULL)
th = GetThread( ctx);
return asSUCCESS;
}
And lastly here is my GetThread function. It maintains the maximum thread limit by waiting for one to finish:
SDL_Thread *ScriptManager::GetThread( asIScriptContext *ctx)
{
SDL_Thread *th = NULL;
if (threads.size() < MAX_THREADS)
{
th = SDL_CreateThread( threadExecuteContext, "Script Execution Thread", ctx);
threads.push_back( th);
}
else
{
int returned;
thread_iterator it = threads.begin();
SDL_WaitThread( *it, &returned);
threads.erase( it);
th = SDL_CreateThread( threadExecuteContext, "Script Execution Thread", ctx);
threads.push_back( th);
}
return th;
}
This method has problems. The context always has an unintialized state and does not execute anything.