diff options
-rw-r--r-- | src/Map.cpp | 126 | ||||
-rw-r--r-- | src/Map.h | 61 |
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); } @@ -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; }; + + + |