From 9020dc993241a4a90e8e98b3435d9b2576f313ea Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 13 Aug 2013 22:45:29 +0200 Subject: Clients are now ticked in cServer first, then in cWorld once they get assigned a world. --- source/World.cpp | 66 +++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 58 insertions(+), 8 deletions(-) (limited to 'source/World.cpp') diff --git a/source/World.cpp b/source/World.cpp index b29bc751f..7a1ecb82e 100644 --- a/source/World.cpp +++ b/source/World.cpp @@ -587,6 +587,7 @@ void cWorld::Tick(float a_Dt) m_ChunkMap->Tick(a_Dt); + TickClients(a_Dt); TickQueuedBlocks(a_Dt); TickQueuedTasks(); @@ -811,6 +812,37 @@ void cWorld::TickQueuedTasks(void) +void cWorld::TickClients(float a_Dt) +{ + cClientHandleList RemoveClients; + { + cCSLock Lock(m_CSClients); + // Tick the clients, take out those that have been destroyed into RemoveClients + for (cClientHandleList::iterator itr = m_Clients.begin(); itr != m_Clients.end();) + { + if ((*itr)->IsDestroyed()) + { + // Remove the client later, when CS is not held, to avoid deadlock + RemoveClients.push_back(*itr); + itr = m_Clients.erase(itr); + continue; + } + (*itr)->Tick(a_Dt); + ++itr; + } // for itr - m_Clients[] + } + + // Delete the clients that have been destroyed + for (cClientHandleList::iterator itr = RemoveClients.begin(); itr != RemoveClients.end(); ++itr) + { + delete *itr; + } // for itr - RemoveClients[] +} + + + + + void cWorld::WakeUpSimulators(int a_BlockX, int a_BlockY, int a_BlockZ) { return m_ChunkMap->WakeUpSimulators(a_BlockX, a_BlockY, a_BlockZ); @@ -1973,13 +2005,22 @@ void cWorld::CollectPickupsByPlayer(cPlayer * a_Player) void cWorld::AddPlayer(cPlayer * a_Player) { - cCSLock Lock(m_CSPlayers); - - ASSERT(std::find(m_Players.begin(), m_Players.end(), a_Player) == m_Players.end()); // Is it already in the list? HOW? - - m_Players.remove(a_Player); // Make sure the player is registered only once - m_Players.push_back(a_Player); + { + cCSLock Lock(m_CSPlayers); + + ASSERT(std::find(m_Players.begin(), m_Players.end(), a_Player) == m_Players.end()); // Is it already in the list? HOW? + + m_Players.remove(a_Player); // Make sure the player is registered only once + m_Players.push_back(a_Player); + } + // Add the player's client to the list of clients to be ticked: + if (a_Player->GetClientHandle() != NULL) + { + cCSLock Lock(m_CSClients); + m_Clients.push_back(a_Player->GetClientHandle()); + } + // The player has already been added to the chunkmap as the entity, do NOT add again! } @@ -1990,8 +2031,17 @@ void cWorld::AddPlayer(cPlayer * a_Player) void cWorld::RemovePlayer(cPlayer * a_Player) { m_ChunkMap->RemoveEntity(a_Player); - cCSLock Lock(m_CSPlayers); - m_Players.remove(a_Player); + { + cCSLock Lock(m_CSPlayers); + m_Players.remove(a_Player); + } + + // Remove the player's client from the list of clients to be ticked: + if (a_Player->GetClientHandle() != NULL) + { + cCSLock Lock(m_CSClients); + m_Clients.remove(a_Player->GetClientHandle()); + } } -- cgit v1.2.3