static int read_persistent(lua_State *state, PersistentDataItem ref, bool create) { if (!ref.isValid()) { lua_pushnil(state); lua_pushstring(state, "entry not found"); return 2; } if (create) lua_createtable(state, 0, 4); lua_pushvalue(state, lua_upvalueindex(1)); lua_setmetatable(state, -2); lua_pushinteger(state, ref.entry_id()); lua_setfield(state, -2, "entry_id"); lua_pushstring(state, ref.key().c_str()); lua_setfield(state, -2, "key"); lua_pushstring(state, ref.val().c_str()); lua_setfield(state, -2, "value"); lua_createtable(state, PersistentDataItem::NumInts, 0); for (int i = 0; i < PersistentDataItem::NumInts; i++) { lua_pushinteger(state, ref.ival(i)); lua_rawseti(state, -2, i+1); } lua_setfield(state, -2, "ints"); return 1; }
static int dfhack_persistent_save(lua_State *state) { CoreSuspender suspend; lua_settop(state, 2); luaL_checktype(state, 1, LUA_TTABLE); bool add = lua_toboolean(state, 2); lua_getfield(state, 1, "key"); const char *str = lua_tostring(state, -1); if (!str) luaL_argerror(state, 1, "no key field"); lua_settop(state, 1); // Retrieve existing or create a new entry PersistentDataItem ref; bool added = false; if (add) { ref = Core::getInstance().getWorld()->AddPersistentData(str); added = true; } else if (lua_getmetatable(state, 1)) { if (!lua_rawequal(state, -1, lua_upvalueindex(1))) return luaL_argerror(state, 1, "invalid table type"); lua_pop(state, 1); ref = persistent_by_struct(state, 1); } else { ref = Core::getInstance().getWorld()->GetPersistentData(str); } // Auto-add if not found if (!ref.isValid()) { ref = Core::getInstance().getWorld()->AddPersistentData(str); if (!ref.isValid()) luaL_error(state, "cannot create persistent entry"); added = true; } // Copy data from lua to C++ memory lua_getfield(state, 1, "value"); if (const char *str = lua_tostring(state, -1)) ref.val() = str; lua_pop(state, 1); lua_getfield(state, 1, "ints"); if (lua_istable(state, -1)) { for (int i = 0; i < PersistentDataItem::NumInts; i++) { lua_rawgeti(state, -1, i+1); if (lua_isnumber(state, -1)) ref.ival(i) = lua_tointeger(state, -1); lua_pop(state, 1); } } lua_pop(state, 1); // Reinitialize lua from C++ and return read_persistent(state, ref, false); lua_pushboolean(state, added); return 2; }
void init(const std::string &str) { config.val() = str; config.ival(2) = 0; }