summaryrefslogtreecommitdiffstats
path: root/src/ChunkData.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/ChunkData.h193
1 files changed, 110 insertions, 83 deletions
diff --git a/src/ChunkData.h b/src/ChunkData.h
index 3b4c9c867..a984b752e 100644
--- a/src/ChunkData.h
+++ b/src/ChunkData.h
@@ -9,132 +9,159 @@
#pragma once
+#include "FunctionRef.h"
+#include "ChunkDef.h"
-#include <cstring>
-#include "AllocationPool.h"
-#include "ChunkDef.h"
-class cChunkData
+
+template <class ElementType, size_t ElementCount, ElementType DefaultValue>
+struct ChunkDataStore
{
-public:
+ using Type = std::array<ElementType, ElementCount>;
- static const int SectionHeight = 16;
- static const size_t NumSections = (cChunkDef::Height / SectionHeight);
- static const size_t SectionBlockCount = SectionHeight * cChunkDef::Width * cChunkDef::Width;
+ /** Copy assign from another ChunkDataStore. */
+ void Assign(const ChunkDataStore<ElementType, ElementCount, DefaultValue> & a_Other);
- struct sChunkSection
- {
- BLOCKTYPE m_BlockTypes[SectionBlockCount];
- NIBBLETYPE m_BlockMetas[SectionBlockCount / 2];
- NIBBLETYPE m_BlockLight[SectionBlockCount / 2];
- NIBBLETYPE m_BlockSkyLight[SectionBlockCount / 2];
- };
+ /** Gets one value at the given position.
+ Returns DefaultValue if the section is not allocated. */
+ ElementType Get(Vector3i a_Position) const;
- cChunkData(cAllocationPool<sChunkSection> & a_Pool);
- cChunkData(cChunkData && a_Other);
- ~cChunkData();
+ /** Returns a raw pointer to the internal representation of the specified section.
+ Will be nullptr if the section is not allocated. */
+ Type * GetSection(size_t a_Y) const;
- cChunkData & operator = (cChunkData && a_Other)
- {
- Assign(std::move(a_Other));
- return *this;
- }
+ /** Sets one value at the given position.
+ Allocates a section if needed for the operation. */
+ void Set(Vector3i a_Position, ElementType a_Value);
+
+ /** Copies the data from the specified flat section array into the internal representation.
+ Allocates a section if needed for the operation. */
+ void SetSection(const ElementType (& a_Source)[ElementCount], size_t a_Y);
- /** Copy assign from another cChunkData */
- void Assign(const cChunkData & a_Other);
+ /** Copies the data from the specified flat array into the internal representation.
+ Allocates sections that are needed for the operation. */
+ void SetAll(const ElementType (& a_Source)[cChunkDef::NumSections * ElementCount]);
- /** Move assign from another cChunkData */
- void Assign(cChunkData && a_Other);
+ /** Contains all the sections this ChunkDataStore manages. */
+ std::unique_ptr<Type> Store[cChunkDef::NumSections];
+};
+
+
+
+
+
+class ChunkBlockData
+{
+public:
- BLOCKTYPE GetBlock(Vector3i a_RelPos) const;
- void SetBlock(Vector3i a_RelPos, BLOCKTYPE a_Block);
+ static constexpr size_t SectionBlockCount = cChunkDef::SectionHeight * cChunkDef::Width * cChunkDef::Width;
+ static constexpr size_t SectionMetaCount = SectionBlockCount / 2;
- NIBBLETYPE GetMeta(Vector3i a_RelPos) const;
- bool SetMeta(Vector3i a_RelPos, NIBBLETYPE a_Nibble);
+ static constexpr BLOCKTYPE DefaultValue = 0x00;
+ static constexpr NIBBLETYPE DefaultMetaValue = 0x00;
- NIBBLETYPE GetBlockLight(Vector3i a_RelPos) const;
+ using SectionType = BLOCKTYPE[SectionBlockCount];
+ using SectionMetaType = NIBBLETYPE[SectionMetaCount];
- NIBBLETYPE GetSkyLight(Vector3i a_RelPos) const;
+private:
- /** Return a pointer to the chunk section or nullptr if all air */
- const sChunkSection * GetSection(size_t a_SectionNum) const;
+ ChunkDataStore<BLOCKTYPE, SectionBlockCount, DefaultValue> m_Blocks;
+ ChunkDataStore<NIBBLETYPE, SectionMetaCount, DefaultMetaValue> m_Metas;
- /** Returns a bitmask of chunk sections which are currently stored. */
- UInt16 GetSectionBitmask() const;
+public:
- /** Clears all data */
- void Clear();
+ using BlockArray = decltype(m_Blocks)::Type;
+ using MetaArray = decltype(m_Metas)::Type;
- /** Copies the blocktype data into the specified flat array.
- Optionally, only a part of the data is copied, as specified by the a_Idx and a_Length parameters. */
- void CopyBlockTypes(BLOCKTYPE * a_Dest, size_t a_Idx = 0, size_t a_Length = cChunkDef::NumBlocks) const;
+ void Assign(const ChunkBlockData & a_Other);
- /** Copies the metadata into the specified flat array. */
- void CopyMetas(NIBBLETYPE * a_Dest) const;
+ BLOCKTYPE GetBlock(Vector3i a_Position) const { return m_Blocks.Get(a_Position); }
+ NIBBLETYPE GetMeta(Vector3i a_Position) const { return m_Metas.Get(a_Position); }
- /** Copies the block light data into the specified flat array. */
- void CopyBlockLight(NIBBLETYPE * a_Dest) const;
+ BlockArray * GetSection(size_t a_Y) const { return m_Blocks.GetSection(a_Y); }
+ MetaArray * GetMetaSection(size_t a_Y) const { return m_Metas.GetSection(a_Y); }
- /** Copies the skylight data into the specified flat array. */
- void CopySkyLight (NIBBLETYPE * a_Dest) const;
+ void SetBlock(Vector3i a_Position, BLOCKTYPE a_Block) { m_Blocks.Set(a_Position, a_Block); }
+ void SetMeta(Vector3i a_Position, NIBBLETYPE a_Meta) { m_Metas.Set(a_Position, a_Meta); }
- /** Fills the chunk with the specified block. */
- void FillBlockTypes(BLOCKTYPE a_Value);
+ void SetAll(const cChunkDef::BlockTypes & a_BlockSource, const cChunkDef::BlockNibbles & a_MetaSource);
+ void SetSection(const SectionType & a_BlockSource, const SectionMetaType & a_MetaSource, size_t a_Y);
+};
- /** Fills the chunk with the specified meta value. */
- void FillMetas (NIBBLETYPE a_Value);
- /** Fills the chunk with the specified block light. */
- void FillBlockLight(NIBBLETYPE a_Value);
- /** Fills the chunk with the specified sky light. */
- void FillSkyLight (NIBBLETYPE a_Value);
- /** Copies the blocktype data from the specified flat array into the internal representation.
- Allocates sections that are needed for the operation.
- Requires that a_Src is a valid pointer. */
- void SetBlockTypes(const BLOCKTYPE * a_Src);
- /** Copies the metadata from the specified flat array into the internal representation.
- Allocates sectios that are needed for the operation.
- Requires that a_Src is a valid pointer. */
- void SetMetas(const NIBBLETYPE * a_Src);
+class ChunkLightData
+{
+public:
- /** Copies the blocklight data from the specified flat array into the internal representation.
- Allocates sectios that are needed for the operation.
- Allows a_Src to be nullptr, in which case it doesn't do anything. */
- void SetBlockLight(const NIBBLETYPE * a_Src);
+ static constexpr size_t SectionLightCount = (cChunkDef::SectionHeight * cChunkDef::Width * cChunkDef::Width) / 2;
- /** Copies the skylight data from the specified flat array into the internal representation.
- Allocates sectios that are needed for the operation.
- Allows a_Src to be nullptr, in which case it doesn't do anything. */
- void SetSkyLight(const NIBBLETYPE * a_Src);
+ static constexpr NIBBLETYPE DefaultBlockLightValue = 0x00;
+ static constexpr NIBBLETYPE DefaultSkyLightValue = 0xFF;
- /** Returns the number of sections present (i.e. non-air). */
- UInt32 NumPresentSections() const;
+ using SectionType = NIBBLETYPE[SectionLightCount];
private:
- sChunkSection * m_Sections[NumSections];
+ ChunkDataStore<NIBBLETYPE, SectionLightCount, DefaultBlockLightValue> m_BlockLights;
+ ChunkDataStore<NIBBLETYPE, SectionLightCount, DefaultSkyLightValue> m_SkyLights;
+
+public:
- cAllocationPool<sChunkSection> & m_Pool;
+ using LightArray = decltype(m_BlockLights)::Type;
- /** Allocates a new section. Entry-point to custom allocators. */
- sChunkSection * Allocate(void);
+ void Assign(const ChunkLightData & a_Other);
- /** Frees the specified section, previously allocated using Allocate().
- Note that a_Section may be nullptr. */
- void Free(sChunkSection * a_Section);
+ NIBBLETYPE GetBlockLight(Vector3i a_Position) const { return m_BlockLights.Get(a_Position); }
+ NIBBLETYPE GetSkyLight(Vector3i a_Position) const { return m_SkyLights.Get(a_Position); }
- /** Sets the data in the specified section to their default values. */
- void ZeroSection(sChunkSection * a_Section) const;
+ LightArray * GetBlockLightSection(size_t a_Y) const { return m_BlockLights.GetSection(a_Y); }
+ LightArray * GetSkyLightSection(size_t a_Y) const { return m_SkyLights.GetSection(a_Y); }
+ void SetAll(const cChunkDef::BlockNibbles & a_BlockLightSource, const cChunkDef::BlockNibbles & a_SkyLightSource);
+ void SetSection(const SectionType & a_BlockLightSource, const SectionType & a_SkyLightSource, size_t a_Y);
};
+namespace ChunkDef
+{
+ using cForEachSectionCallback = cFunctionRef<void(
+ size_t,
+ ChunkBlockData::BlockArray *,
+ ChunkBlockData::MetaArray *,
+ ChunkLightData::LightArray *,
+ ChunkLightData::LightArray *)>;
+
+ /** Invokes the callback functor for every chunk section containing at least one present block or light section data.
+ This is used to collect all data for all sections. */
+ inline void ForEachSection(const ChunkBlockData & a_BlockData, const ChunkLightData & a_LightData, cForEachSectionCallback a_Callback)
+ {
+ for (size_t Y = 0; Y < cChunkDef::NumSections; ++Y)
+ {
+ const auto Blocks = a_BlockData.GetSection(Y);
+ const auto Metas = a_BlockData.GetMetaSection(Y);
+ const auto BlockLights = a_LightData.GetBlockLightSection(Y);
+ const auto SkyLights = a_LightData.GetSkyLightSection(Y);
+
+ if ((Blocks != nullptr) || (Metas != nullptr) || (BlockLights != nullptr) || (SkyLights != nullptr))
+ {
+ a_Callback(Y, Blocks, Metas, BlockLights, SkyLights);
+ }
+ }
+ }
+}
+
+
+
+
+extern template struct ChunkDataStore<BLOCKTYPE, ChunkBlockData::SectionBlockCount, ChunkBlockData::DefaultValue>;
+extern template struct ChunkDataStore<NIBBLETYPE, ChunkBlockData::SectionMetaCount, ChunkLightData::DefaultBlockLightValue>;
+extern template struct ChunkDataStore<NIBBLETYPE, ChunkLightData::SectionLightCount, ChunkLightData::DefaultSkyLightValue>;