Change the creation/deletion of tangibles so that the tangible database is never really deleted.

This commit is contained in:
2023-03-16 23:31:29 -04:00
parent 86a27ef2d4
commit a8c780563f
9 changed files with 152 additions and 90 deletions

View File

@@ -134,14 +134,16 @@ World::TanVector World::tangible_get_all(const IdVector &ids) const {
return result;
}
Tangible *World::tangible_get(const LuaStack &LS, LuaSlot tab) {
Tangible *World::tangible_get(const LuaStack &LS, LuaSlot tab, bool allowdel) {
int64_t id = LS.tanid(tab);
if (id == 0) {
luaL_error(LS.state(), "parameter is not a tangible");
}
Tangible *result = tangible_get(id);
if (result == nullptr) {
luaL_error(LS.state(), "parameter is not a tangible");
if (!allowdel) {
if (result == nullptr) {
luaL_error(LS.state(), "argument is a deleted tangible, which is not allowed here");
}
}
return result;
}
@@ -154,9 +156,9 @@ Tangible *World::tangible_make(lua_State *L, int64_t id, const eng::string &plan
}
assert(id != 0);
LuaVar tangibles, metatab;
LuaVar metatab;
LuaRet database;
LuaStack LS(L, tangibles, database, metatab);
LuaStack LS(L, database, metatab);
// Create the C++ part of the structure.
UniqueTangible &t = tangibles_[id];
@@ -167,25 +169,14 @@ Tangible *World::tangible_make(lua_State *L, int64_t id, const eng::string &plan
t->anim_queue_.clear(plane);
t->update_plane_item();
// Create the tangible's database and metatable.
LS.set(database, LuaNewTable);
LS.set(metatab, LuaNewTable);
LS.setmetatable(database, metatab);
// Fetch the tangible's Lua database and metatable.
LS.maketan(database, id);
LS.getmetatable(metatab, database);
// Mark the tangible using the tabletype field.
LS.settabletype(database, LUA_TT_TANGIBLE);
LS.settabletype(metatab, LUA_TT_TANGIBLEMETA);
// Store the database into the tangibles table.
LS.rawget(tangibles, LuaRegistry, "tangibles");
LS.rawset(tangibles, id, database);
// Populate the database and metatable with initial stuff.
// Set up the inventory and thread table.
LS.rawset(database, "inventory", LuaNewTable);
LS.rawset(metatab, "id", id);
LS.rawset(metatab, "threads", LuaNewTable);
// LS.rawset(metatab, "__metatable", LuaNil);
LS.result();
if (!pushdb) lua_pop(L, 1);
return t.get();
@@ -193,8 +184,8 @@ Tangible *World::tangible_make(lua_State *L, int64_t id, const eng::string &plan
void World::tangible_delete(int64_t id) {
lua_State *L = state();
LuaVar tangibles, database;
LuaStack LS(L, tangibles, database);
LuaVar tangibles, database, metatab;
LuaStack LS(L, tangibles, database, metatab);
// Fetch the C++ side of the tangible.
auto iter = tangibles_.find(id);
@@ -204,16 +195,17 @@ void World::tangible_delete(int64_t id) {
}
// Fetch the lua side of the tangible.
LS.rawget(tangibles, LuaRegistry, "tangibles");
LS.rawget(database, tangibles, id);
LS.maketan(database, id);
assert(LS.istable(database));
// Clear out the database.
LS.cleartable(database, true);
LS.settabletype(database, LUA_TT_DEADTANGIBLE);
LS.getmetatable(metatab, database);
// Remove the lua portion from the tangibles table.
LS.rawset(tangibles, id, LuaNil);
// Clear out the database and the metatable.
LS.cleartable(database, false);
LS.cleartable(metatab, true);
// Now put the bare minimum info back into the metatable.
LS.rawset(metatab, "id", id);
LS.rawset(metatab, "__metatable", false);
// Remove the C++ portion from the tangibles table.
tangibles_.erase(iter);