summaryrefslogtreecommitdiffstats
path: root/src/ChunkData.h
blob: 60eeca81672900896c2d4c6bf4c18202f21c1c97 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133

// 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 "ChunkDef.h"

#include "AllocationPool.h"



#if __cplusplus < 201103L
// auto_ptr style interface for memory management
#else
// unique_ptr style interface for memory management
#endif

class cChunkData
{
private:

	static const int SectionHeight = 16;
	static const size_t NumSections = (cChunkDef::Height / SectionHeight);
	static const size_t SectionBlockCount = SectionHeight * cChunkDef::Width * cChunkDef::Width;

public:

	struct sChunkSection;

	cChunkData(cAllocationPool<cChunkData::sChunkSection> & a_Pool);
	~cChunkData();
	
	#if __cplusplus < 201103L
		// auto_ptr style interface for memory management
		cChunkData(const cChunkData & a_Other);
		cChunkData & operator =(const cChunkData & a_Other);
	#else
		// unique_ptr style interface for memory management
		cChunkData(cChunkData && a_Other);
		cChunkData & operator =(cChunkData && a_ther);
	#endif

	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;
	
	/** Creates a (deep) copy of self. */
	cChunkData Copy(void) const;

	/** 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);

	struct sChunkSection
	{
		BLOCKTYPE  m_BlockTypes   [SectionHeight * 16 * 16]    ;
		NIBBLETYPE m_BlockMetas   [SectionHeight * 16 * 16 / 2];
		NIBBLETYPE m_BlockLight   [SectionHeight * 16 * 16 / 2];
		NIBBLETYPE m_BlockSkyLight[SectionHeight * 16 * 16 / 2];
	};
	
private:
	#if __cplusplus < 201103L
	// auto_ptr style interface for memory management
	mutable bool m_IsOwner;
	#endif

	sChunkSection * m_Sections[NumSections];

	cAllocationPool<cChunkData::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;

};