lua-users home
lua-l archive

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


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()