Redesigned ID allocator and tangible.actor

This commit is contained in:
2021-10-14 11:43:16 -04:00
parent 50d62d9bfd
commit 796a3c4139
6 changed files with 131 additions and 126 deletions

View File

@@ -47,6 +47,9 @@ World::World(util::WorldType wt) {
// Clear the global GUI pointer.
Gui::store_global_pointer(state(), nullptr);
// Clear the lthread state.
set_lthread_state(0, 0, false);
// Set the tabletype of the registry.
LS.settabletype(LuaRegistry, LUA_TT_REGISTRY);
@@ -151,14 +154,12 @@ Tangible *World::tangible_make(lua_State *L, int64_t id, const std::string &plan
L = state();
assert(!pushdb);
}
assert(id != 0);
LuaVar tangibles, metatab;
LuaRet database;
LuaStack LS(L, tangibles, database, metatab);
// Allocate an ID if we don't already have one.
if (id == 0) id = id_global_pool_.alloc_id_for_thread(L);
// Create the C++ part of the structure.
std::unique_ptr<Tangible> &t = tangibles_[id];
assert (t == nullptr);
@@ -250,7 +251,8 @@ World::Redirects World::fetch_redirects() {
}
int64_t World::create_login_actor() {
Tangible *tan = tangible_make(state(), 0, "nowhere", true);
int64_t id = id_global_pool_.get_one();
Tangible *tan = tangible_make(state(), id, "nowhere", true);
LuaArg database;
LuaVar classtab, mt;
LuaStack LS(state(), database, classtab, mt);
@@ -302,11 +304,9 @@ 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);
set_lthread_state(actor_id, place_id, false);
int status = traceback_pcall(L, 2, 0);
LS.rawset(LuaRegistry, "actor", LuaNil);
LS.rawset(LuaRegistry, "place", LuaNil);
set_lthread_state(0, 0, false);
Gui::store_global_pointer(L, nullptr);
if (status != 0) {
gui->clear();
@@ -359,9 +359,9 @@ void World::invoke_plan(int64_t actor_id, int64_t place_id, const std::string &a
return;
}
// Get an ID batch for the thread, and take one for the thread itself.
int64_t id_batch = tactor->id_player_pool_.get_batch();
int64_t tid = id_batch++;
// Get an ID for the thread. We always use the player
// pool in this case.
int64_t tid = tactor->id_player_pool_.get_one();
// Set up for Lua manipulation.
lua_State *L = state();
@@ -418,8 +418,9 @@ void World::invoke_plan(int64_t actor_id, int64_t place_id, const std::string &a
// Create the thread info table.
LS.newtable(thinfo);
LS.rawset(thinfo, "thread", thread);
LS.rawset(thinfo, "actor", actor);
LS.rawset(thinfo, "actorid", actor_id);
LS.rawset(thinfo, "isnew", true);
LS.rawset(thinfo, "useppool", true);
// Store the thread into place's thread table.
LS.rawget(threads, mt, "threads");
@@ -440,8 +441,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, actor, place, mt, threads, thinfo, isnew, thread;
LuaStack LS(L, tangibles, actor, place, mt, threads, thinfo, isnew, thread);
LuaVar tangibles, place, mt, threads, thinfo, actorid, isnew, useppool, thread;
LuaStack LS(L, tangibles, place, mt, threads, thinfo, actorid, isnew, useppool, thread);
LS.rawget(tangibles, LuaRegistry, "tangibles");
while (thread_sched_.ready(clk)) {
@@ -462,27 +463,28 @@ void World::run_scheduled_threads(int64_t clk) {
if (!LS.istable(thinfo)) {
continue;
}
LS.rawget(actor, thinfo, "actor");
if (!LS.istable(actor)) {
LS.rawget(actorid, thinfo, "actorid");
if (!LS.isnumber(actorid)) {
continue;
}
LS.rawget(isnew, thinfo, "isnew");
if (!LS.isboolean(isnew)) {
continue;
}
LS.rawget(useppool, thinfo, "useppool");
if (!LS.isboolean(useppool)) {
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);
LS.rawset(LuaRegistry, "actor", actor);
LS.rawset(LuaRegistry, "place", place);
set_lthread_state(LS.ckinteger(actorid), sched.place_id(), LS.ckboolean(useppool));
int status = lua_resume(CO, nullptr, LS.ckboolean(isnew) ? 3 : 0);
LS.rawset(LuaRegistry, "actor", LuaNil);
LS.rawset(LuaRegistry, "place", LuaNil);
set_lthread_state(0, 0, false);
// Three possible outcomes: finished, yielded, or errored.
if (status == LUA_YIELD) {
@@ -493,6 +495,8 @@ void World::run_scheduled_threads(int64_t clk) {
} else {
lua_Number delay = lua_tonumber(CO, 1);
lua_settop(CO, 0);
LS.rawset(thinfo, "isnew", false);
LS.rawset(thinfo, "useppool", false);
std::cerr << "Thread wait = " << delay << std::endl;
thread_sched_.add(sched.clock() + int64_t(delay), sched.thread_id(), sched.place_id());
std::cerr << "Added to schedule." << std::endl;
@@ -512,6 +516,23 @@ void World::run_scheduled_threads(int64_t clk) {
assert(stack_is_clear());
}
int64_t World::alloc_id_predictable() {
if (!lthread_use_ppool_) {
return id_global_pool_.get_one();
}
Tangible *t = tangible_get(lthread_actor_id_);
if (t == nullptr) {
return id_global_pool_.get_one();
}
return t->id_player_pool_.get_one();
}
void World::set_lthread_state(int64_t actor, int64_t place, bool ppool) {
lthread_actor_id_ = actor;
lthread_place_id_ = place;
lthread_use_ppool_ = ppool;
}
void World::serialize(StreamBuffer *sb) {
assert(stack_is_clear());
assert(redirects_.empty());