Jump to content

  • Log In with Google      Sign In   
  • Create Account

Interested in a FREE copy of HTML5 game maker Construct 2?

We'll be giving away three Personal Edition licences in next Tuesday's GDNet Direct email newsletter!

Sign up from the right-hand sidebar on our homepage and read Tuesday's newsletter for details!


#Actualjustin12343

Posted 20 July 2013 - 12:35 PM

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.


#1justin12343

Posted 20 July 2013 - 11:53 AM

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 on 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:

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.


PARTNERS