Lua threads and stuff
by M_D_K
OK for the lulz I’m making this post. Its about setting up Lua threads, yielding them, and messing around with them. First, What benefit do you get from using threads? You get to run multiple scripts at once, and you get persistent memory; So say you need to keep score in a script, if you weren’t using threads your score would keep resetting every run.
What you’ll need:
- A project with a lua implementation – I’m not covering this…right now
- A basic knowledge of the Lua API
- An IQ above the practical value of a constant NULL pointer
OK so you want to have several Lua scripts running at the same time all with they’re own heartbeat. Well your gonna need threads or as its known in the scripting scene a coroutine.
You create a coroutine with the function lua_newthread here is an example:
lua_State *thread = lua_newthread(MainState);//MainState is just a standard lua_State
So to create a thread you need a state, good thing is you can create as many threads on a state as you want. By the way that ain’t all you need to do, you also need to add to the main state, give it its own global index, etc so more code 🙂
lua_State *CreateThread() { lua_State *thread = lua_newthread(MainState); //making the stuff lua_newtable(thread); lua_newtable(thread); lua_pushliteral(thread, "__index"); lua_pushvalue(thread, LUA_GLOBALSINDEX); lua_settable(thread, -3); lua_setmetatable(thread, -2); lua_replace(thread, LUA_GLOBALSINDEX); return thread; };
So know you have a thread ready to run, but nothings loaded into it, so just use the function luaL_dofile that will load it and get ready to run. You use use lua_resume to start up a yielded thread.
int res = lua_resume(L, 0);
Oh that reminds me how to yield a thread. First do this:
int LuaYield(lua_State *L) { return lua_yield(L, 1); }; [...somewhere after loading libs into MainState...] lua_register(MainState, "yield", LuaYield);
Now in a script you can yield an infinate loop with yield(). Nice right?
anyway a test script:
count = 0 while 1 do count = count + 1; print("Count:", count); yield(); end
So yeah what do you have when your done…this if you copied and pasted
//stuffs missing so that you actually need to know what your doing int main(int argc, char *argv[]) { lua_State *myThread = CreateThread(); luaL_dofile(L, "myscript.lua"); while(1) { //put exit checking here like if(Input::GetSingleton().keyDown(SDLK_ESCAPE) == true) break; lua_resume(myThread, 0); } lua_close(L); return 0; };
So if you managed to get anything out of this congratulations. This should give you an idea of to use threads in Lua. OK so I can’t be assed showing how to mess with them, I’ll do it next post. Its pretty cool I made it so my ingame console patch into any thread I want and execute anything, also I can modify objects owned by the thread. Here is a pic 🙂
Peace Out.
sweet! you are now officially demi-god status with me!
Yay I’m a demi-god 🙂
This works better replacing line number 5:
05 luaL_loadfile(L, “myscript.lua”);
Explanation:
“luaL_dofile” performs a “lua_pcall” that will eventualy return an error when “myscript.lua” comes to yield.
Having a specific function to do “lua_yield()” is not even necessary. A call to “coroutine.yield()” can be used in pure LUA instead.
This, using LUA 5.1 had worked for me. Thanks for the tip. ^_^