spawn help

Started by
3 comments, last by wadetb 17 years, 9 months ago
Hey all, I'm working on a new side project engine based around AngelScript, and am wondering what the best way is to go about implementing a proper spawn. void soundoff(float timer, string msg) { sleep(timer); say(msg); } void main() { spawn soundoff(1.0, "hello1"); spawn soundoff(2.0, "hello1"); spawn soundoff(3.0, "hello1"); } The spawn operator creates a new script context, prepares it to run soundoff, and pushes the arguments passed to soundoff onto the new context's stack, and finally invokes an application-side callback with the new context (so that it may be registered with threads engine). So, the spawn operator can be thought of as a modifier to the function call. Instead of executing in the current context, it should be executed in a new one. Can anyone give me some pointers as to how this should best be implemented? FWIW, at the moment I'm hacking it with a spawn(string) function. The string argument is compiled and executed in a new context. Problems with this: - Inefficient because the compiler has to be invoked - Errors are caught at runtime instead of compile time - Worst of all, in order to pass variables as arguments I have to do string formatting. Thanks, -Wade
Advertisement
My wrapper library can do this, though I'm not certain the version I have available right now is fully functional (My current project doesn't use angelscript at all, so I'm not working with it at the moment).

I identified script functions with the combination 'filename:function'. My system is a little different, though, because all my functions had zero paremeters (My system didn't actually allow the spawning of a random script function from angelscript itself; but the spawning of entities which each had their own script context.)

From inside C++, it's a single function call to spawn some function on a given entity. It looks like this.

sil::Thread sil::Script::spawn_process(const std::string& function, sil::AnyList& parameters, sil::Any thread_data){	if (!good_module) return Thread(0);	std::string signature = "void ";	signature += function + "(";	for (std::list<Any>::iterator I = parameters.begin(); I != parameters.end(); ++I)	{		if (I != parameters.begin()) signature += ",";		signature += I->script_typename();	}	signature += ")";	int func_id = fetch_function(signature);	if (func_id == -1) return Thread(0);	Thread r(new c_Thread(func_id,SCI,thread_data));	int a_id = 0;	for (std::list<Any>::iterator I = parameters.begin(); I != parameters.end(); ++I, ++a_id)		r->set_argument(a_id,*I);	r->start();	threads.push_back(r);	return r;}
instead of recompiling a script you could precompile the whole functions, then when u need to spawn, you can use a "void spawn (const string& funcName)" that creates a temporary context and executes the function called "funcName" that has already be compiled. obviously you have to find a way to pass dynamic parameters...
My suggestion is already implemented in the 'coroutine' sample available in the sdk. That sample solves it like this:

class ThreadArg                            {                                            int count;                                 string str;                              };                                         void main()                                {                                            for(;;)                                    {                                            int count = 10;                            ThreadArg a;                               a.count = 3;                               a.str = " B";                            CreateCoRoutine("thread2", any(@a));     while( count-- > 0 )                       {                                            Print("A :" + count + "\n");          Yield();                                 }                                        }                                        }                                          void thread2(any &in arg)                  {                                            ThreadArg @a;                              arg.retrieve(@a);                          int count = a.count;                       string str = a.str;                        while( count-- > 0 )                       {                                            Print(str + ":" + count + "\n");     Yield();                                 }                                        }                                          


In your case you'll need a slightly different context manager than what is used in that sample, as you want independent threads instead of co-routines. But the spawning of new threads could work just the same way. Actually the context manager from the 'concurrent' sample may be just what you need.

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

Thanks for the suggestions, everyone - the arguments are indeed the hard part.

Unfortunately, the proposed syntax is not what I'm looking for. It's much too complicated for the designers to work with, when the concept of threads is tricky enough to master.

I'll just implement it myself as a patch.

Regards,

-Wade

This topic is closed to new replies.

Advertisement