Added getactor/getplace using registry keys.

This commit is contained in:
2021-10-13 20:32:43 -04:00
parent 5b3f3b7ff0
commit 50d62d9bfd
2 changed files with 50 additions and 11 deletions

View File

@@ -153,6 +153,21 @@ LuaDefine(tangible_id, "c") {
return LS.result(); return LS.result();
} }
LuaDefine(tangible_getactor, "c") {
LuaRet actor;
LuaStack LS(L, actor);
LS.rawget(actor, LuaRegistry, "actor");
return LS.result();
}
LuaDefine(tangible_getplace, "c") {
LuaRet place;
LuaStack LS(L, place);
LS.rawget(place, LuaRegistry, "place");
return LS.result();
}
LuaDefine(world_wait, "f") { LuaDefine(world_wait, "f") {
if ((lua_gettop(L) != 1) || (lua_type(L, -1) != LUA_TNUMBER)) { if ((lua_gettop(L) != 1) || (lua_type(L, -1) != LUA_TNUMBER)) {
luaL_error(L, "Argument to wait must be a number."); luaL_error(L, "Argument to wait must be a number.");

View File

@@ -302,7 +302,11 @@ void World::update_gui(int64_t actor_id, int64_t place_id, Gui *gui) {
lua_pushvalue(L, actor.index()); lua_pushvalue(L, actor.index());
lua_pushvalue(L, place.index()); lua_pushvalue(L, place.index());
Gui::store_global_pointer(L, gui); Gui::store_global_pointer(L, gui);
LS.rawset(LuaRegistry, "actor", actor);
LS.rawset(LuaRegistry, "place", place);
int status = traceback_pcall(L, 2, 0); int status = traceback_pcall(L, 2, 0);
LS.rawset(LuaRegistry, "actor", LuaNil);
LS.rawset(LuaRegistry, "place", LuaNil);
Gui::store_global_pointer(L, nullptr); Gui::store_global_pointer(L, nullptr);
if (status != 0) { if (status != 0) {
gui->clear(); gui->clear();
@@ -361,8 +365,8 @@ void World::invoke_plan(int64_t actor_id, int64_t place_id, const std::string &a
// Set up for Lua manipulation. // Set up for Lua manipulation.
lua_State *L = state(); lua_State *L = state();
LuaVar actor, place, func, tangibles, mt, index, actions, thread, threads, message, invdata; LuaVar actor, place, func, tangibles, mt, index, actions, thread, threads, thinfo, message, invdata;
LuaStack LS(L, actor, place, func, tangibles, mt, index, actions, thread, threads, message, invdata); LuaStack LS(L, actor, place, func, tangibles, mt, index, actions, thread, threads, thinfo, message, invdata);
// Get the actor and place. // Get the actor and place.
LS.rawget(tangibles, LuaRegistry, "tangibles"); LS.rawget(tangibles, LuaRegistry, "tangibles");
@@ -404,22 +408,26 @@ void World::invoke_plan(int64_t actor_id, int64_t place_id, const std::string &a
// Create a new thread, set up function and parameters. // Create a new thread, set up function and parameters.
lua_State *CO = LS.newthread(thread); lua_State *CO = LS.newthread(thread);
// Push the function to be invoked and its arguments. // Move function and args to new thread.
lua_pushvalue(L, func.index()); lua_pushvalue(L, func.index());
lua_pushvalue(L, actor.index()); lua_pushvalue(L, actor.index());
lua_pushvalue(L, place.index()); lua_pushvalue(L, place.index());
lua_pushvalue(L, invdata.index()); lua_pushvalue(L, invdata.index());
// Move actor, place, function and args to new thread.
lua_xmove(L, CO, 4); lua_xmove(L, CO, 4);
// Create the thread info table.
LS.newtable(thinfo);
LS.rawset(thinfo, "thread", thread);
LS.rawset(thinfo, "actor", actor);
LS.rawset(thinfo, "isnew", true);
// Store the thread into place's thread table. // Store the thread into place's thread table.
LS.rawget(threads, mt, "threads"); LS.rawget(threads, mt, "threads");
if (!LS.istable(threads)) { if (!LS.istable(threads)) {
LS.result(); LS.result();
return; return;
} }
LS.rawset(threads, tid, thread); LS.rawset(threads, tid, thinfo);
LS.result(); LS.result();
// Push the thread's ID into the runnable thread queue, // Push the thread's ID into the runnable thread queue,
@@ -432,8 +440,8 @@ void World::invoke_plan(int64_t actor_id, int64_t place_id, const std::string &a
void World::run_scheduled_threads(int64_t clk) { void World::run_scheduled_threads(int64_t clk) {
assert(stack_is_clear()); assert(stack_is_clear());
lua_State *L = state(); lua_State *L = state();
LuaVar tangibles, place, mt, threads, thread; LuaVar tangibles, actor, place, mt, threads, thinfo, isnew, thread;
LuaStack LS(L, tangibles, place, mt, threads, thread); LuaStack LS(L, tangibles, actor, place, mt, threads, thinfo, isnew, thread);
LS.rawget(tangibles, LuaRegistry, "tangibles"); LS.rawget(tangibles, LuaRegistry, "tangibles");
while (thread_sched_.ready(clk)) { while (thread_sched_.ready(clk)) {
@@ -450,15 +458,31 @@ void World::run_scheduled_threads(int64_t clk) {
if (!LS.istable(threads)) { if (!LS.istable(threads)) {
continue; continue;
} }
LS.rawget(thread, threads, sched.thread_id()); LS.rawget(thinfo, threads, sched.thread_id());
if (!LS.istable(thinfo)) {
continue;
}
LS.rawget(actor, thinfo, "actor");
if (!LS.istable(actor)) {
continue;
}
LS.rawget(isnew, thinfo, "isnew");
if (!LS.isboolean(isnew)) {
continue;
}
LS.rawget(thread, thinfo, "thread");
if (!LS.isthread(thread)) { if (!LS.isthread(thread)) {
continue; continue;
} }
// Resume the coroutine. // Resume the coroutine.
LS.rawset(thinfo, "isnew", false);
lua_State *CO = LS.ckthread(thread); lua_State *CO = LS.ckthread(thread);
int top = lua_gettop(CO); LS.rawset(LuaRegistry, "actor", actor);
int status = lua_resume(CO, nullptr, (top >= 4) ? 3 : 0); LS.rawset(LuaRegistry, "place", place);
int status = lua_resume(CO, nullptr, LS.ckboolean(isnew) ? 3 : 0);
LS.rawset(LuaRegistry, "actor", LuaNil);
LS.rawset(LuaRegistry, "place", LuaNil);
// Three possible outcomes: finished, yielded, or errored. // Three possible outcomes: finished, yielded, or errored.
if (status == LUA_YIELD) { if (status == LUA_YIELD) {