summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/Generating/StructGen.cpp9
-rw-r--r--src/Globals.h6
-rw-r--r--src/Map.h15
-rw-r--r--src/MapManager.cpp178
-rw-r--r--src/MapManager.h76
-rw-r--r--src/World.cpp3
-rw-r--r--src/World.h5
7 files changed, 275 insertions, 17 deletions
diff --git a/src/Generating/StructGen.cpp b/src/Generating/StructGen.cpp
index 4efcf92f0..47945cc2b 100644
--- a/src/Generating/StructGen.cpp
+++ b/src/Generating/StructGen.cpp
@@ -51,15 +51,6 @@ const int NEST_SIZE_GRAVEL = 32;
-template <typename T> T Clamp(T a_Value, T a_Min, T a_Max)
-{
- return (a_Value < a_Min) ? a_Min : ((a_Value > a_Max) ? a_Max : a_Value);
-}
-
-
-
-
-
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cStructGenTrees:
diff --git a/src/Globals.h b/src/Globals.h
index 7ee045130..e4737a98a 100644
--- a/src/Globals.h
+++ b/src/Globals.h
@@ -235,11 +235,11 @@ public:
-/** Clamp a_X to the specified range. */
+/** Clamp X to the specified range. */
template <typename T>
-T Clamp(T a_X, T a_Min, T a_Max)
+T Clamp(T a_Value, T a_Min, T a_Max)
{
- return std::min(std::max(a_X, a_Min), a_Max);
+ return (a_Value < a_Min) ? a_Min : ((a_Value > a_Max) ? a_Max : a_Value);
}
diff --git a/src/Map.h b/src/Map.h
index 3cf9977ab..ce19c8d2e 100644
--- a/src/Map.h
+++ b/src/Map.h
@@ -28,7 +28,14 @@ class cMap;
-/** Encapsulates a map decorator. */
+/** Encapsulates a map decorator.
+ *
+ * A map decorator represents an object drawn on the map that can move freely.
+ * (e.g. player trackers and item frame pointers)
+ *
+ * Excluding manually placed decorators,
+ * decorators are automatically managed (allocated and freed) by their parent cMap instance.
+ */
class cMapDecorator
{
public:
@@ -98,7 +105,11 @@ public:
typedef std::vector<ColorID> cColorList;
- /** Encapsulates the state of a map client. */
+ /** Encapsulates the state of a map client.
+ *
+ * In order to enhance performace, maps are streamed column-by-column to each client.
+ * This structure stores the state of the stream.
+ */
struct cMapClient
{
cClientHandle * m_Handle;
diff --git a/src/MapManager.cpp b/src/MapManager.cpp
new file mode 100644
index 000000000..2fc44ccc8
--- /dev/null
+++ b/src/MapManager.cpp
@@ -0,0 +1,178 @@
+
+// MapManager.cpp
+
+#include "Globals.h"
+
+#include "MapManager.h"
+
+#include "World.h"
+#include "WorldStorage/MapSerializer.h"
+
+
+
+
+
+cMapManager::cMapManager(cWorld * a_World)
+ : m_World(a_World)
+{
+ ASSERT(m_World != NULL);
+}
+
+
+
+
+
+bool cMapManager::DoWithMap(unsigned int a_ID, cMapCallback & a_Callback)
+{
+ cCSLock Lock(m_CS);
+ cMap * Map = GetMapData(a_ID);
+
+ if (Map == NULL)
+ {
+ return false;
+ }
+ else
+ {
+ a_Callback.Item(Map);
+ return true;
+ }
+}
+
+
+
+
+
+bool cMapManager::ForEachMap(cMapCallback & a_Callback)
+{
+ cCSLock Lock(m_CS);
+ for (cMapList::iterator itr = m_MapData.begin(); itr != m_MapData.end(); ++itr)
+ {
+ cMap * Map = &(*itr);
+ if (a_Callback.Item(Map))
+ {
+ return false;
+ }
+ } // for itr - m_MapData[]
+ return true;
+}
+
+
+
+
+
+cMap * cMapManager::GetMapData(unsigned int a_ID)
+{
+ if (a_ID < m_MapData.size())
+ {
+ return &m_MapData[a_ID];
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+
+
+
+
+cMap * cMapManager::CreateMap(int a_CenterX, int a_CenterY, int a_Scale)
+{
+ cCSLock Lock(m_CS);
+
+ if (m_MapData.size() >= 65536)
+ {
+ LOGWARN("Could not craft map - Too many maps in use");
+ return NULL;
+ }
+
+ cMap Map(m_MapData.size(), a_CenterX, a_CenterY, m_World, a_Scale);
+
+ m_MapData.push_back(Map);
+
+ return &m_MapData[Map.GetID()];
+}
+
+
+
+
+
+unsigned int cMapManager::GetNumMaps(void) const
+{
+ return m_MapData.size();
+}
+
+
+
+
+
+void cMapManager::LoadMapData(void)
+{
+ cCSLock Lock(m_CS);
+
+ cIDCountSerializer IDSerializer(m_World->GetName());
+
+ if (!IDSerializer.Load())
+ {
+ return;
+ }
+
+ unsigned int MapCount = IDSerializer.GetMapCount();
+
+ m_MapData.clear();
+
+ for (unsigned int i = 0; i < MapCount; ++i)
+ {
+ cMap Map(i, m_World);
+
+ cMapSerializer Serializer(m_World->GetName(), &Map);
+
+ if (!Serializer.Load())
+ {
+ LOGWARN("Could not load map #%i", Map.GetID());
+ }
+
+ m_MapData.push_back(Map);
+ }
+}
+
+
+
+
+
+void cMapManager::SaveMapData(void)
+{
+ cCSLock Lock(m_CS);
+
+ if (m_MapData.empty())
+ {
+ return;
+ }
+
+ cIDCountSerializer IDSerializer(m_World->GetName());
+
+ IDSerializer.SetMapCount(m_MapData.size());
+
+ if (!IDSerializer.Save())
+ {
+ LOGERROR("Could not save idcounts.dat");
+ return;
+ }
+
+ for (cMapList::iterator it = m_MapData.begin(); it != m_MapData.end(); ++it)
+ {
+ cMap & Map = *it;
+
+ cMapSerializer Serializer(m_World->GetName(), &Map);
+
+ if (!Serializer.Save())
+ {
+ LOGWARN("Could not save map #%i", Map.GetID());
+ }
+ }
+}
+
+
+
+
+
diff --git a/src/MapManager.h b/src/MapManager.h
new file mode 100644
index 000000000..05673c694
--- /dev/null
+++ b/src/MapManager.h
@@ -0,0 +1,76 @@
+
+// MapManager.h
+
+
+
+
+
+#pragma once
+
+
+
+
+
+#include "Map.h"
+
+
+
+
+typedef cItemCallback<cMap> cMapCallback;
+
+
+
+
+
+/** Manages the in-game maps of a single world - Thread safe. */
+class cMapManager
+{
+public:
+
+ cMapManager(cWorld * a_World);
+
+ /** Returns the map with the specified ID, NULL if out of range.
+ *
+ * WARNING: The returned map object is not thread safe.
+ */
+ cMap * GetMapData(unsigned int a_ID);
+
+ /** Creates a new map. Returns NULL on error */
+ cMap * CreateMap(int a_CenterX, int a_CenterY, int a_Scale = 3);
+
+ /** Calls the callback for the map with the specified ID.
+ *
+ * Returns true if the map was found and the callback called, false if map not found.
+ * Callback return ignored.
+ */
+ bool DoWithMap(unsigned int a_ID, cMapCallback & a_Callback);
+
+ /** Calls the callback for each map.
+ *
+ * Returns true if all maps processed, false if the callback aborted by returning true.
+ */
+ bool ForEachMap(cMapCallback & a_Callback);
+
+ unsigned int GetNumMaps(void) const;
+
+ /** Loads the map data from the disk */
+ void LoadMapData(void);
+
+ /** Saves the map data to the disk */
+ void SaveMapData(void);
+
+
+private:
+
+ typedef std::vector<cMap> cMapList;
+
+ cCriticalSection m_CS;
+
+ cMapList m_MapData;
+
+ cWorld * m_World;
+
+};
+
+
+
diff --git a/src/World.cpp b/src/World.cpp
index c1e0731c1..01fdae697 100644
--- a/src/World.cpp
+++ b/src/World.cpp
@@ -12,8 +12,8 @@
#include "Generating/ChunkDesc.h"
#include "OSSupport/Timer.h"
+// Serializers
#include "WorldStorage/ScoreboardSerializer.h"
-#include "WorldStorage/MapSerializer.h"
// Entities (except mobs):
#include "Entities/ExpOrb.h"
@@ -233,6 +233,7 @@ void cWorld::cTickThread::Execute(void)
// cWorld:
cWorld::cWorld(const AString & a_WorldName) :
+ cMapManager(this),
m_WorldName(a_WorldName),
m_IniFileName(m_WorldName + "/world.ini"),
m_StorageSchema("Default"),
diff --git a/src/World.h b/src/World.h
index 92fc66c8c..f05ea9b2a 100644
--- a/src/World.h
+++ b/src/World.h
@@ -24,7 +24,7 @@
#include "Entities/ProjectileEntity.h"
#include "ForEachChunkProvider.h"
#include "Scoreboard.h"
-#include "Map.h"
+#include "MapManager.h"
#include "Blocks/WorldInterface.h"
#include "Blocks/BroadcastInterface.h"
@@ -71,7 +71,8 @@ typedef cItemCallback<cMobHeadEntity> cMobHeadBlockCallback;
class cWorld :
public cForEachChunkProvider,
public cWorldInterface,
- public cBroadcastInterface
+ public cBroadcastInterface,
+ public cMapManager
{
public: