Create a coroutine to run plans
This commit is contained in:
@@ -120,6 +120,7 @@ Tangible *World::tangible_make(lua_State *L, int64_t id, bool pushdb) {
|
||||
LS.rawset(database, "inventory", LuaNewTable);
|
||||
LS.rawset(database, "id", id);
|
||||
LS.rawset(metatab, "id", id);
|
||||
LS.rawset(metatab, "threads", LuaNewTable);
|
||||
// LS.rawset(metatab, "__metatable", LuaNil);
|
||||
|
||||
LS.result();
|
||||
@@ -202,8 +203,8 @@ void World::invoke_plan(int64_t actor_id, int64_t place_id, const std::string &a
|
||||
|
||||
lua_State *L = state();
|
||||
|
||||
LuaVar actor, place, ugui, func, tangibles, mt, index, actions;
|
||||
LuaStack LS(L, actor, place, ugui, func, tangibles, mt, index, actions);
|
||||
LuaVar actor, place, ugui, func, tangibles, mt, index, actions, thread, message;
|
||||
LuaStack LS(L, actor, place, ugui, func, tangibles, mt, index, actions, thread, message);
|
||||
|
||||
// Get the actor and place.
|
||||
LS.rawget(tangibles, LuaRegistry, "tangibles");
|
||||
@@ -239,17 +240,28 @@ void World::invoke_plan(int64_t actor_id, int64_t place_id, const std::string &a
|
||||
// Construct the userdata with the GUI pointer.
|
||||
LS.newpointer<Gui>(ugui, gui, false);
|
||||
|
||||
// Call the action function.
|
||||
// Create a new thread, set up function and parameters.
|
||||
lua_State *CO = LS.newthread(thread);
|
||||
lua_pushvalue(L, func.index());
|
||||
lua_pushvalue(L, actor.index());
|
||||
lua_pushvalue(L, place.index());
|
||||
lua_pushvalue(L, ugui.index());
|
||||
int status = traceback_pcall(L, 3, 0);
|
||||
if (status != 0) {
|
||||
gui->clear();
|
||||
lua_xmove(L, CO, 4);
|
||||
|
||||
// Resume the new coroutine.
|
||||
int status = lua_resume(CO, 3);
|
||||
|
||||
// Three possible outcomes: finished, yielded, or errored.
|
||||
if (status == LUA_YIELD) {
|
||||
// Yield not implemented yet. The coroutine is simply dropped.
|
||||
std::cerr << "Thread yield not implemented yet." << std::endl;
|
||||
} else if (status == 0) {
|
||||
// Successfully ran to completion.
|
||||
std::cerr << "Thread ran to completion." << std::endl;
|
||||
} else {
|
||||
// Transfer the error message from CO to L, and add a traceback.
|
||||
traceback_coroutine(L, CO);
|
||||
std::cerr << lua_tostring(L, -1);
|
||||
LS.result();
|
||||
return;
|
||||
}
|
||||
|
||||
// Nuke the userdata, in case somebody saved a pointer to it.
|
||||
|
||||
Reference in New Issue
Block a user