[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Turning an entire script into a coroutine
- From: Michael Abbott <mabster@...>
- Date: Sun, 20 Feb 2005 02:16:58 +1100
I've continued (albeit with very little time to do so) playing around
with initiating an entire script as a coroutine and I think I've made
some headway. I've ended up with the code below the message, and this
appears to all work for now. In the code snippet, the pBaseScript will
be the class of each script (ie. player.lua, alien.lua, boss.lua, etc.
will each have a corresponding pBaseScript). The pThreadScript will
represent an instance of a class of script (every game entity with have
a pThreadScript associated with it). At least, that's how I hope it
will turn out.
At the moment, this appears to work. I'm pretty sure it's a stack of
cards now because of the LUA_TTHREAD still hanging around on the
pBaseScript stack. That is, I assume that the gc would would throw away
the thread if that LUA_TTHREAD were to get discarded. If this is the
case, I need to store this thread value somewhere on the lua end without
the lua script itself having access to it. Is this possible? Or is
there some way of storing lua values on the C end without them getting gc'd?
Oh, and I realise my usage of the lua stack leaves a lot to be desired,
I'm doing this all a step at a time so I can understand each bit as a
logical unit :-)
Ta!,
- Mab
<----------------------------------
C++
---------------------------------->
extern "C" {
#include "lauxlib.h"
#include "lua.h"
#include "lualib.h"
}
#include <assert.h>
int main()
{
// Setup a base script (this will hold the script in it's
non-threaded form)
lua_State* pBaseScript = lua_open();
assert(pBaseScript);
// Setup the base libraries we will use
static const luaL_reg s_luaLibraries[] =
{
{ "base", luaopen_base },
{ "io", luaopen_io }
};
enum { NUM_LIBRARIES = sizeof(s_luaLibraries) /
sizeof(*s_luaLibraries) };
// Install them
for (int nLibrary = 0; nLibrary < NUM_LIBRARIES; ++nLibrary)
{
s_luaLibraries[nLibrary].func(pBaseScript);
lua_settop(pBaseScript, 0); // flush results of library call
}
// Load in the base script // BASE SCRIPT | THREAD
int nError = luaL_loadfile(pBaseScript, "source/player.lua"); //
{ func } | { }
assert(!nError);
// Create a thread, and setup the base script function as the coroutine
lua_State* pThreadScript = lua_newthread(pBaseScript);
// { func thread } | { }
assert(pThreadScript);
lua_pushvalue(pBaseScript, 1);
// { func thread func } |
lua_xmove(pBaseScript, pThreadScript, 1);
// { func thread } | { func }
for (;;)
{
nError = lua_resume(pThreadScript, 0);
// { thread } | { }
assert(!nError);
}
// Return (NOTE: we will never get here)
return 0;
}
<----------------------------------
player.lua
---------------------------------->
local f = io.open("lua.txt", "wt")
f:write("1\n") f:flush()
function player_idle()
f:write("2\n") f:flush()
repeat
f:write("3\n") f:flush()
coroutine.yield()
f:write("4\n") f:flush()
until true
while true do
f:write("5\n") f:flush()
coroutine.yield()
f:write("6\n") f:flush()
end
f:write("7\n") f:flush()
end
player_idle()