From b904223b9dbbe7b696dbd30e748bc131742e11ea Mon Sep 17 00:00:00 2001 From: Mattes D Date: Fri, 6 Jun 2014 22:31:16 +0200 Subject: [PATCH] Added queue for adding entities to cWorld. This alone doesn't work properly yet, further changes to cPlayer are needed. --- src/ClientHandle.h | 3 ++- src/Entities/Entity.h | 5 +++-- src/Entities/Player.cpp | 2 -- src/Entities/Player.h | 2 ++ src/World.cpp | 28 +++++++++++++++++++++++++++- src/World.h | 9 ++++++++- 6 files changed, 42 insertions(+), 7 deletions(-) diff --git a/src/ClientHandle.h b/src/ClientHandle.h index 659c67658..3f1cdf55a 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -250,7 +250,8 @@ public: void SendData(const char * a_Data, size_t a_Size); - /** Called when the player moves into a different world; queues sreaming the new chunks */ + /** Called when the player moves into a different world. + Locks the current world, doesn't lock the new world. */ void MoveToWorld(cWorld & a_World, bool a_SendRespawnPacket); /** Called when the player will enchant a Item */ diff --git a/src/Entities/Entity.h b/src/Entities/Entity.h index 0c393c0f5..9fe771120 100644 --- a/src/Entities/Entity.h +++ b/src/Entities/Entity.h @@ -421,6 +421,9 @@ public: UNUSED(a_Killer); } + /** Sets the internal world pointer to a new cWorld, doesn't update anything else. */ + void SetWorld(cWorld * a_World) { m_World = a_World; } + protected: static cCriticalSection m_CSCount; static int m_EntityCount; @@ -485,8 +488,6 @@ protected: virtual void Destroyed(void) {} // Called after the entity has been destroyed - void SetWorld(cWorld * a_World) { m_World = a_World; } - /** Called in each tick to handle air-related processing i.e. drowning */ virtual void HandleAir(); diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 3a9324d09..b83419903 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -1595,8 +1595,6 @@ bool cPlayer::MoveToWorld(const char * a_WorldName) m_ClientHandle->MoveToWorld(*World, (OldDimension != World->GetDimension())); // Add player to all the necessary parts of the new world - SetWorld(World); - m_ClientHandle->StreamChunks(); World->AddEntity(this); World->AddPlayer(this); diff --git a/src/Entities/Player.h b/src/Entities/Player.h index b7cb27d6c..83b9ad593 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -328,6 +328,8 @@ public: void SetVisible( bool a_bVisible ); // tolua_export bool IsVisible(void) const { return m_bVisible; } // tolua_export + /** Moves the player to the specified world. + Returns true if successful, false on failure (world not found). */ bool MoveToWorld(const char * a_WorldName); // tolua_export bool SaveToDisk(void); diff --git a/src/World.cpp b/src/World.cpp index 88e9c32e6..ccd47d3b0 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -743,6 +743,17 @@ void cWorld::Tick(float a_Dt, int a_LastTickDurationMSec) m_LastTimeUpdate = m_WorldAge; } + // Add entities waiting in the queue to be added: + { + cCSLock Lock(m_CSEntitiesToAdd); + for (cEntityList::iterator itr = m_EntitiesToAdd.begin(), end = m_EntitiesToAdd.end(); itr != end; ++itr) + { + (*itr)->SetWorld(this); + m_ChunkMap->AddEntity(*itr); + } + m_EntitiesToAdd.clear(); + } + m_ChunkMap->Tick(a_Dt); TickClients(a_Dt); @@ -2808,9 +2819,11 @@ void cWorld::ScheduleTask(int a_DelayTicks, cTask * a_Task) + void cWorld::AddEntity(cEntity * a_Entity) { - m_ChunkMap->AddEntity(a_Entity); + cCSLock Lock(m_CSEntitiesToAdd); + m_EntitiesToAdd.push_back(a_Entity); } @@ -2819,6 +2832,19 @@ void cWorld::AddEntity(cEntity * a_Entity) bool cWorld::HasEntity(int a_UniqueID) { + // Check if the entity is in the queue to be added to the world: + { + cCSLock Lock(m_CSEntitiesToAdd); + for (cEntityList::const_iterator itr = m_EntitiesToAdd.begin(), end = m_EntitiesToAdd.end(); itr != end; ++itr) + { + if ((*itr)->GetUniqueID() == a_UniqueID) + { + return true; + } + } // for itr - m_EntitiesToAdd[] + } + + // Check if the entity is in the chunkmap: return m_ChunkMap->HasEntity(a_UniqueID); } diff --git a/src/World.h b/src/World.h index 98b241a2b..4c014a976 100644 --- a/src/World.h +++ b/src/World.h @@ -301,7 +301,8 @@ public: void SendPlayerList(cPlayer * a_DestPlayer); // Sends playerlist to the player - /** Adds the entity into its appropriate chunk; takes ownership of the entity ptr */ + /** Adds the entity into its appropriate chunk; takes ownership of the entity ptr. + The entity is added lazily - this function only puts it in a queue that is then processed by the Tick thread. */ void AddEntity(cEntity * a_Entity); bool HasEntity(int a_UniqueID); @@ -926,6 +927,12 @@ private: /** Clients that are scheduled for adding, waiting for TickClients to add them */ cClientHandleList m_ClientsToAdd; + /** Guards m_EntitiesToAdd */ + cCriticalSection m_CSEntitiesToAdd; + + /** List of entities that are scheduled for adding, waiting for the Tick thread to add them. */ + cEntityList m_EntitiesToAdd; + cWorld(const AString & a_WorldName); virtual ~cWorld();