From 9fcd2d4210d6928fa974adc82e289472a9b4f181 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Thu, 24 Dec 2020 15:27:44 +0000 Subject: [PATCH] Avoid a gratuitous dirty when loading chunks with entities Loaded entities are directly moved into the chunk data, instead of having to go through cWorld, as if they were just spawned. This avoid dirtying the chunk. --- src/Chunk.cpp | 22 ++++++++++++++++++++++ src/World.cpp | 15 --------------- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/src/Chunk.cpp b/src/Chunk.cpp index eb44828e2..fc128b31c 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -262,6 +262,9 @@ void cChunk::MarkLoadFailed(void) { ASSERT(m_Presence == cpQueued); + // Mark dirty before generating, so that we get saved and don't have to later generate again: + MarkDirty(); + // The chunk is always needed, generate it: m_World->GetGenerator().QueueGenerateChunk({m_PosX, m_PosZ}, false); } @@ -307,6 +310,25 @@ void cChunk::SetAllData(cSetChunkData & a_SetChunkData) m_ChunkData.Assign(std::move(a_SetChunkData.GetChunkData())); m_IsLightValid = a_SetChunkData.IsLightValid(); + // Entities need some extra steps to destroy, so here we're keeping the old ones. + // Move the entities already in the chunk, including player entities, so that we don't lose any: + a_SetChunkData.GetEntities().insert( + a_SetChunkData.GetEntities().end(), + std::make_move_iterator(m_Entities.begin()), + std::make_move_iterator(m_Entities.end()) + ); + + // Store the augmented result: + m_Entities = std::move(a_SetChunkData.GetEntities()); + + // Set all the entity variables again: + for (const auto & Entity : m_Entities) + { + Entity->SetWorld(m_World); + Entity->SetParentChunk(this); + Entity->SetIsTicking(true); + } + // Clear the block entities present - either the loader / saver has better, or we'll create empty ones: m_BlockEntities = std::move(a_SetChunkData.GetBlockEntities()); diff --git a/src/World.cpp b/src/World.cpp index 02de985c6..aea963257 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -2310,13 +2310,6 @@ void cWorld::SetChunkData(cSetChunkData & a_SetChunkData) m_ChunkMap.SetChunkData(a_SetChunkData); - // Initialize the entities (outside the m_ChunkMap's CS, to fix FS #347): - for (auto & Entity : a_SetChunkData.GetEntities()) - { - auto EntityPtr = Entity.get(); - EntityPtr->Initialize(std::move(Entity), *this); - } - // If a client is requesting this chunk, send it to them: int ChunkX = a_SetChunkData.GetChunkX(); int ChunkZ = a_SetChunkData.GetChunkZ(); @@ -2337,14 +2330,6 @@ void cWorld::SetChunkData(cSetChunkData & a_SetChunkData) return true; } ); - - // Save the chunk right after generating, so that we don't have to generate it again on next run - // If saving is disabled, then the chunk was marked dirty so it will get - // saved if saving is later enabled. - if (a_SetChunkData.ShouldMarkDirty() && IsSavingEnabled()) - { - m_Storage.QueueSaveChunk(ChunkX, ChunkZ); - } }