Refactor autosave rotation.
In order to remove boost:filesystem from CResourceManager Move() function has to be removed or rewrited. Since Move is only used in autosave rotation it's simpler to change autosave rotation and remove Move(). Now oldest autosaves (with lowest timestamp) will be removed in rotation.master
parent
2168b57cac
commit
32629a2f2a
|
@ -31,11 +31,8 @@
|
||||||
|
|
||||||
#include <physfs.h>
|
#include <physfs.h>
|
||||||
|
|
||||||
#include <boost/filesystem.hpp>
|
|
||||||
#include <boost/regex.hpp>
|
#include <boost/regex.hpp>
|
||||||
|
|
||||||
namespace fs = boost::filesystem;
|
|
||||||
|
|
||||||
|
|
||||||
CResourceManager::CResourceManager(const char *argv0)
|
CResourceManager::CResourceManager(const char *argv0)
|
||||||
{
|
{
|
||||||
|
@ -231,32 +228,6 @@ long long CResourceManager::GetLastModificationTime(const std::string& filename)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: Don't use boost::filesystem. Why doesn't PHYSFS have this?
|
|
||||||
bool CResourceManager::Move(const std::string& from, const std::string& to)
|
|
||||||
{
|
|
||||||
if (PHYSFS_isInit())
|
|
||||||
{
|
|
||||||
bool success = true;
|
|
||||||
std::string writeDir = PHYSFS_getWriteDir();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
std::string path_from = writeDir + "/" + CleanPath(from);
|
|
||||||
std::string path_to = writeDir + "/" + CleanPath(to);
|
|
||||||
#if PLATFORM_WINDOWS
|
|
||||||
fs::rename(CSystemUtilsWindows::UTF8_Decode(path_from), CSystemUtilsWindows::UTF8_Decode(path_to));
|
|
||||||
#else
|
|
||||||
fs::rename(path_from, path_to);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
catch (std::exception&)
|
|
||||||
{
|
|
||||||
success = false;
|
|
||||||
}
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CResourceManager::Remove(const std::string& filename)
|
bool CResourceManager::Remove(const std::string& filename)
|
||||||
{
|
{
|
||||||
if (PHYSFS_isInit())
|
if (PHYSFS_isInit())
|
||||||
|
|
|
@ -66,8 +66,6 @@ public:
|
||||||
//! Returns last modification date as timestamp
|
//! Returns last modification date as timestamp
|
||||||
static long long GetLastModificationTime(const std::string &filename);
|
static long long GetLastModificationTime(const std::string &filename);
|
||||||
|
|
||||||
//! Move file/directory
|
|
||||||
static bool Move(const std::string &from, const std::string &to);
|
|
||||||
//! Remove file
|
//! Remove file
|
||||||
static bool Remove(const std::string& filename);
|
static bool Remove(const std::string& filename);
|
||||||
};
|
};
|
||||||
|
|
|
@ -105,6 +105,7 @@
|
||||||
|
|
||||||
#include "ui/screen/screen_loading.h"
|
#include "ui/screen/screen_loading.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
@ -5456,7 +5457,7 @@ void CRobotMain::SetAutosave(bool enable)
|
||||||
|
|
||||||
m_autosave = enable;
|
m_autosave = enable;
|
||||||
m_autosaveLast = m_gameTimeAbsolute;
|
m_autosaveLast = m_gameTimeAbsolute;
|
||||||
AutosaveRotate(false);
|
AutosaveRotate();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CRobotMain::GetAutosave()
|
bool CRobotMain::GetAutosave()
|
||||||
|
@ -5482,7 +5483,7 @@ void CRobotMain::SetAutosaveSlots(int slots)
|
||||||
if (m_autosaveSlots == slots) return;
|
if (m_autosaveSlots == slots) return;
|
||||||
|
|
||||||
m_autosaveSlots = slots;
|
m_autosaveSlots = slots;
|
||||||
AutosaveRotate(false);
|
AutosaveRotate();
|
||||||
}
|
}
|
||||||
|
|
||||||
int CRobotMain::GetAutosaveSlots()
|
int CRobotMain::GetAutosaveSlots()
|
||||||
|
@ -5490,85 +5491,39 @@ int CRobotMain::GetAutosaveSlots()
|
||||||
return m_autosaveSlots;
|
return m_autosaveSlots;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CRobotMain::AutosaveRotate(bool freeOne)
|
// Remove oldest saves with autosave prefix
|
||||||
|
void CRobotMain::AutosaveRotate()
|
||||||
{
|
{
|
||||||
if (m_playerProfile == nullptr)
|
if (m_playerProfile == nullptr)
|
||||||
return 0;
|
return;
|
||||||
|
|
||||||
GetLogger()->Debug("Rotate autosaves...\n");
|
GetLogger()->Debug("Rotate autosaves...\n");
|
||||||
// Find autosave dirs
|
|
||||||
auto saveDirs = CResourceManager::ListDirectories(m_playerProfile->GetSaveDir());
|
auto saveDirs = CResourceManager::ListDirectories(m_playerProfile->GetSaveDir());
|
||||||
std::map<int, std::string> autosaveDirs;
|
const std::string autosavePrefix = "autosave";
|
||||||
for (auto& dir : saveDirs)
|
std::vector<std::string> autosaves;
|
||||||
{
|
std::copy_if(saveDirs.begin(), saveDirs.end(), std::back_inserter(autosaves), [&](const std::string &save) {
|
||||||
try
|
return save.substr(0, autosavePrefix.length()) == autosavePrefix;
|
||||||
{
|
});
|
||||||
const std::string autosavePrefix = "autosave";
|
|
||||||
if (dir.substr(0, autosavePrefix.length()) == autosavePrefix)
|
|
||||||
{
|
|
||||||
int id = boost::lexical_cast<int>(dir.substr(autosavePrefix.length()));
|
|
||||||
autosaveDirs[id] = m_playerProfile->GetSaveFile(dir);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
GetLogger()->Info("Bad autosave found: %s\n", dir.c_str());
|
|
||||||
// skip
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (autosaveDirs.size() == 0) return 1;
|
|
||||||
|
|
||||||
// Remove all but last m_autosaveSlots
|
std::sort(autosaves.begin(), autosaves.end(), std::less<std::string>());
|
||||||
std::map<int, std::string> autosavesToKeep;
|
for (int i = 0; i < static_cast<int>(autosaves.size()) - m_autosaveSlots + 1; i++)
|
||||||
int last_id = autosaveDirs.rbegin()->first;
|
|
||||||
int count = 0;
|
|
||||||
int to_keep = m_autosaveSlots-(freeOne ? 1 : 0);
|
|
||||||
int new_last_id = Math::Min(autosaveDirs.size(), to_keep);
|
|
||||||
bool rotate = false;
|
|
||||||
for (int i = last_id; i > 0; i--)
|
|
||||||
{
|
{
|
||||||
if (autosaveDirs.count(i) > 0)
|
CResourceManager::RemoveDirectory(m_playerProfile->GetSaveDir() + "/" + autosaves[i]);
|
||||||
{
|
|
||||||
count++;
|
|
||||||
if (count > m_autosaveSlots-(freeOne ? 1 : 0) || !m_autosave)
|
|
||||||
{
|
|
||||||
GetLogger()->Trace("Remove %s\n", autosaveDirs[i].c_str());
|
|
||||||
CResourceManager::RemoveDirectory(autosaveDirs[i]);
|
|
||||||
rotate = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
GetLogger()->Trace("Keep %s\n", autosaveDirs[i].c_str());
|
|
||||||
autosavesToKeep[new_last_id-count+1] = autosaveDirs[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rename autosaves that we kept
|
|
||||||
if (rotate)
|
|
||||||
{
|
|
||||||
for (auto& save : autosavesToKeep)
|
|
||||||
{
|
|
||||||
std::string newDir = m_playerProfile->GetSaveFile("autosave" + boost::lexical_cast<std::string>(save.first));
|
|
||||||
GetLogger()->Trace("Rename %s -> %s\n", save.second.c_str(), newDir.c_str());
|
|
||||||
CResourceManager::Move(save.second, newDir);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return rotate ? count : count+1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CRobotMain::Autosave()
|
void CRobotMain::Autosave()
|
||||||
{
|
{
|
||||||
int id = AutosaveRotate(true);
|
AutosaveRotate();
|
||||||
GetLogger()->Info("Autosave!\n");
|
GetLogger()->Info("Autosave!\n");
|
||||||
|
|
||||||
std::string dir = m_playerProfile->GetSaveFile("autosave" + boost::lexical_cast<std::string>(id));
|
|
||||||
|
|
||||||
char timestr[100];
|
char timestr[100];
|
||||||
|
char infostr[100];
|
||||||
time_t now = time(nullptr);
|
time_t now = time(nullptr);
|
||||||
strftime(timestr, 99, "%x %X", localtime(&now));
|
strftime(timestr, 99, "%y%m%d%H%M%S", localtime(&now));
|
||||||
std::string info = std::string("[AUTOSAVE] ")+timestr;
|
strftime(infostr, 99, "%y.%m.%d %H:%M", localtime(&now));
|
||||||
|
std::string info = std::string("[AUTOSAVE] ") + infostr;
|
||||||
|
std::string dir = m_playerProfile->GetSaveFile(std::string("autosave") + timestr);
|
||||||
|
|
||||||
m_playerProfile->SaveScene(dir, info);
|
m_playerProfile->SaveScene(dir, info);
|
||||||
}
|
}
|
||||||
|
|
|
@ -402,7 +402,7 @@ protected:
|
||||||
void ExecuteCmd(const std::string& cmd);
|
void ExecuteCmd(const std::string& cmd);
|
||||||
void UpdateSpeedLabel();
|
void UpdateSpeedLabel();
|
||||||
|
|
||||||
int AutosaveRotate(bool freeOne);
|
void AutosaveRotate();
|
||||||
void Autosave();
|
void Autosave();
|
||||||
bool DestroySelectedObject();
|
bool DestroySelectedObject();
|
||||||
void PushToSelectionHistory(CObject* obj);
|
void PushToSelectionHistory(CObject* obj);
|
||||||
|
|
|
@ -80,7 +80,7 @@ void CScreenIO::IOReadName()
|
||||||
}
|
}
|
||||||
|
|
||||||
time(&now);
|
time(&now);
|
||||||
strftime(line, 99, "%y%m%d%H%M", localtime(&now));
|
strftime(line, 99, "%y.%m.%d %H:%M", localtime(&now));
|
||||||
sprintf(name, "%s - %s %d", line, resume.c_str(), m_main->GetLevelRank());
|
sprintf(name, "%s - %s %d", line, resume.c_str(), m_main->GetLevelRank());
|
||||||
|
|
||||||
pe->SetText(name);
|
pe->SetText(name);
|
||||||
|
|
Loading…
Reference in New Issue