From 868cd94ee9a5a0638c014a4cc42224f01ff234c8 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 5 Mar 2021 13:03:55 +0000 Subject: Prepare ChunkData for BlockState storage (#5105) * Rename ChunkData Creatable test * Add missing Y-check in RedstoneWireHandler * Remove ChunkDef.h dependency in Scoreboard * Prepare ChunkData for BlockState storage + Split chunk block, meta, block & sky light storage + Load the height map from disk - Reduce duplicated code in ChunkData - Remove saving MCSBiomes, there aren't any - Remove the allocation pool, ref #4315, #3864 * fixed build * fixed test * fixed the debug compile Co-authored-by: 12xx12 <44411062+12xx12@users.noreply.github.com> --- src/World.cpp | 136 +++++++++++++++++++++++++--------------------------------- 1 file changed, 58 insertions(+), 78 deletions(-) (limited to 'src/World.cpp') 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( - 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)); } -- cgit v1.2.3