lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


It might not be suitable for you, but I just want to take this opportunity to plug my new multi-tasking library, it would do this pretty cleanly and bring a lot more options to the table- http://northarc.com/tuna

email me off-list if you have any questions, I'm still anxious to get feedback on it.

-Curt

On 2/1/2012 3:04 PM, Dmitry Marakasov wrote:
Hi!

I want lua code to be running as a single coroutine. For example,
imagine C/C++ GUI application with logic written in lua. GUI event
loop runs in C/C++, and lua code needs to drop back to it when it
needs input from the user (it can't get user input by calling C/C++
function, as this would not resume event loop). I'm trying to use a
single lua coroutine for it, but I'm confused about whether I can
call lua_resume on a lua_State returned by lua_open, not lua_newthread,
cause lua_resume documentation says "To start a coroutine, you first
create a new thread".

This test code works, but I want to be sure that there is no errors
or undefined behaviour in it:

---
#include<lua.h>
#include<lualib.h>
#include<lauxlib.h>

#include<stdio.h>
#include<assert.h>

int my_func(lua_State* lua) {
	fprintf(stderr, "[LUA] Hello from lua!\n");
	return 0;
}

int my_yield(lua_State* lua) {
	fprintf(stderr, "[LUA] Now yielding...\n");
	return lua_yield(lua, 0);
}

int main() {
	int ret;

	/* create lua state */
	lua_State* lua = lua_open();
	assert(lua != NULL);

	/* register own lua functions */
	lua_register(lua, "my_func", my_func);
	lua_register(lua, "my_yield", my_yield);

	/* load lua code */
	ret = luaL_dostring(lua, "function main() my_func(\"Hello, world!\"); my_yield(); for i = 1,9 do my_func(i); if i % 3 == 0 then my_yield(); end end my_yield(); my_func(\"Bye!\"); end");
	assert(ret == 0);

	/* push lua main() function onto the stack */
	lua_getglobal(lua, "main");

	/* main loop which runs "in parallel" to lua main(), switching back and forth */
	fprintf(stderr, "[ C ] Starting mainloop...\n");
	while (1) {
		fprintf(stderr, "[ C ] Running/resuming lua...\n");
		ret = lua_resume(lua, 0);

		if (ret == LUA_YIELD) {
			fprintf(stderr, "[ C ] Lua has yielded!\n");
		} else if (ret == 0) {
			fprintf(stderr, "[ C ] Lua has finished!\n");
			break;
		} else {
			assert(0); /* something gone wrong */
		}

		fprintf(stderr, "[ C ] Hello from C!\n");
	}

	fprintf(stderr, "[ C ] We're done!\n");

	lua_close(lua);
	return 0;
}
---