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 🙂

console_pwnage

Peace Out.