// ChunkData.h
// Declares the cChunkData class that represents the block's type, meta, blocklight and skylight storage for a chunk
#pragma once
#include <cstring>
#include "AllocationPool.h"
class cChunkData
{
public:
static const int SectionHeight = 16;
static const size_t NumSections = (cChunkDef::Height / SectionHeight);
static const size_t SectionBlockCount = SectionHeight * cChunkDef::Width * cChunkDef::Width;
struct sChunkSection
{
BLOCKTYPE m_BlockTypes[SectionBlockCount];
NIBBLETYPE m_BlockMetas[SectionBlockCount / 2];
NIBBLETYPE m_BlockLight[SectionBlockCount / 2];
NIBBLETYPE m_BlockSkyLight[SectionBlockCount / 2];
};
cChunkData(cAllocationPool<sChunkSection> & a_Pool);
cChunkData(cChunkData && a_Other);
~cChunkData();
cChunkData & operator = (cChunkData && a_Other)
{
Assign(std::move(a_Other));
return *this;
}
/** Copy assign from another cChunkData */
void Assign(const cChunkData & a_Other);
/** Move assign from another cChunkData */
void Assign(cChunkData && a_Other);
BLOCKTYPE GetBlock(int a_X, int a_Y, int a_Z) const;
void SetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_Block);
NIBBLETYPE GetMeta(int a_RelX, int a_RelY, int a_RelZ) const;
bool SetMeta(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_Nibble);
NIBBLETYPE GetBlockLight(int a_RelX, int a_RelY, int a_RelZ) const;
NIBBLETYPE GetSkyLight(int a_RelX, int a_RelY, int a_RelZ) const;
/** Return a pointer to the chunk section or nullptr if all air */
const sChunkSection * GetSection(size_t a_SectionNum) const;
/** Returns a bitmask of chunk sections which are currently stored. */
UInt16 GetSectionBitmask() const;
/** Clears all data */
void Clear();
/** 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;
/** Copies the metadata into the specified flat array. */
void CopyMetas(NIBBLETYPE * a_Dest) const;
/** Copies the block light data into the specified flat array. */
void CopyBlockLight(NIBBLETYPE * a_Dest) const;
/** Copies the skylight data into the specified flat array. */
void CopySkyLight (NIBBLETYPE * a_Dest) const;
/** 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);
/** 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);
/** 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);
/** Returns the number of sections present (i.e. non-air). */
UInt32 NumPresentSections() const;
private:
sChunkSection * m_Sections[NumSections];
cAllocationPool<sChunkSection> & m_Pool;
/** Allocates a new section. Entry-point to custom allocators. */
sChunkSection * Allocate(void);
/** Frees the specified section, previously allocated using Allocate().
Note that a_Section may be nullptr. */
void Free(sChunkSection * a_Section);
/** Sets the data in the specified section to their default values. */
void ZeroSection(sChunkSection * a_Section) const;
};