From 31b86f3886e4b8991861b007df091faafc8be782 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 18 Dec 2016 20:41:26 +0000 Subject: test --- src/Chunk.h | 3 +-- src/ChunkMap.cpp | 4 +--- src/Entities/Entity.cpp | 51 ++++++++++++++++++++++++++++++------------------- 3 files changed, 33 insertions(+), 25 deletions(-) diff --git a/src/Chunk.h b/src/Chunk.h index de46b5f8f..ecb594191 100644 --- a/src/Chunk.h +++ b/src/Chunk.h @@ -519,9 +519,8 @@ private: std::vector m_ToTickBlocks; sSetBlockVector m_PendingSendBlocks; ///< Blocks that have changed and need to be sent to all clients - // A critical section is not needed, because all chunk access is protected by its parent ChunkMap's csLayers - std::vector m_LoadedByClient; cEntityList m_Entities; + std::vector> m_LoadedByClient; cBlockEntityList m_BlockEntities; /** Number of times the chunk has been requested to stay (by various cChunkStay objects); if zero, the chunk can be unloaded */ diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index 7f53865d0..2e6153f0e 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -1582,10 +1582,7 @@ void cChunkMap::RemoveChunkClient(int a_ChunkX, int a_ChunkZ, const std::shared_ - -void cChunkMap::RemoveClientFromChunks(cClientHandle * a_Client) { - cCSLock Lock(m_CSChunks); for (const auto & Chunk : m_Chunks) { Chunk.second->RemoveClient(a_Client); @@ -1613,6 +1610,7 @@ void cChunkMap::AddEntity(cEntity * a_Entity) + ASSERT(GetWorld()->IsInTickThread()); void cChunkMap::AddEntityIfNotPresent(cEntity * a_Entity) { diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index 8d74ee99a..489b55cf8 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -132,7 +132,9 @@ const char * cEntity::GetParentClass(void) const bool cEntity::Initialize(cWorld & a_World) { - if (cPluginManager::Get()->CallHookSpawningEntity(a_World, *this)) + ASSERT(a_EntityWorld.IsInTickThread()); + + if (cPluginManager::Get()->CallHookSpawningEntity(a_EntityWorld, *this) && !IsPlayer()) { return false; } @@ -144,15 +146,22 @@ bool cEntity::Initialize(cWorld & a_World) ); */ - ASSERT(m_World == nullptr); ASSERT(GetParentChunk() == nullptr); - a_World.AddEntity(this); - ASSERT(m_World != nullptr); + cpp14::move_on_copy_wrapper Entity(std::move(a_Entity)); + + // So that entities do not appear in the middle of ticks + a_EntityWorld.QueueTask( + [Entity, &a_EntityWorld](cWorld & a_World) + { + auto & EntityPtr = *Entity.value; - cPluginManager::Get()->CallHookSpawnedEntity(a_World, *this); + EntityPtr.SetWorld(&a_EntityWorld); + a_EntityWorld.AddEntity(std::move(Entity.value)); - // Spawn the entity on the clients: - a_World.BroadcastSpawnEntity(*this); + a_EntityWorld.BroadcastSpawnEntity(EntityPtr); + cPluginManager::Get()->CallHookSpawnedEntity(a_EntityWorld, EntityPtr); + } + ); return true; } @@ -209,8 +218,7 @@ cChunk * cEntity::GetParentChunk() const void cEntity::Destroy(bool a_ShouldBroadcast) { - ASSERT(IsTicking()); - ASSERT(GetParentChunk() != nullptr); + ASSERT(GetWorld()->IsInTickThread()); SetIsTicking(false); if (a_ShouldBroadcast) @@ -218,17 +226,20 @@ void cEntity::Destroy(bool a_ShouldBroadcast) m_World->BroadcastDestroyEntity(*this); } - cChunk * ParentChunk = GetParentChunk(); - m_World->QueueTask([this, ParentChunk](cWorld & a_World) - { - LOGD("Destroying entity #%i (%s) from chunk (%d, %d)", - this->GetUniqueID(), this->GetClass(), - ParentChunk->GetPosX(), ParentChunk->GetPosZ() - ); - ParentChunk->RemoveEntity(this); - delete this; - }); - Destroyed(); + // So that entities do not disappear unexpectedly during ticks + m_World->QueueTask( + [this](cWorld & a_World) + { + auto ParentChunk = GetParentChunk(); + LOGD("Destroying entity #%i (%s) from chunk (%d, %d)", + GetUniqueID(), GetClass(), + ParentChunk->GetPosX(), ParentChunk->GetPosZ() + ); + + Destroyed(); // TODO: rename to OnPreDestroy() + ParentChunk->RemoveEntity(*this); + } + ); } -- cgit v1.2.3