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/WorldStorage/NBTChunkSerializer.cpp | 94 +++++++++++++++++---------------- 1 file changed, 49 insertions(+), 45 deletions(-) (limited to 'src/WorldStorage/NBTChunkSerializer.cpp') diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp index 2542cd2da..714c65a91 100644 --- a/src/WorldStorage/NBTChunkSerializer.cpp +++ b/src/WorldStorage/NBTChunkSerializer.cpp @@ -53,16 +53,14 @@ /** Collects and stores the chunk data via the cChunkDataCallback interface */ -class SerializerCollector: +class SerializerCollector final : public cChunkDataCopyCollector { public: // The data collected from the chunk: - cChunkDef::BiomeMap mBiomes; - UInt8 mVanillaBiomes[cChunkDef::Width * cChunkDef::Width]; - int mVanillaHeightMap[cChunkDef::Width * cChunkDef::Width]; - bool mBiomesAreValid; + UInt8 Biomes[cChunkDef::Width * cChunkDef::Width]; + int Heights[cChunkDef::Width * cChunkDef::Width]; /** True if a tag has been opened in the callbacks and not yet closed. */ bool mIsTagOpen; @@ -84,7 +82,6 @@ public: SerializerCollector(cFastNBTWriter & aWriter): - mBiomesAreValid(false), mIsTagOpen(false), mHasHadEntity(false), mHasHadBlockEntity(false), @@ -106,14 +103,13 @@ public: - virtual void HeightMap(const cChunkDef::HeightMap * a_HeightMap) override + virtual void HeightMap(const cChunkDef::HeightMap & a_HeightMap) override { - for (int RelX = 0; RelX < cChunkDef::Width; RelX++) + for (int RelZ = 0; RelZ < cChunkDef::Width; RelZ++) { - for (int RelZ = 0; RelZ < cChunkDef::Width; RelZ++) + for (int RelX = 0; RelX < cChunkDef::Width; RelX++) { - int Height = cChunkDef::GetHeight(*a_HeightMap, RelX, RelZ); - mVanillaHeightMap[(RelZ << 4) | RelX] = Height; + Heights[RelX + RelZ * cChunkDef::Width] = cChunkDef::GetHeight(a_HeightMap, RelX, RelZ); } } } @@ -122,15 +118,14 @@ public: - virtual void BiomeData(const cChunkDef::BiomeMap * a_BiomeMap) override + virtual void BiomeMap(const cChunkDef::BiomeMap & a_BiomeMap) override { - memcpy(mBiomes, a_BiomeMap, sizeof(mBiomes)); - for (size_t i = 0; i < ARRAYCOUNT(mBiomes); i++) + for (size_t i = 0; i < ARRAYCOUNT(Biomes); i++) { - if ((*a_BiomeMap)[i] < 255) + if (a_BiomeMap[i] < 255) { // Normal MC biome, copy as-is: - mVanillaBiomes[i] = static_cast((*a_BiomeMap)[i]); + Biomes[i] = static_cast(a_BiomeMap[i]); } else { @@ -139,7 +134,6 @@ public: return; } } // for i - mBiomeMap[] - mBiomesAreValid = true; } @@ -252,13 +246,6 @@ public: mWriter.EndList(); } - // If light not valid, reset it to defaults: - if (!mIsLightValid) - { - m_Data.FillBlockLight(0x00); - m_Data.FillSkyLight(0x0f); - } - // Check if "Entity" and "TileEntities" lists exists. MCEdit requires this. if (!mHasHadEntity) { @@ -1187,40 +1174,57 @@ void NBTChunkSerializer::Serialize(const cWorld & aWorld, cChunkCoords aCoords, ASSERT(Result); serializer.Finish(); // Close NBT tags - // Save biomes, both MCS (IntArray) and MC-vanilla (ByteArray): - if (serializer.mBiomesAreValid) - { - aWriter.AddByteArray("Biomes", reinterpret_cast(serializer.mVanillaBiomes), ARRAYCOUNT(serializer.mVanillaBiomes)); - aWriter.AddIntArray ("MCSBiomes", reinterpret_cast(serializer.mBiomes), ARRAYCOUNT(serializer.mBiomes)); - } + // Save biomes: + aWriter.AddByteArray("Biomes", reinterpret_cast(serializer.Biomes), ARRAYCOUNT(serializer.Biomes)); // Save heightmap (Vanilla require this): - aWriter.AddIntArray("HeightMap", reinterpret_cast(serializer.mVanillaHeightMap), ARRAYCOUNT(serializer.mVanillaHeightMap)); + aWriter.AddIntArray("HeightMap", reinterpret_cast(serializer.Heights), ARRAYCOUNT(serializer.Heights)); // Save blockdata: aWriter.BeginList("Sections", TAG_Compound); - for (size_t Y = 0; Y != cChunkData::NumSections; ++Y) + ChunkDef::ForEachSection(serializer.m_BlockData, serializer.m_LightData, [&aWriter](const auto Y, const auto Blocks, const auto Metas, const auto BlockLights, const auto SkyLights) { - auto section = serializer.m_Data.GetSection(Y); - if (section == nullptr) + aWriter.BeginCompound(""); + + if (Blocks != nullptr) { - continue; + aWriter.AddByteArray("Blocks", reinterpret_cast(Blocks->data()), Blocks->size()); + } + else + { + aWriter.AddByteArray("Blocks", ChunkBlockData::SectionBlockCount, ChunkBlockData::DefaultValue); } - aWriter.BeginCompound(""); - aWriter.AddByteArray("Blocks", reinterpret_cast(section->m_BlockTypes), ARRAYCOUNT(section->m_BlockTypes)); - aWriter.AddByteArray("Data", reinterpret_cast(section->m_BlockMetas), ARRAYCOUNT(section->m_BlockMetas)); + if (Metas != nullptr) + { + aWriter.AddByteArray("Data", reinterpret_cast(Metas->data()), Metas->size()); + } + else + { + aWriter.AddByteArray("Data", ChunkBlockData::SectionMetaCount, ChunkBlockData::DefaultMetaValue); + } + + if (BlockLights != nullptr) + { + aWriter.AddByteArray("BlockLight", reinterpret_cast(BlockLights->data()), BlockLights->size()); + } + else + { + aWriter.AddByteArray("BlockLight", ChunkLightData::SectionLightCount, ChunkLightData::DefaultBlockLightValue); + } - #ifdef DEBUG_SKYLIGHT - aWriter.AddByteArray("BlockLight", reinterpret_cast(section->m_BlockSkyLight), ARRAYCOUNT(section->m_BlockSkyLight)); - #else - aWriter.AddByteArray("BlockLight", reinterpret_cast(section->m_BlockLight), ARRAYCOUNT(section->m_BlockLight)); - #endif + if (SkyLights != nullptr) + { + aWriter.AddByteArray("SkyLight", reinterpret_cast(SkyLights->data()), SkyLights->size()); + } + else + { + aWriter.AddByteArray("SkyLight", ChunkLightData::SectionLightCount, ChunkLightData::DefaultSkyLightValue); + } - aWriter.AddByteArray("SkyLight", reinterpret_cast(section->m_BlockSkyLight), ARRAYCOUNT(section->m_BlockSkyLight)); aWriter.AddByte("Y", static_cast(Y)); aWriter.EndCompound(); - } + }); aWriter.EndList(); // "Sections" // Store the information that the lighting is valid. -- cgit v1.2.3