From 4e3b272af7398df4f9313dda763930658d278aa0 Mon Sep 17 00:00:00 2001 From: mjagdis Date: Fri, 1 Nov 2024 22:19:34 +0000 Subject: Save changed maps every 5 minutes (#5557) * Save maps every 5 minutes Signed-off-by: Mike Jagdis * Only save maps with changes Signed-off-by: Mike Jagdis * Maps created with non-default values are immediately dirty Signed-off-by: Mike Jagdis * Apply suggestions from code review * Fix spacing for clang-tidy --------- Signed-off-by: Mike Jagdis Co-authored-by: Alexander Harkness --- src/Map.cpp | 10 +++++++++- src/Map.h | 3 +++ src/MapManager.cpp | 37 +++++++++++++++++++++++++++++++------ src/MapManager.h | 4 ++++ 4 files changed, 47 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/Map.cpp b/src/Map.cpp index 9e3c364b1..3691d0ab0 100644 --- a/src/Map.cpp +++ b/src/Map.cpp @@ -23,6 +23,7 @@ cMap::cMap(unsigned int a_ID, cWorld * a_World): m_Scale(3), m_CenterX(0), m_CenterZ(0), + m_Dirty(false), // This constructor is for an empty map object which will be filled by the caller with the correct values - it does not need saving. m_World(a_World), m_Name(fmt::format(FMT_STRING("map_{}"), m_ID)) { @@ -40,6 +41,7 @@ cMap::cMap(unsigned int a_ID, int a_CenterX, int a_CenterZ, cWorld * a_World, un m_Scale(a_Scale), m_CenterX(a_CenterX), m_CenterZ(a_CenterZ), + m_Dirty(true), // This constructor is for creating a brand new map in game, it will always need saving. m_World(a_World), m_Name(fmt::format(FMT_STRING("map_{}"), m_ID)) { @@ -223,7 +225,13 @@ bool cMap::SetPixel(unsigned int a_X, unsigned int a_Z, cMap::ColorID a_Data) { if ((a_X < m_Width) && (a_Z < m_Height)) { - m_Data[a_Z * m_Width + a_X] = a_Data; + auto index = a_Z * m_Width + a_X; + + if (m_Data[index] != a_Data) + { + m_Data[index] = a_Data; + m_Dirty = true; + } return true; } diff --git a/src/Map.h b/src/Map.h index 493b0883e..645f84c08 100644 --- a/src/Map.h +++ b/src/Map.h @@ -185,6 +185,8 @@ private: int m_CenterX; int m_CenterZ; + bool m_Dirty; + /** Column-major array of colours */ cColorList m_Data; @@ -196,6 +198,7 @@ private: AString m_Name; + friend class cMapManager; friend class cMapSerializer; }; // tolua_export diff --git a/src/MapManager.cpp b/src/MapManager.cpp index ae020d800..f7b393648 100644 --- a/src/MapManager.cpp +++ b/src/MapManager.cpp @@ -12,8 +12,16 @@ -cMapManager::cMapManager(cWorld * a_World) - : m_World(a_World) +// 6000 ticks or 5 minutes +#define MAP_DATA_SAVE_INTERVAL 6000 + + + + + +cMapManager::cMapManager(cWorld * a_World) : + m_World(a_World), + m_TicksUntilNextSave(MAP_DATA_SAVE_INTERVAL) { ASSERT(m_World != nullptr); } @@ -49,6 +57,16 @@ void cMapManager::TickMaps() { Map.Tick(); } + + if (m_TicksUntilNextSave == 0) + { + m_TicksUntilNextSave = MAP_DATA_SAVE_INTERVAL; + SaveMapData(); + } + else + { + m_TicksUntilNextSave--; + } } @@ -149,11 +167,18 @@ void cMapManager::SaveMapData(void) { cMap & Map = *it; - cMapSerializer Serializer(m_World->GetDataPath(), &Map); - - if (!Serializer.Save()) + if (Map.m_Dirty) { - LOGWARN("Could not save map #%i", Map.GetID()); + cMapSerializer Serializer(m_World->GetDataPath(), &Map); + + if (Serializer.Save()) + { + Map.m_Dirty = false; + } + else + { + LOGWARN("Could not save map #%i", Map.GetID()); + } } } } diff --git a/src/MapManager.h b/src/MapManager.h index 8959b1d8b..d20fe6683 100644 --- a/src/MapManager.h +++ b/src/MapManager.h @@ -64,6 +64,10 @@ private: cWorld * m_World; + /** How long till the map data will be saved + Default save interval is #defined in MAP_DATA_SAVE_INTERVAL */ + unsigned int m_TicksUntilNextSave; + }; // tolua_export -- cgit v1.2.3