summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/Map.cpp126
-rw-r--r--src/Map.h61
2 files changed, 114 insertions, 73 deletions
diff --git a/src/Map.cpp b/src/Map.cpp
index cb5472a22..0028a1e94 100644
--- a/src/Map.cpp
+++ b/src/Map.cpp
@@ -278,28 +278,35 @@ void cMap::UpdateDecorators(void)
-void cMap::UpdateClient(cPlayer * a_Player)
+void cMap::AddPlayer(cPlayer * a_Player, cClientHandle * a_Handle, Int64 a_WorldAge)
{
- ASSERT(a_Player != NULL);
- cClientHandle * Handle = a_Player->GetClientHandle();
+ cMapClient MapClient;
+
+ MapClient.m_LastUpdate = a_WorldAge;
+ MapClient.m_SendInfo = true;
+ MapClient.m_Handle = a_Handle;
+
+ m_Clients.push_back(MapClient);
+
+ cMapDecorator PlayerDecorator(this, a_Player);
+
+ m_Decorators.push_back(PlayerDecorator);
+}
+
+
- if (Handle == NULL)
- {
- return;
- }
- Int64 WorldAge = a_Player->GetWorld()->GetWorldAge();
- // Remove invalid clients
+void cMap::RemoveInactiveClients(Int64 a_WorldAge)
+{
for (cMapClientList::iterator it = m_Clients.begin(); it != m_Clients.end();)
{
- // Check if client is active
- if (it->m_LastUpdate < WorldAge - 5)
+ if (it->m_LastUpdate < a_WorldAge)
{
// Remove associated decorators
for (cMapDecoratorList::iterator it2 = m_Decorators.begin(); it2 != m_Decorators.end();)
{
- if (it2->GetPlayer()->GetClientHandle() == Handle)
+ if (it2->GetPlayer()->GetClientHandle() == it->m_Handle)
{
// Erase decorator
cMapDecoratorList::iterator temp = it2;
@@ -322,63 +329,82 @@ void cMap::UpdateClient(cPlayer * a_Player)
++it;
}
}
+}
- // Linear search for client state
- for (cMapClientList::iterator it = m_Clients.begin(); it != m_Clients.end(); ++it)
+
+
+
+
+void cMap::StreamNext(cMapClient & a_Client)
+{
+ cClientHandle * Handle = a_Client.m_Handle;
+
+ if (a_Client.m_SendInfo)
{
- if (it->m_Handle == Handle)
- {
- it->m_LastUpdate = WorldAge;
+ Handle->SendMapInfo(m_ID, m_Scale);
- if (it->m_SendInfo)
- {
- Handle->SendMapInfo(m_ID, m_Scale);
+ a_Client.m_SendInfo = false;
- it->m_SendInfo = false;
+ return;
+ }
- return;
- }
+ ++a_Client.m_NextDecoratorUpdate;
- ++it->m_NextDecoratorUpdate;
+ if (a_Client.m_NextDecoratorUpdate >= 4)
+ {
+ // TODO 2014-02-19 xdot
+ // This is dangerous as the player object may have been destroyed before the decorator is erased from the list
+ UpdateDecorators();
- if (it->m_NextDecoratorUpdate >= 4)
- {
- // TODO 2014-02-19 xdot
- // This is dangerous as the player object may have been destroyed before the decorator is erased from the list
- UpdateDecorators();
+ Handle->SendMapDecorators(m_ID, m_Decorators);
- Handle->SendMapDecorators(m_ID, m_Decorators);
+ a_Client.m_NextDecoratorUpdate = 0;
+ }
+ else
+ {
+ ++a_Client.m_DataUpdate;
- it->m_NextDecoratorUpdate = 0;
- }
- else
- {
- ++it->m_DataUpdate;
+ unsigned int Y = (a_Client.m_DataUpdate * 11) % m_Width;
- unsigned int Y = (it->m_DataUpdate * 11) % m_Width;
+ const Byte * Colors = &m_Data[Y * m_Height];
- const Byte * Colors = &m_Data[Y * m_Height];
+ Handle->SendMapColumn(m_ID, Y, 0, Colors, m_Height);
+ }
+}
- Handle->SendMapColumn(m_ID, Y, 0, Colors, m_Height);
- }
- return;
- }
+
+
+
+void cMap::UpdateClient(cPlayer * a_Player)
+{
+ ASSERT(a_Player != NULL);
+ cClientHandle * Handle = a_Player->GetClientHandle();
+
+ if (Handle == NULL)
+ {
+ return;
}
- // New player, construct a new client state
- cMapClient MapClient;
+ Int64 WorldAge = a_Player->GetWorld()->GetWorldAge();
- MapClient.m_LastUpdate = WorldAge;
- MapClient.m_SendInfo = true;
- MapClient.m_Handle = a_Player->GetClientHandle();
+ RemoveInactiveClients(WorldAge - 5);
- m_Clients.push_back(MapClient);
+ // Linear search for client state
+ for (cMapClientList::iterator it = m_Clients.begin(); it != m_Clients.end(); ++it)
+ {
+ if (it->m_Handle == Handle)
+ {
+ it->m_LastUpdate = WorldAge;
- // Insert new decorator
- cMapDecorator PlayerDecorator(this, a_Player);
+ StreamNext(*it);
- m_Decorators.push_back(PlayerDecorator);
+ return;
+ }
+ }
+
+ // New player, construct a new client state
+ AddPlayer(a_Player, Handle, WorldAge);
}
diff --git a/src/Map.h b/src/Map.h
index ce19c8d2e..01ffd19f5 100644
--- a/src/Map.h
+++ b/src/Map.h
@@ -105,29 +105,6 @@ public:
typedef std::vector<ColorID> cColorList;
- /** 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;
-
- /** Whether the map scale was modified and needs to be resent. */
- bool m_SendInfo;
-
- /** Ticks since last decorator update. */
- unsigned int m_NextDecoratorUpdate;
-
- /** Number of pixel data updates. */
- Int64 m_DataUpdate;
-
- Int64 m_LastUpdate;
- };
-
- typedef std::list<cMapClient> cMapClientList;
-
public:
@@ -185,6 +162,32 @@ public:
// tolua_end
+protected:
+
+ /** 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;
+
+ /** Whether the map scale was modified and needs to be resent. */
+ bool m_SendInfo;
+
+ /** Ticks since last decorator update. */
+ unsigned int m_NextDecoratorUpdate;
+
+ /** Number of pixel data updates. */
+ Int64 m_DataUpdate;
+
+ Int64 m_LastUpdate;
+ };
+
+ typedef std::list<cMapClient> cMapClientList;
+
+
private:
/** Update the associated decorators. */
@@ -193,6 +196,15 @@ private:
/** Update the specified pixel. */
bool UpdatePixel(unsigned int a_X, unsigned int a_Z);
+ /** Add a new map client. */
+ void AddPlayer(cPlayer * a_Player, cClientHandle * a_Handle, Int64 a_WorldAge);
+
+ /** Remove inactive or invalid clients. */
+ void RemoveInactiveClients(Int64 a_WorldAge);
+
+ /** Send next update packet to the specified client. */
+ void StreamNext(cMapClient & a_Client);
+
unsigned int m_ID;
unsigned int m_Width;
@@ -218,3 +230,6 @@ private:
friend class cMapSerializer;
};
+
+
+