Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add the API code to know when the last save was. #5203

Merged
merged 10 commits into from
Jan 16, 2025
4 changes: 4 additions & 0 deletions docs/dev/Lua API.rst
Original file line number Diff line number Diff line change
Expand Up @@ -771,6 +771,10 @@ arbitrary Lua tables.
Same semantics as for the ``Site`` functions, but will associated the data
with the global world context.

* ``dfhack.persistent.getUnsavedSecs()``
realSquidCoder marked this conversation as resolved.
Show resolved Hide resolved

Returns the number of seconds since last save or load of a save
realSquidCoder marked this conversation as resolved.
Show resolved Hide resolved

The data is kept in memory, so no I/O occurs when getting or saving keys. It is
all written to a json file in the game save directory when the game is saved.

Expand Down
8 changes: 8 additions & 0 deletions library/LuaApi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -353,13 +353,19 @@ static int dfhack_persistent_delete_world_data(lua_State *L) {
return delete_site_data(L, get_world_data);
}

static int dfhack_persistent_get_last_save_time(lua_State *L) {
realSquidCoder marked this conversation as resolved.
Show resolved Hide resolved
lua_pushinteger(L, Persistence::getUnsavedSeconds());
return 1;
}

static const luaL_Reg dfhack_persistent_funcs[] = {
{ "getSiteDataString", dfhack_persistent_get_site_data_string },
{ "saveSiteDataString", dfhack_persistent_save_site_data_string },
{ "deleteSiteData", dfhack_persistent_delete_site_data },
{ "getWorldDataString", dfhack_persistent_get_world_data_string },
{ "saveWorldDataString", dfhack_persistent_save_world_data_string },
{ "deleteWorldData", dfhack_persistent_delete_world_data },
{ "getUnsavedSeconds", dfhack_persistent_get_last_save_time },
realSquidCoder marked this conversation as resolved.
Show resolved Hide resolved
{ NULL, NULL }
};

Expand Down Expand Up @@ -1343,6 +1349,7 @@ static string getArchitectureName()

static string getDFVersion() { return Core::getInstance().vinfo->getVersion(); }
static uint32_t getTickCount() { return Core::getInstance().p->getTickCount(); }
static uint32_t getCurSaveDur() { return Persistence::getUnsavedSeconds(); }
realSquidCoder marked this conversation as resolved.
Show resolved Hide resolved

static string getDFPath() { return Core::getInstance().p->getPath(); }
static string getHackPath() { return Core::getInstance().getHackPath(); }
Expand Down Expand Up @@ -1370,6 +1377,7 @@ static const LuaWrapper::FunctionReg dfhack_module[] = {
WRAP(getDFVersion),
WRAP(getDFPath),
WRAP(getTickCount),
WRAP(getCurSaveDur),
realSquidCoder marked this conversation as resolved.
Show resolved Hide resolved
realSquidCoder marked this conversation as resolved.
Show resolved Hide resolved
WRAP(getHackPath),
WRAP(isWorldLoaded),
WRAP(isMapLoaded),
Expand Down
2 changes: 2 additions & 0 deletions library/include/modules/Persistence.h
Original file line number Diff line number Diff line change
Expand Up @@ -213,5 +213,7 @@ namespace DFHack
// Fills the vector with references to each persistent item with a key that is
// equal to the given key.
DFHACK_EXPORT void getAllByKey(std::vector<PersistentDataItem> &vec, int entity_id, const std::string &key);
// Returns the number of seconds since the current savegame was saved or loaded.
DFHACK_EXPORT uint32_t getUnsavedSeconds();
}
}
10 changes: 10 additions & 0 deletions library/modules/Persistence.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ using namespace DFHack;
static std::unordered_map<int, std::multimap<std::string, std::shared_ptr<Persistence::DataEntry>>> store;
static std::unordered_map<size_t, std::shared_ptr<Persistence::DataEntry>> entry_cache;

static uint32_t lastLoadSaveTickCount = 0;

size_t next_entry_id = 0; // goes more positive
int next_fake_df_id = -101; // goes more negative

Expand Down Expand Up @@ -237,6 +239,8 @@ void Persistence::Internal::save(color_ostream& out) {
color_ostream_wrapper wrapper(file);
Lua::CallLuaModuleFunction(wrapper, "script-manager", "print_timers");
}

lastLoadSaveTickCount = Core::getInstance().p->getTickCount();
realSquidCoder marked this conversation as resolved.
Show resolved Hide resolved
}

static bool get_entity_id(const std::string & fname, int & entity_id) {
Expand Down Expand Up @@ -306,6 +310,7 @@ void Persistence::Internal::load(color_ostream& out) {
out.printerr("Cannot load data from: '%s'\n", path.c_str());
}

lastLoadSaveTickCount = Core::getInstance().p->getTickCount();
realSquidCoder marked this conversation as resolved.
Show resolved Hide resolved
if (found)
return;

Expand Down Expand Up @@ -417,3 +422,8 @@ void Persistence::getAllByKey(std::vector<PersistentDataItem> &vec, int entity_i
for (auto it = range.first; it != range.second; ++it)
vec.emplace_back(it->second);
}

uint32_t Persistence::getUnsavedSeconds() {
uint32_t durMS = Core::getInstance().p->getTickCount() - lastLoadSaveTickCount;
return durMS / 1000;
}
Loading