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();
}
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") {
if ((lua_gettop(L) != 1) || (lua_type(L, -1) != LUA_TNUMBER)) {
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, place.index());
Gui::store_global_pointer(L, gui);
LS.rawset(LuaRegistry, "actor", actor);
LS.rawset(LuaRegistry, "place", place);
int status = traceback_pcall(L, 2, 0);
LS.rawset(LuaRegistry, "actor", LuaNil);
LS.rawset(LuaRegistry, "place", LuaNil);
Gui::store_global_pointer(L, nullptr);
if (status != 0) {
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.
lua_State *L = state();
LuaVar actor, place, func, tangibles, mt, index, actions, thread, threads, message, invdata;
LuaStack LS(L, 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, thinfo, message, invdata);
// Get the actor and place.
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.
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, actor.index());
lua_pushvalue(L, place.index());
lua_pushvalue(L, invdata.index());
// Move actor, place, function and args to new thread.
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.
LS.rawget(threads, mt, "threads");
if (!LS.istable(threads)) {
LS.result();
return;
}
LS.rawset(threads, tid, thread);
LS.rawset(threads, tid, thinfo);
LS.result();
// 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) {
assert(stack_is_clear());
lua_State *L = state();
LuaVar tangibles, place, mt, threads, thread;
LuaStack LS(L, tangibles, place, mt, threads, thread);
LuaVar tangibles, actor, place, mt, threads, thinfo, isnew, thread;
LuaStack LS(L, tangibles, actor, place, mt, threads, thinfo, isnew, thread);
LS.rawget(tangibles, LuaRegistry, "tangibles");
while (thread_sched_.ready(clk)) {
@@ -450,15 +458,31 @@ void World::run_scheduled_threads(int64_t clk) {
if (!LS.istable(threads)) {
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)) {
continue;
}
// Resume the coroutine.
LS.rawset(thinfo, "isnew", false);
lua_State *CO = LS.ckthread(thread);
int top = lua_gettop(CO);
int status = lua_resume(CO, nullptr, (top >= 4) ? 3 : 0);
LS.rawset(LuaRegistry, "actor", actor);
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.
if (status == LUA_YIELD) {