diff options
author | Tiger Wang <ziwei.tiger@outlook.com> | 2021-03-05 14:03:55 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-03-05 14:03:55 +0100 |
commit | 868cd94ee9a5a0638c014a4cc42224f01ff234c8 (patch) | |
tree | cd23dc866f77de5b0b3e89a5eafeeb2ef24ffbdd /src/World.cpp | |
parent | fixed the crash on generating in the SinglePiceStructuresGen (#5136) (diff) | |
download | cuberite-868cd94ee9a5a0638c014a4cc42224f01ff234c8.tar cuberite-868cd94ee9a5a0638c014a4cc42224f01ff234c8.tar.gz cuberite-868cd94ee9a5a0638c014a4cc42224f01ff234c8.tar.bz2 cuberite-868cd94ee9a5a0638c014a4cc42224f01ff234c8.tar.lz cuberite-868cd94ee9a5a0638c014a4cc42224f01ff234c8.tar.xz cuberite-868cd94ee9a5a0638c014a4cc42224f01ff234c8.tar.zst cuberite-868cd94ee9a5a0638c014a4cc42224f01ff234c8.zip |
Diffstat (limited to 'src/World.cpp')
-rw-r--r-- | src/World.cpp | 136 |
1 files changed, 58 insertions, 78 deletions
diff --git a/src/World.cpp b/src/World.cpp index 1ade4d69c..d2aab1ac4 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -962,17 +962,6 @@ void cWorld::Tick(std::chrono::milliseconds a_Dt, std::chrono::milliseconds a_La // Call the plugins cPluginManager::Get()->CallHookWorldTick(*this, a_Dt, a_LastTickDurationMSec); - // Set any chunk data that has been queued for setting: - cSetChunkDataPtrs SetChunkDataQueue; - { - cCSLock Lock(m_CSSetChunkDataQueue); - std::swap(SetChunkDataQueue, m_SetChunkDataQueue); - } - for (cSetChunkDataPtrs::iterator itr = SetChunkDataQueue.begin(), end = SetChunkDataQueue.end(); itr != end; ++itr) - { - SetChunkData(**itr); - } // for itr - SetChunkDataQueue[] - m_WorldAge += a_Dt; if (m_IsDaylightCycleEnabled) @@ -997,6 +986,7 @@ void cWorld::Tick(std::chrono::milliseconds a_Dt, std::chrono::milliseconds a_La } } + TickQueuedChunkDataSets(); TickQueuedBlocks(); m_ChunkMap.Tick(a_Dt); TickMobs(a_Dt); @@ -1151,6 +1141,48 @@ void cWorld::TickMobs(std::chrono::milliseconds a_Dt) +void cWorld::TickQueuedChunkDataSets() +{ + decltype(m_SetChunkDataQueue) SetChunkDataQueue; + { + cCSLock Lock(m_CSSetChunkDataQueue); + SetChunkDataQueue = std::move(m_SetChunkDataQueue); + } + + // Set any chunk data that has been queued for setting: + for (auto & Item : SetChunkDataQueue) + { + // A copy of the chunk coordinates since we're moving Item. + const auto Chunk = Item.Chunk; + + // Set the data: + m_ChunkMap.SetChunkData(std::move(Item)); + + // If a client is requesting this chunk, send it to them: + cChunkSender & ChunkSender = m_ChunkSender; + DoWithChunk( + Chunk.m_ChunkX, Chunk.m_ChunkZ, + [&ChunkSender](cChunk & a_Chunk) + { + if (a_Chunk.HasAnyClients()) + { + ChunkSender.QueueSendChunkTo( + a_Chunk.GetPosX(), + a_Chunk.GetPosZ(), + cChunkSender::Priority::Medium, + a_Chunk.GetAllClients() + ); + } + return true; + } + ); + } // for itr - SetChunkDataQueue[] +} + + + + + void cWorld::TickQueuedEntityAdditions(void) { decltype(m_EntitiesToAdd) EntitiesToAdd; @@ -2236,22 +2268,8 @@ void cWorld::MarkChunkSaved (int a_ChunkX, int a_ChunkZ) -void cWorld::QueueSetChunkData(cSetChunkDataPtr a_SetChunkData) +void cWorld::QueueSetChunkData(struct SetChunkData && a_SetChunkData) { - // Validate biomes, if needed: - if (!a_SetChunkData->AreBiomesValid()) - { - // The biomes are not assigned, get them from the generator: - m_Generator.GenerateBiomes({a_SetChunkData->GetChunkX(), a_SetChunkData->GetChunkZ()}, a_SetChunkData->GetBiomes()); - a_SetChunkData->MarkBiomesValid(); - } - - // Validate heightmap, if needed: - if (!a_SetChunkData->IsHeightMapValid()) - { - a_SetChunkData->CalculateHeightMap(); - } - // Store a copy of the data in the queue: // TODO: If the queue is too large, wait for it to get processed. Not likely, though. cCSLock Lock(m_CSSetChunkDataQueue); @@ -2262,39 +2280,6 @@ void cWorld::QueueSetChunkData(cSetChunkDataPtr a_SetChunkData) -void cWorld::SetChunkData(cSetChunkData & a_SetChunkData) -{ - ASSERT(a_SetChunkData.AreBiomesValid()); - ASSERT(a_SetChunkData.IsHeightMapValid()); - - m_ChunkMap.SetChunkData(a_SetChunkData); - - // If a client is requesting this chunk, send it to them: - int ChunkX = a_SetChunkData.GetChunkX(); - int ChunkZ = a_SetChunkData.GetChunkZ(); - cChunkSender & ChunkSender = m_ChunkSender; - DoWithChunk( - ChunkX, ChunkZ, - [&ChunkSender] (cChunk & a_Chunk) -> bool - { - if (a_Chunk.HasAnyClients()) - { - ChunkSender.QueueSendChunkTo( - a_Chunk.GetPosX(), - a_Chunk.GetPosZ(), - cChunkSender::Priority::Medium, - a_Chunk.GetAllClients() - ); - } - return true; - } - ); -} - - - - - void cWorld::ChunkLighted( int a_ChunkX, int a_ChunkZ, const cChunkDef::BlockNibbles & a_BlockLight, @@ -2317,15 +2302,6 @@ bool cWorld::GetChunkData(cChunkCoords a_Coords, cChunkDataCallback & a_Callback -bool cWorld::GetChunkBlockTypes(int a_ChunkX, int a_ChunkZ, BLOCKTYPE * a_BlockTypes) -{ - return m_ChunkMap.GetChunkBlockTypes(a_ChunkX, a_ChunkZ, a_BlockTypes); -} - - - - - bool cWorld::IsChunkQueued(int a_ChunkX, int a_ChunkZ) const { return m_ChunkMap.IsChunkQueued(a_ChunkX, a_ChunkZ); @@ -3260,16 +3236,20 @@ void cWorld::cChunkGeneratorCallbacks::OnChunkGenerated(cChunkDesc & a_ChunkDesc cChunkDef::BlockNibbles BlockMetas; a_ChunkDesc.CompressBlockMetas(BlockMetas); - auto SetChunkData = std::make_unique<cSetChunkData>( - a_ChunkDesc.GetChunkX(), a_ChunkDesc.GetChunkZ(), - a_ChunkDesc.GetBlockTypes(), BlockMetas, - nullptr, nullptr, // We don't have lighting, chunk will be lighted when needed - &a_ChunkDesc.GetHeightMap(), &a_ChunkDesc.GetBiomeMap(), - std::move(a_ChunkDesc.GetEntities()), std::move(a_ChunkDesc.GetBlockEntities()), - true - ); - SetChunkData->RemoveInvalidBlockEntities(); - m_World->QueueSetChunkData(std::move(SetChunkData)); + struct SetChunkData Data({ a_ChunkDesc.GetChunkX(), a_ChunkDesc.GetChunkZ() }); + { + Data.BlockData.SetAll(a_ChunkDesc.GetBlockTypes(), BlockMetas); + + std::copy(a_ChunkDesc.GetBiomeMap(), a_ChunkDesc.GetBiomeMap() + std::size(a_ChunkDesc.GetBiomeMap()), Data.BiomeMap); + std::copy(a_ChunkDesc.GetHeightMap(), a_ChunkDesc.GetHeightMap() + std::size(a_ChunkDesc.GetHeightMap()), Data.HeightMap); + + Data.Entities = std::move(a_ChunkDesc.GetEntities()); + Data.BlockEntities = std::move(a_ChunkDesc.GetBlockEntities()); + + Data.IsLightValid = false; + } + + m_World->QueueSetChunkData(std::move(Data)); } |