From 32629a2f2ad631ccb8774ac846795208d4c87d18 Mon Sep 17 00:00:00 2001 From: Krzysztof Dermont Date: Sun, 15 May 2016 19:42:27 +0200 Subject: [PATCH] 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. --- src/common/resources/resourcemanager.cpp | 29 -------- src/common/resources/resourcemanager.h | 2 - src/level/robotmain.cpp | 85 ++++++------------------ src/level/robotmain.h | 2 +- src/ui/screen/screen_io.cpp | 2 +- 5 files changed, 22 insertions(+), 98 deletions(-) diff --git a/src/common/resources/resourcemanager.cpp b/src/common/resources/resourcemanager.cpp index 9130b889..3ed0dee6 100644 --- a/src/common/resources/resourcemanager.cpp +++ b/src/common/resources/resourcemanager.cpp @@ -31,11 +31,8 @@ #include -#include #include -namespace fs = boost::filesystem; - CResourceManager::CResourceManager(const char *argv0) { @@ -231,32 +228,6 @@ long long CResourceManager::GetLastModificationTime(const std::string& filename) 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) { if (PHYSFS_isInit()) diff --git a/src/common/resources/resourcemanager.h b/src/common/resources/resourcemanager.h index b21ad267..61f85b38 100644 --- a/src/common/resources/resourcemanager.h +++ b/src/common/resources/resourcemanager.h @@ -66,8 +66,6 @@ public: //! Returns last modification date as timestamp static long long GetLastModificationTime(const std::string &filename); - //! Move file/directory - static bool Move(const std::string &from, const std::string &to); //! Remove file static bool Remove(const std::string& filename); }; diff --git a/src/level/robotmain.cpp b/src/level/robotmain.cpp index 374a7495..8019786b 100644 --- a/src/level/robotmain.cpp +++ b/src/level/robotmain.cpp @@ -105,6 +105,7 @@ #include "ui/screen/screen_loading.h" +#include #include #include #include @@ -5456,7 +5457,7 @@ void CRobotMain::SetAutosave(bool enable) m_autosave = enable; m_autosaveLast = m_gameTimeAbsolute; - AutosaveRotate(false); + AutosaveRotate(); } bool CRobotMain::GetAutosave() @@ -5482,7 +5483,7 @@ void CRobotMain::SetAutosaveSlots(int slots) if (m_autosaveSlots == slots) return; m_autosaveSlots = slots; - AutosaveRotate(false); + AutosaveRotate(); } int CRobotMain::GetAutosaveSlots() @@ -5490,85 +5491,39 @@ int CRobotMain::GetAutosaveSlots() return m_autosaveSlots; } -int CRobotMain::AutosaveRotate(bool freeOne) +// Remove oldest saves with autosave prefix +void CRobotMain::AutosaveRotate() { if (m_playerProfile == nullptr) - return 0; + return; GetLogger()->Debug("Rotate autosaves...\n"); - // Find autosave dirs auto saveDirs = CResourceManager::ListDirectories(m_playerProfile->GetSaveDir()); - std::map autosaveDirs; - for (auto& dir : saveDirs) - { - try - { - const std::string autosavePrefix = "autosave"; - if (dir.substr(0, autosavePrefix.length()) == autosavePrefix) - { - int id = boost::lexical_cast(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; + const std::string autosavePrefix = "autosave"; + std::vector autosaves; + std::copy_if(saveDirs.begin(), saveDirs.end(), std::back_inserter(autosaves), [&](const std::string &save) { + return save.substr(0, autosavePrefix.length()) == autosavePrefix; + }); - // Remove all but last m_autosaveSlots - std::map autosavesToKeep; - 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--) + std::sort(autosaves.begin(), autosaves.end(), std::less()); + for (int i = 0; i < static_cast(autosaves.size()) - m_autosaveSlots + 1; i++) { - if (autosaveDirs.count(i) > 0) - { - 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]; - } - } + CResourceManager::RemoveDirectory(m_playerProfile->GetSaveDir() + "/" + autosaves[i]); } - - // Rename autosaves that we kept - if (rotate) - { - for (auto& save : autosavesToKeep) - { - std::string newDir = m_playerProfile->GetSaveFile("autosave" + boost::lexical_cast(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() { - int id = AutosaveRotate(true); + AutosaveRotate(); GetLogger()->Info("Autosave!\n"); - std::string dir = m_playerProfile->GetSaveFile("autosave" + boost::lexical_cast(id)); - char timestr[100]; + char infostr[100]; time_t now = time(nullptr); - strftime(timestr, 99, "%x %X", localtime(&now)); - std::string info = std::string("[AUTOSAVE] ")+timestr; + strftime(timestr, 99, "%y%m%d%H%M%S", localtime(&now)); + 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); } diff --git a/src/level/robotmain.h b/src/level/robotmain.h index c25d1923..18649c0e 100644 --- a/src/level/robotmain.h +++ b/src/level/robotmain.h @@ -402,7 +402,7 @@ protected: void ExecuteCmd(const std::string& cmd); void UpdateSpeedLabel(); - int AutosaveRotate(bool freeOne); + void AutosaveRotate(); void Autosave(); bool DestroySelectedObject(); void PushToSelectionHistory(CObject* obj); diff --git a/src/ui/screen/screen_io.cpp b/src/ui/screen/screen_io.cpp index 52e62ee2..82db8d12 100644 --- a/src/ui/screen/screen_io.cpp +++ b/src/ui/screen/screen_io.cpp @@ -80,7 +80,7 @@ void CScreenIO::IOReadName() } 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()); pe->SetText(name);