diff options
| author | Alexander Gavrilov | 2012-04-16 18:05:42 +0400 |
|---|---|---|
| committer | Alexander Gavrilov | 2012-04-16 18:05:42 +0400 |
| commit | 1e64a6a2f623a6f6a3ce1b0b10ccfe40acbcdde4 (patch) | |
| tree | 78128cabdc114527b0755bbf6b16e5f9d1cd6635 /library/LuaTools.cpp | |
| parent | 9c253512818adc0b36f5a32b8be499dcf65f34a2 (diff) | |
| download | dfhack-1e64a6a2f623a6f6a3ce1b0b10ccfe40acbcdde4.tar.gz dfhack-1e64a6a2f623a6f6a3ce1b0b10ccfe40acbcdde4.tar.bz2 dfhack-1e64a6a2f623a6f6a3ce1b0b10ccfe40acbcdde4.tar.xz | |
Make dfhack.lineedit automatically interact with RunCoreQueryLoop.
It still falls back to the original waiting mode if yield fails.
Diffstat (limited to 'library/LuaTools.cpp')
| -rw-r--r-- | library/LuaTools.cpp | 62 |
1 files changed, 55 insertions, 7 deletions
diff --git a/library/LuaTools.cpp b/library/LuaTools.cpp index 993efa74..be4fa864 100644 --- a/library/LuaTools.cpp +++ b/library/LuaTools.cpp @@ -240,15 +240,14 @@ static int lua_dfhack_is_interactive(lua_State *S) return 1; } -static int lua_dfhack_lineedit(lua_State *S) +static int dfhack_lineedit_sync(lua_State *S, Console *pstream) { - const char *prompt = luaL_optstring(S, 1, ">> "); - const char *hfile = luaL_optstring(S, 2, NULL); - - Console *pstream = get_console(S); if (!pstream) return 2; + const char *prompt = luaL_optstring(S, 1, ">> "); + const char *hfile = luaL_optstring(S, 2, NULL); + DFHack::CommandHistory hist; if (hfile) hist.load(hfile); @@ -271,6 +270,47 @@ static int lua_dfhack_lineedit(lua_State *S) } } +static int DFHACK_QUERY_COROTABLE_TOKEN = 0; + +static int yield_helper(lua_State *S) +{ + return lua_yield(S, lua_gettop(S)); +} + +namespace { + int dfhack_lineedit_cont(lua_State *L, int status, int) + { + if (Lua::IsSuccess(status)) + return lua_gettop(L) - 2; + else + return dfhack_lineedit_sync(L, get_console(L)); + } +} + +static int dfhack_lineedit(lua_State *S) +{ + lua_settop(S, 2); + + Console *pstream = get_console(S); + if (!pstream) + return 2; + + lua_rawgetp(S, LUA_REGISTRYINDEX, &DFHACK_QUERY_COROTABLE_TOKEN); + lua_rawgetp(S, -1, S); + bool in_coroutine = !lua_isnil(S, -1); + lua_settop(S, 2); + + if (in_coroutine) + { + lua_pushcfunction(S, yield_helper); + lua_pushvalue(S, 1); + lua_pushvalue(S, 2); + return Lua::TailPCallK<dfhack_lineedit_cont>(S, 2, LUA_MULTRET, 0, 0); + } + + return dfhack_lineedit_sync(S, pstream); +} + /* * Exception handling */ @@ -796,10 +836,12 @@ bool DFHack::Lua::RunCoreQueryLoop(color_ostream &out, lua_State *state, return false; } + lua_rawgetp(state, LUA_REGISTRYINDEX, &DFHACK_QUERY_COROTABLE_TOKEN); lua_pushvalue(state, base+1); lua_remove(state, base+1); thread = Lua::NewCoroutine(state); - lua_rawsetp(state, LUA_REGISTRYINDEX, thread); + lua_rawsetp(state, -2, thread); + lua_pop(state, 1); rv = resume_query_loop(out, thread, state, lua_gettop(state)-base, prompt, histfile); } @@ -839,8 +881,10 @@ bool DFHack::Lua::RunCoreQueryLoop(color_ostream &out, lua_State *state, { CoreSuspender suspend; + lua_rawgetp(state, LUA_REGISTRYINDEX, &DFHACK_QUERY_COROTABLE_TOKEN); lua_pushnil(state); - lua_rawsetp(state, LUA_REGISTRYINDEX, thread); + lua_rawsetp(state, -2, thread); + lua_pop(state, 1); } return (rv == LUA_OK); @@ -1180,6 +1224,10 @@ lua_State *DFHack::Lua::Open(color_ostream &out, lua_State *state) luaL_openlibs(state); AttachDFGlobals(state); + // Table of query coroutines + lua_newtable(state); + lua_rawsetp(state, LUA_REGISTRYINDEX, &DFHACK_QUERY_COROTABLE_TOKEN); + // Replace the print function of the standard library lua_pushcfunction(state, lua_dfhack_println); lua_setglobal(state, "print"); |
