From 096cdac80d222ac0be2a0554a759a0b16c1c34f6 Mon Sep 17 00:00:00 2001 From: peterbell10 Date: Mon, 21 Aug 2017 17:56:53 +0100 Subject: Implement protocol level chunk sparsing (#3864) --- src/ChunkData.cpp | 176 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 91 insertions(+), 85 deletions(-) (limited to 'src/ChunkData.cpp') diff --git a/src/ChunkData.cpp b/src/ChunkData.cpp index ab29e4ed3..c2b09bafb 100644 --- a/src/ChunkData.cpp +++ b/src/ChunkData.cpp @@ -27,36 +27,23 @@ template inline bool IsAllValue(const T * a_Array, size_t a_NumElem -cChunkData::cChunkData(cAllocationPool & a_Pool) : -#if __cplusplus < 201103L - // auto_ptr style interface for memory management - m_IsOwner(true), -#endif +cChunkData::cChunkData(cAllocationPool & a_Pool): + m_Sections(), m_Pool(a_Pool) { - for (size_t i = 0; i < NumSections; i++) - { - m_Sections[i] = nullptr; - } } -cChunkData::~cChunkData() +cChunkData::cChunkData(cChunkData && a_Other): + m_Pool(a_Other.m_Pool) { - #if __cplusplus < 201103L - // auto_ptr style interface for memory management - if (!m_IsOwner) - { - return; - } - #endif for (size_t i = 0; i < NumSections; i++) { - Free(m_Sections[i]); - m_Sections[i] = nullptr; + m_Sections[i] = a_Other.m_Sections[i]; + a_Other.m_Sections[i] = nullptr; } } @@ -64,85 +51,60 @@ cChunkData::~cChunkData() -#if __cplusplus < 201103L - // auto_ptr style interface for memory management - cChunkData::cChunkData(const cChunkData & a_Other) : - m_IsOwner(true), - m_Pool(a_Other.m_Pool) - { - // Move contents and ownership from a_Other to this, pointer-wise: - for (size_t i = 0; i < NumSections; i++) - { - m_Sections[i] = a_Other.m_Sections[i]; - } - a_Other.m_IsOwner = false; - } +cChunkData::~cChunkData() +{ + Clear(); +} - cChunkData & cChunkData::operator =(const cChunkData & a_Other) +void cChunkData::Assign(const cChunkData & a_Other) +{ + // If assigning to self, no-op + if (&a_Other == this) { - // If assigning to self, no-op - if (&a_Other == this) - { - return *this; - } - - // Free any currently held contents: - if (m_IsOwner) - { - for (size_t i = 0; i < NumSections; i++) - { - Free(m_Sections[i]); - m_Sections[i] = nullptr; - } - } - - // Move contents and ownership from a_Other to this, pointer-wise: - m_IsOwner = true; - for (size_t i = 0; i < NumSections; i++) - { - m_Sections[i] = a_Other.m_Sections[i]; - } - a_Other.m_IsOwner = false; - ASSERT(&m_Pool == &a_Other.m_Pool); - return *this; + return; } -#else - - // unique_ptr style interface for memory management - cChunkData::cChunkData(cChunkData && other) : - m_Pool(other.m_Pool) + Clear(); + for (size_t i = 0; i < NumSections; ++i) { - for (size_t i = 0; i < NumSections; i++) + if (a_Other.m_Sections[i] != nullptr) { - m_Sections[i] = other.m_Sections[i]; - other.m_Sections[i] = nullptr; + m_Sections[i] = Allocate(); + *m_Sections[i] = *a_Other.m_Sections[i]; } } +} - cChunkData & cChunkData::operator =(cChunkData && other) +void cChunkData::Assign(cChunkData && a_Other) +{ + if (&a_Other == this) { - if (&other != this) - { - ASSERT(&m_Pool == &other.m_Pool); - for (size_t i = 0; i < NumSections; i++) - { - Free(m_Sections[i]); - m_Sections[i] = other.m_Sections[i]; - other.m_Sections[i] = nullptr; - } - } - return *this; + return; } -#endif + + 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; + } +} @@ -325,18 +287,45 @@ NIBBLETYPE cChunkData::GetSkyLight(int a_RelX, int a_RelY, int a_RelZ) const -cChunkData cChunkData::Copy(void) const +const cChunkData::sChunkSection * cChunkData::GetSection(size_t a_SectionNum) const { - cChunkData copy(m_Pool); - for (size_t i = 0; i < NumSections; i++) + 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) { - copy.m_Sections[i] = copy.Allocate(); - *copy.m_Sections[i] = *m_Sections[i]; + Free(m_Sections[i]); + m_Sections[i] = nullptr; } } - return copy; } @@ -569,6 +558,23 @@ void cChunkData::SetSkyLight(const NIBBLETYPE * a_Src) +UInt32 cChunkData::NumPresentSections() const +{ + UInt32 Ret = 0U; + for (size_t i = 0; i < NumSections; i++) + { + if (m_Sections[i] != nullptr) + { + ++Ret; + } + } + return Ret; +} + + + + + cChunkData::sChunkSection * cChunkData::Allocate(void) { return m_Pool.Allocate(); -- cgit v1.2.3