Save changed maps every 5 minutes (#5557)

* Save maps every 5 minutes

Signed-off-by: Mike Jagdis <mjagdis@eris-associates.co.uk>

* Only save maps with changes

Signed-off-by: Mike Jagdis <mjagdis@eris-associates.co.uk>

* Maps created with non-default values are immediately dirty

Signed-off-by: Mike Jagdis <mjagdis@eris-associates.co.uk>

* Apply suggestions from code review

* Fix spacing for clang-tidy

---------

Signed-off-by: Mike Jagdis <mjagdis@eris-associates.co.uk>
Co-authored-by: Alexander Harkness <me@bearbin.net>
This commit is contained in:
mjagdis 2024-11-01 22:19:34 +00:00 committed by GitHub
parent 352134ba9e
commit 4e3b272af7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 47 additions and 7 deletions

View File

@ -23,6 +23,7 @@ cMap::cMap(unsigned int a_ID, cWorld * a_World):
m_Scale(3), m_Scale(3),
m_CenterX(0), m_CenterX(0),
m_CenterZ(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_World(a_World),
m_Name(fmt::format(FMT_STRING("map_{}"), m_ID)) 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_Scale(a_Scale),
m_CenterX(a_CenterX), m_CenterX(a_CenterX),
m_CenterZ(a_CenterZ), 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_World(a_World),
m_Name(fmt::format(FMT_STRING("map_{}"), m_ID)) 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)) 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; return true;
} }

View File

@ -185,6 +185,8 @@ private:
int m_CenterX; int m_CenterX;
int m_CenterZ; int m_CenterZ;
bool m_Dirty;
/** Column-major array of colours */ /** Column-major array of colours */
cColorList m_Data; cColorList m_Data;
@ -196,6 +198,7 @@ private:
AString m_Name; AString m_Name;
friend class cMapManager;
friend class cMapSerializer; friend class cMapSerializer;
}; // tolua_export }; // tolua_export

View File

@ -12,8 +12,16 @@
cMapManager::cMapManager(cWorld * a_World) // 6000 ticks or 5 minutes
: m_World(a_World) #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); ASSERT(m_World != nullptr);
} }
@ -49,6 +57,16 @@ void cMapManager::TickMaps()
{ {
Map.Tick(); 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; cMap & Map = *it;
cMapSerializer Serializer(m_World->GetDataPath(), &Map); if (Map.m_Dirty)
if (!Serializer.Save())
{ {
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());
}
} }
} }
} }

View File

@ -64,6 +64,10 @@ private:
cWorld * m_World; 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 }; // tolua_export