summaryrefslogtreecommitdiffstats
path: root/src/ChunkData.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ChunkData.cpp')
-rw-r--r--src/ChunkData.cpp658
1 files changed, 81 insertions, 577 deletions
diff --git a/src/ChunkData.cpp b/src/ChunkData.cpp
index a480c2c66..a820f043b 100644
--- a/src/ChunkData.cpp
+++ b/src/ChunkData.cpp
@@ -13,437 +13,121 @@
namespace
{
- /** Returns true if all a_Array's elements between [0] and [a_NumElements - 1] are equal to a_Value. */
- template <typename T>
- bool IsAllValue(const T * a_Array, size_t a_NumElements, T a_Value)
+ struct SectionIndices
{
- for (size_t i = 0; i < a_NumElements; i++)
- {
- if (a_Array[i] != a_Value)
- {
- return false;
- }
- }
- return true;
- }
-
-
-
-
-
- struct sSectionIndices
- {
- int Section = 0; // Index into m_Sections
- int Index = 0; // Index into a single sChunkSection
+ size_t Section = 0; // Index into m_Sections
+ size_t Index = 0; // Index into a single sChunkSection
};
- sSectionIndices IndicesFromRelPos(Vector3i a_RelPos)
+ inline SectionIndices IndicesFromRelPos(const Vector3i a_RelPos)
{
ASSERT(cChunkDef::IsValidRelPos(a_RelPos));
- sSectionIndices Ret;
- Ret.Section = a_RelPos.y / cChunkData::SectionHeight;
- Ret.Index = cChunkDef::MakeIndexNoCheck(a_RelPos.x, a_RelPos.y % cChunkData::SectionHeight, a_RelPos.z);
- return Ret;
- }
-} // namespace (anonymous)
-
-
-
-
-
-cChunkData::cChunkData(cAllocationPool<cChunkData::sChunkSection> & a_Pool):
- m_Sections(),
- m_Pool(a_Pool)
-{
-}
-
-
-
-
-
-cChunkData::cChunkData(cChunkData && a_Other):
- m_Pool(a_Other.m_Pool)
-{
- for (size_t i = 0; i < NumSections; i++)
- {
- m_Sections[i] = a_Other.m_Sections[i];
- a_Other.m_Sections[i] = nullptr;
- }
-}
-
-
-
-
-
-cChunkData::~cChunkData()
-{
- Clear();
-}
-
-
-
-
-void cChunkData::Assign(const cChunkData & a_Other)
-{
- // If assigning to self, no-op
- if (&a_Other == this)
- {
- return;
- }
-
- Clear();
- for (size_t i = 0; i < NumSections; ++i)
- {
- if (a_Other.m_Sections[i] != nullptr)
+ return
{
- m_Sections[i] = Allocate();
- *m_Sections[i] = *a_Other.m_Sections[i];
- }
- }
-}
-
-
-
-
-
-void cChunkData::Assign(cChunkData && a_Other)
-{
- if (&a_Other == this)
- {
- return;
- }
-
- if (m_Pool != a_Other.m_Pool)
- {
- // Cannot transfer the memory, do a copy instead
- const cChunkData & CopyOther = a_Other;
- Assign(CopyOther);
- return;
- }
-
- Clear();
- for (size_t i = 0; i < NumSections; i++)
- {
- m_Sections[i] = a_Other.m_Sections[i];
- a_Other.m_Sections[i] = nullptr;
- }
-}
-
-
-
-
-
-BLOCKTYPE cChunkData::GetBlock(Vector3i a_RelPos) const
-{
- if (!cChunkDef::IsValidRelPos(a_RelPos))
- {
- return E_BLOCK_AIR; // Coordinates are outside outside the world, so this must be an air block
+ static_cast<size_t>(a_RelPos.y / cChunkDef::SectionHeight),
+ static_cast<size_t>(cChunkDef::MakeIndexNoCheck(a_RelPos.x, a_RelPos.y % cChunkDef::SectionHeight, a_RelPos.z))
+ };
}
- auto Idxs = IndicesFromRelPos(a_RelPos);
- if (m_Sections[Idxs.Section] != nullptr)
- {
- return m_Sections[Idxs.Section]->m_BlockTypes[Idxs.Index];
- }
- else
- {
- return 0;
- }
-}
-
-
-
-
-void cChunkData::SetBlock(Vector3i a_RelPos, BLOCKTYPE a_Block)
-{
- if (!cChunkDef::IsValidRelPos(a_RelPos))
+ bool IsCompressed(const size_t ElementCount)
{
- ASSERT(!"cChunkData::SetMeta(): index out of range!");
- return;
+ return ElementCount != ChunkBlockData::SectionBlockCount;
}
- auto Idxs = IndicesFromRelPos(a_RelPos);
- if (m_Sections[Idxs.Section] == nullptr)
+ template <size_t ElementCount, typename ValueType>
+ ValueType UnpackDefaultValue(const ValueType DefaultValue)
{
- if (a_Block == 0x00)
- {
- return;
- }
- m_Sections[Idxs.Section] = Allocate();
- if (m_Sections[Idxs.Section] == nullptr)
+ if (IsCompressed(ElementCount))
{
- ASSERT(!"Failed to allocate a new section in Chunkbuffer");
- return;
+ return DefaultValue & 0xF;
}
- ZeroSection(m_Sections[Idxs.Section]);
- }
- m_Sections[Idxs.Section]->m_BlockTypes[Idxs.Index] = a_Block;
-}
-
-
-
-
-NIBBLETYPE cChunkData::GetMeta(Vector3i a_RelPos) const
-{
- if (cChunkDef::IsValidRelPos(a_RelPos))
- {
- auto Idxs = IndicesFromRelPos(a_RelPos);
- if (m_Sections[Idxs.Section] != nullptr)
- {
- return (m_Sections[Idxs.Section]->m_BlockMetas[Idxs.Index / 2] >> ((Idxs.Index & 1) * 4)) & 0x0f;
- }
- else
- {
- return 0;
- }
+ return DefaultValue;
}
- // Coordinates are outside outside the world, so it must be an air block with a blank meta
- return 0;
-}
+} // namespace (anonymous)
-bool cChunkData::SetMeta(Vector3i a_RelPos, NIBBLETYPE a_Nibble)
+template<class ElementType, size_t ElementCount, ElementType DefaultValue>
+void ChunkDataStore<ElementType, ElementCount, DefaultValue>::Assign(const ChunkDataStore<ElementType, ElementCount, DefaultValue> & a_Other)
{
- if (!cChunkDef::IsValidRelPos(a_RelPos))
+ for (size_t Y = 0; Y != cChunkDef::NumSections; Y++)
{
- ASSERT(!"cChunkData::SetMeta(): index out of range!");
- return false;
- }
+ Store[Y].reset();
- auto Idxs = IndicesFromRelPos(a_RelPos);
- if (m_Sections[Idxs.Section] == nullptr)
- {
- if ((a_Nibble & 0xf) == 0x00)
- {
- return false;
- }
- m_Sections[Idxs.Section] = Allocate();
- if (m_Sections[Idxs.Section] == nullptr)
+ if (const auto & Other = a_Other.Store[Y]; Other != nullptr)
{
- ASSERT(!"Failed to allocate a new section in Chunkbuffer");
- return false;
+ Store[Y] = std::make_unique<Type>(*Other);
}
- ZeroSection(m_Sections[Idxs.Section]);
}
- NIBBLETYPE oldval = m_Sections[Idxs.Section]->m_BlockMetas[Idxs.Index / 2] >> ((Idxs.Index & 1) * 4) & 0xf;
- m_Sections[Idxs.Section]->m_BlockMetas[Idxs.Index / 2] = static_cast<NIBBLETYPE>(
- (m_Sections[Idxs.Section]->m_BlockMetas[Idxs.Index / 2] & (0xf0 >> ((Idxs.Index & 1) * 4))) | // The untouched nibble
- ((a_Nibble & 0x0f) << ((Idxs.Index & 1) * 4)) // The nibble being set
- );
- return oldval != a_Nibble;
}
-NIBBLETYPE cChunkData::GetBlockLight(Vector3i a_RelPos) const
+template<class ElementType, size_t ElementCount, ElementType DefaultValue>
+ElementType ChunkDataStore<ElementType, ElementCount, DefaultValue>::Get(const Vector3i a_Position) const
{
- if (cChunkDef::IsValidRelPos(a_RelPos))
- {
- auto Idxs = IndicesFromRelPos(a_RelPos);
- if (m_Sections[Idxs.Section] != nullptr)
- {
- return (m_Sections[Idxs.Section]->m_BlockLight[Idxs.Index / 2] >> ((Idxs.Index & 1) * 4)) & 0x0f;
- }
- else
- {
- return 0;
- }
- }
- ASSERT(!"cChunkData::GetMeta(): coords out of chunk range!");
- return 0;
-}
-
+ const auto Indices = IndicesFromRelPos(a_Position);
+ const auto & Section = Store[Indices.Section];
-
-
-
-NIBBLETYPE cChunkData::GetSkyLight(Vector3i a_RelPos) const
-{
- if (cChunkDef::IsValidRelPos(a_RelPos))
+ if (Section != nullptr)
{
- auto Idxs = IndicesFromRelPos(a_RelPos);
- if (m_Sections[Idxs.Section] != nullptr)
+ if (IsCompressed(ElementCount))
{
- return (m_Sections[Idxs.Section]->m_BlockSkyLight[Idxs.Index / 2] >> ((Idxs.Index & 1) * 4)) & 0x0f;
+ return cChunkDef::ExpandNibble(Section->data(), Indices.Index);
}
else
{
- return 0xF;
+ return (*Section)[Indices.Index];
}
}
- ASSERT(!"cChunkData::GetMeta(): coords out of chunk range!");
- return 0;
-}
-
-
-
-
-
-const cChunkData::sChunkSection * cChunkData::GetSection(size_t a_SectionNum) const
-{
- if (a_SectionNum < NumSections)
- {
- return m_Sections[a_SectionNum];
- }
- ASSERT(!"cChunkData::GetSection: section index out of range");
- return nullptr;
-}
-
-
-
-
-
-UInt16 cChunkData::GetSectionBitmask() const
-{
- static_assert(NumSections <= 16U, "cChunkData::GetSectionBitmask needs a bigger data type");
- UInt16 Res = 0U;
- for (size_t i = 0U; i < NumSections; ++i)
- {
- Res |= ((m_Sections[i] != nullptr) << i);
- }
- return Res;
-}
-
-
-
-
-void cChunkData::Clear()
-{
- for (size_t i = 0; i < NumSections; ++i)
- {
- if (m_Sections[i] != nullptr)
- {
- Free(m_Sections[i]);
- m_Sections[i] = nullptr;
- }
- }
+ return UnpackDefaultValue<ElementCount>(DefaultValue);
}
-void cChunkData::CopyBlockTypes(BLOCKTYPE * a_Dest, size_t a_Idx, size_t a_Length) const
+template<class ElementType, size_t ElementCount, ElementType DefaultValue>
+typename ChunkDataStore<ElementType, ElementCount, DefaultValue>::Type * ChunkDataStore<ElementType, ElementCount, DefaultValue>::GetSection(const size_t a_Y) const
{
- size_t ToSkip = a_Idx;
-
- for (size_t i = 0; i < NumSections; i++)
- {
- size_t StartPos = 0;
- if (ToSkip > 0)
- {
- StartPos = std::min(ToSkip, +SectionBlockCount);
- ToSkip -= StartPos;
- }
- if (StartPos < SectionBlockCount)
- {
- size_t ToCopy = std::min(+SectionBlockCount - StartPos, a_Length);
- a_Length -= ToCopy;
- if (m_Sections[i] != nullptr)
- {
- BLOCKTYPE * blockbuffer = m_Sections[i]->m_BlockTypes;
- memcpy(&a_Dest[(i * SectionBlockCount) + StartPos - a_Idx], blockbuffer + StartPos, sizeof(BLOCKTYPE) * ToCopy);
- }
- else
- {
- memset(&a_Dest[(i * SectionBlockCount) + StartPos - a_Idx], 0, sizeof(BLOCKTYPE) * ToCopy);
- }
- }
- }
+ return Store[a_Y].get();
}
-void cChunkData::CopyMetas(NIBBLETYPE * a_Dest) const
+template<class ElementType, size_t ElementCount, ElementType DefaultValue>
+void ChunkDataStore<ElementType, ElementCount, DefaultValue>::Set(const Vector3i a_Position, const ElementType a_Value)
{
- for (size_t i = 0; i < NumSections; i++)
- {
- if (m_Sections[i] != nullptr)
- {
- memcpy(&a_Dest[i * SectionBlockCount / 2], &m_Sections[i]->m_BlockMetas, sizeof(m_Sections[i]->m_BlockMetas));
- }
- else
- {
- memset(&a_Dest[i * SectionBlockCount / 2], 0, sizeof(m_Sections[i]->m_BlockMetas));
- }
- }
-}
-
-
-
-
+ const auto Indices = IndicesFromRelPos(a_Position);
+ auto & Section = Store[Indices.Section];
-void cChunkData::CopyBlockLight(NIBBLETYPE * a_Dest) const
-{
- for (size_t i = 0; i < NumSections; i++)
+ if (Section == nullptr)
{
- if (m_Sections[i] != nullptr)
- {
- memcpy(&a_Dest[i * SectionBlockCount / 2], &m_Sections[i]->m_BlockLight, sizeof(m_Sections[i]->m_BlockLight));
- }
- else
+ if (a_Value == UnpackDefaultValue<ElementCount>(DefaultValue))
{
- memset(&a_Dest[i * SectionBlockCount / 2], 0, sizeof(m_Sections[i]->m_BlockLight));
+ return;
}
- }
-}
-
-
-
-
-void cChunkData::CopySkyLight(NIBBLETYPE * a_Dest) const
-{
- for (size_t i = 0; i < NumSections; i++)
- {
- if (m_Sections[i] != nullptr)
- {
- memcpy(&a_Dest[i * SectionBlockCount / 2], &m_Sections[i]->m_BlockSkyLight, sizeof(m_Sections[i]->m_BlockSkyLight));
- }
- else
- {
- memset(&a_Dest[i * SectionBlockCount / 2], 0xff, sizeof(m_Sections[i]->m_BlockSkyLight));
- }
+ Section = cpp20::make_unique_for_overwrite<Type>();
+ std::fill(Section->begin(), Section->end(), DefaultValue);
}
-}
-
-
-
-
-void cChunkData::FillBlockTypes(BLOCKTYPE a_Value)
-{
- // If needed, allocate any missing sections
- if (a_Value != 0x00)
+ if (IsCompressed(ElementCount))
{
- for (auto & Section : m_Sections)
- {
- if (Section == nullptr)
- {
- Section = Allocate();
- std::fill(std::begin(Section->m_BlockMetas), std::end(Section->m_BlockMetas), 0x00);
- std::fill(std::begin(Section->m_BlockLight), std::end(Section->m_BlockLight), 0x00);
- std::fill(std::begin(Section->m_BlockSkyLight), std::end(Section->m_BlockSkyLight), 0xff);
- }
- }
+ cChunkDef::PackNibble(Section->data(), Indices.Index, a_Value);
}
-
- for (auto Section : m_Sections)
+ else
{
- if (Section != nullptr)
- {
- std::fill(std::begin(Section->m_BlockTypes), std::end(Section->m_BlockTypes), a_Value);
- }
+ (*Section)[Indices.Index] = a_Value;
}
}
@@ -451,61 +135,20 @@ void cChunkData::FillBlockTypes(BLOCKTYPE a_Value)
-void cChunkData::FillMetas(NIBBLETYPE a_Value)
+template<class ElementType, size_t ElementCount, ElementType DefaultValue>
+void ChunkDataStore<ElementType, ElementCount, DefaultValue>::SetSection(const ElementType (& a_Source)[ElementCount], const size_t a_Y)
{
- // If needed, allocate any missing sections
- if (a_Value != 0x00)
- {
- for (auto & Section : m_Sections)
- {
- if (Section == nullptr)
- {
- Section = Allocate();
- std::fill(std::begin(Section->m_BlockTypes), std::end(Section->m_BlockTypes), 0x00);
- std::fill(std::begin(Section->m_BlockLight), std::end(Section->m_BlockLight), 0x00);
- std::fill(std::begin(Section->m_BlockSkyLight), std::end(Section->m_BlockSkyLight), 0xff);
- }
- }
- }
-
- NIBBLETYPE NewMeta = static_cast<NIBBLETYPE>((a_Value << 4) | a_Value);
- for (auto Section : m_Sections)
- {
- if (Section != nullptr)
- {
- std::fill(std::begin(Section->m_BlockMetas), std::end(Section->m_BlockMetas), NewMeta);
- }
- }
-}
-
-
+ auto & Section = Store[a_Y];
+ const auto SourceEnd = std::end(a_Source);
-
-
-void cChunkData::FillBlockLight(NIBBLETYPE a_Value)
-{
- // If needed, allocate any missing sections
- if (a_Value != 0x00)
+ if (Section != nullptr)
{
- for (auto & Section : m_Sections)
- {
- if (Section == nullptr)
- {
- Section = Allocate();
- std::fill(std::begin(Section->m_BlockTypes), std::end(Section->m_BlockTypes), 0x00);
- std::fill(std::begin(Section->m_BlockMetas), std::end(Section->m_BlockMetas), 0x00);
- std::fill(std::begin(Section->m_BlockSkyLight), std::end(Section->m_BlockSkyLight), 0xff);
- }
- }
+ std::copy(a_Source, SourceEnd, Section->begin());
}
-
- NIBBLETYPE NewLight = static_cast<NIBBLETYPE>((a_Value << 4) | a_Value);
- for (auto Section : m_Sections)
+ else if (std::any_of(a_Source, SourceEnd, [](const auto Value) { return Value != DefaultValue; }))
{
- if (Section != nullptr)
- {
- std::fill(std::begin(Section->m_BlockLight), std::end(Section->m_BlockLight), NewLight);
- }
+ Section = cpp20::make_unique_for_overwrite<Type>();
+ std::copy(a_Source, SourceEnd, Section->begin());
}
}
@@ -513,30 +156,12 @@ void cChunkData::FillBlockLight(NIBBLETYPE a_Value)
-void cChunkData::FillSkyLight(NIBBLETYPE a_Value)
+template<class ElementType, size_t ElementCount, ElementType DefaultValue>
+void ChunkDataStore<ElementType, ElementCount, DefaultValue>::SetAll(const ElementType (& a_Source)[cChunkDef::NumSections * ElementCount])
{
- // If needed, allocate any missing sections
- if (a_Value != 0x0f)
+ for (size_t Y = 0; Y != cChunkDef::NumSections; Y++)
{
- for (auto & Section : m_Sections)
- {
- if (Section == nullptr)
- {
- Section = Allocate();
- std::fill(std::begin(Section->m_BlockTypes), std::end(Section->m_BlockTypes), 0x00);
- std::fill(std::begin(Section->m_BlockMetas), std::end(Section->m_BlockMetas), 0x00);
- std::fill(std::begin(Section->m_BlockLight), std::end(Section->m_BlockLight), 0x00);
- }
- }
- }
-
- NIBBLETYPE NewSkyLight = static_cast<NIBBLETYPE>((a_Value << 4) | a_Value);
- for (auto Section : m_Sections)
- {
- if (Section != nullptr)
- {
- std::fill(std::begin(Section->m_BlockSkyLight), std::end(Section->m_BlockSkyLight), NewSkyLight);
- }
+ SetSection(*reinterpret_cast<const ElementType (*)[ElementCount]>(a_Source + Y * ElementCount), Y);
}
}
@@ -544,187 +169,66 @@ void cChunkData::FillSkyLight(NIBBLETYPE a_Value)
-void cChunkData::SetBlockTypes(const BLOCKTYPE * a_Src)
-{
- ASSERT(a_Src != nullptr);
-
- for (size_t i = 0; i < NumSections; i++)
- {
- // If the section is already allocated, copy the data into it:
- if (m_Sections[i] != nullptr)
- {
- memcpy(m_Sections[i]->m_BlockTypes, &a_Src[i * SectionBlockCount], sizeof(m_Sections[i]->m_BlockTypes));
- continue;
- }
-
- // The section doesn't exist, find out if it is needed:
- if (IsAllValue(a_Src + i * SectionBlockCount, SectionBlockCount, static_cast<BLOCKTYPE>(0)))
- {
- // No need for the section, the data is all-air
- continue;
- }
-
- // Allocate the section and copy the data into it:
- m_Sections[i] = Allocate();
- memcpy(m_Sections[i]->m_BlockTypes, &a_Src[i * SectionBlockCount], sizeof(m_Sections[i]->m_BlockTypes));
- memset(m_Sections[i]->m_BlockMetas, 0x00, sizeof(m_Sections[i]->m_BlockMetas));
- memset(m_Sections[i]->m_BlockLight, 0x00, sizeof(m_Sections[i]->m_BlockLight));
- memset(m_Sections[i]->m_BlockSkyLight, 0xff, sizeof(m_Sections[i]->m_BlockSkyLight));
- } // for i - m_Sections[]
-}
-
-
-
-
-
-void cChunkData::SetMetas(const NIBBLETYPE * a_Src)
+void ChunkBlockData::Assign(const ChunkBlockData & a_Other)
{
- ASSERT(a_Src != nullptr);
-
- for (size_t i = 0; i < NumSections; i++)
- {
- // If the section is already allocated, copy the data into it:
- if (m_Sections[i] != nullptr)
- {
- memcpy(m_Sections[i]->m_BlockMetas, &a_Src[i * SectionBlockCount / 2], sizeof(m_Sections[i]->m_BlockMetas));
- continue;
- }
-
- // The section doesn't exist, find out if it is needed:
- if (IsAllValue(a_Src + i * SectionBlockCount / 2, SectionBlockCount / 2, static_cast<NIBBLETYPE>(0)))
- {
- // No need for the section, the data is all zeroes
- continue;
- }
-
- // Allocate the section and copy the data into it:
- m_Sections[i] = Allocate();
- memcpy(m_Sections[i]->m_BlockMetas, &a_Src[i * SectionBlockCount / 2], sizeof(m_Sections[i]->m_BlockMetas));
- memset(m_Sections[i]->m_BlockTypes, 0x00, sizeof(m_Sections[i]->m_BlockTypes));
- memset(m_Sections[i]->m_BlockLight, 0x00, sizeof(m_Sections[i]->m_BlockLight));
- memset(m_Sections[i]->m_BlockSkyLight, 0xff, sizeof(m_Sections[i]->m_BlockSkyLight));
- } // for i - m_Sections[]
+ m_Blocks.Assign(a_Other.m_Blocks);
+ m_Metas.Assign(a_Other.m_Metas);
}
-void cChunkData::SetBlockLight(const NIBBLETYPE * a_Src)
+void ChunkBlockData::SetAll(const cChunkDef::BlockTypes & a_BlockSource, const cChunkDef::BlockNibbles & a_MetaSource)
{
- if (a_Src == nullptr)
- {
- return;
- }
-
- for (size_t i = 0; i < NumSections; i++)
- {
- // If the section is already allocated, copy the data into it:
- if (m_Sections[i] != nullptr)
- {
- memcpy(m_Sections[i]->m_BlockLight, &a_Src[i * SectionBlockCount / 2], sizeof(m_Sections[i]->m_BlockLight));
- continue;
- }
-
- // The section doesn't exist, find out if it is needed:
- if (IsAllValue(a_Src + i * SectionBlockCount / 2, SectionBlockCount / 2, static_cast<NIBBLETYPE>(0)))
- {
- // No need for the section, the data is all zeroes
- continue;
- }
-
- // Allocate the section and copy the data into it:
- m_Sections[i] = Allocate();
- memcpy(m_Sections[i]->m_BlockLight, &a_Src[i * SectionBlockCount / 2], sizeof(m_Sections[i]->m_BlockLight));
- memset(m_Sections[i]->m_BlockTypes, 0x00, sizeof(m_Sections[i]->m_BlockTypes));
- memset(m_Sections[i]->m_BlockMetas, 0x00, sizeof(m_Sections[i]->m_BlockMetas));
- memset(m_Sections[i]->m_BlockSkyLight, 0xff, sizeof(m_Sections[i]->m_BlockSkyLight));
- } // for i - m_Sections[]
+ m_Blocks.SetAll(a_BlockSource);
+ m_Metas.SetAll(a_MetaSource);
}
-void cChunkData::SetSkyLight(const NIBBLETYPE * a_Src)
+void ChunkBlockData::SetSection(const SectionType & a_BlockSource, const SectionMetaType & a_MetaSource, const size_t a_Y)
{
- if (a_Src == nullptr)
- {
- return;
- }
-
- for (size_t i = 0; i < NumSections; i++)
- {
- // If the section is already allocated, copy the data into it:
- if (m_Sections[i] != nullptr)
- {
- memcpy(m_Sections[i]->m_BlockSkyLight, &a_Src[i * SectionBlockCount / 2], sizeof(m_Sections[i]->m_BlockSkyLight));
- continue;
- }
-
- // The section doesn't exist, find out if it is needed:
- if (IsAllValue(a_Src + i * SectionBlockCount / 2, SectionBlockCount / 2, static_cast<NIBBLETYPE>(0xff)))
- {
- // No need for the section, the data is all zeroes
- continue;
- }
-
- // Allocate the section and copy the data into it:
- m_Sections[i] = Allocate();
- memcpy(m_Sections[i]->m_BlockSkyLight, &a_Src[i * SectionBlockCount / 2], sizeof(m_Sections[i]->m_BlockSkyLight));
- memset(m_Sections[i]->m_BlockTypes, 0x00, sizeof(m_Sections[i]->m_BlockTypes));
- memset(m_Sections[i]->m_BlockMetas, 0x00, sizeof(m_Sections[i]->m_BlockMetas));
- memset(m_Sections[i]->m_BlockLight, 0x00, sizeof(m_Sections[i]->m_BlockLight));
- } // for i - m_Sections[]
+ m_Blocks.SetSection(a_BlockSource, a_Y);
+ m_Metas.SetSection(a_MetaSource, a_Y);
}
-UInt32 cChunkData::NumPresentSections() const
+void ChunkLightData::Assign(const ChunkLightData & a_Other)
{
- UInt32 Ret = 0U;
- for (size_t i = 0; i < NumSections; i++)
- {
- if (m_Sections[i] != nullptr)
- {
- ++Ret;
- }
- }
- return Ret;
+ m_BlockLights.Assign(a_Other.m_BlockLights);
+ m_SkyLights.Assign(a_Other.m_SkyLights);
}
-cChunkData::sChunkSection * cChunkData::Allocate(void)
+void ChunkLightData::SetAll(const cChunkDef::BlockNibbles & a_BlockLightSource, const cChunkDef::BlockNibbles & a_SkyLightSource)
{
- return m_Pool.Allocate();
+ m_BlockLights.SetAll(a_BlockLightSource);
+ m_SkyLights.SetAll(a_SkyLightSource);
}
-void cChunkData::Free(cChunkData::sChunkSection * a_Section)
+void ChunkLightData::SetSection(const SectionType & a_BlockLightSource, const SectionType & a_SkyLightSource, const size_t a_Y)
{
- m_Pool.Free(a_Section);
+ m_BlockLights.SetSection(a_BlockLightSource, a_Y);
+ m_SkyLights.SetSection(a_SkyLightSource, a_Y);
}
-void cChunkData::ZeroSection(cChunkData::sChunkSection * a_Section) const
-{
- memset(a_Section->m_BlockTypes, 0x00, sizeof(a_Section->m_BlockTypes));
- memset(a_Section->m_BlockMetas, 0x00, sizeof(a_Section->m_BlockMetas));
- memset(a_Section->m_BlockLight, 0x00, sizeof(a_Section->m_BlockLight));
- memset(a_Section->m_BlockSkyLight, 0xff, sizeof(a_Section->m_BlockSkyLight));
-}
-
-
-
-
+template struct ChunkDataStore<BLOCKTYPE, ChunkBlockData::SectionBlockCount, ChunkBlockData::DefaultValue>;
+template struct ChunkDataStore<NIBBLETYPE, ChunkBlockData::SectionMetaCount, ChunkLightData::DefaultBlockLightValue>;
+template struct ChunkDataStore<NIBBLETYPE, ChunkLightData::SectionLightCount, ChunkLightData::DefaultSkyLightValue>;