Cuberite
A lightweight, fast and extensible game server for Minecraft
ChunkData.cpp
Go to the documentation of this file.
1 
2 // ChunkData.cpp
3 
4 // Implements the cChunkData class that represents the block's type, meta, blocklight and skylight storage for a chunk
5 
6 #include "Globals.h"
7 #include "ChunkData.h"
8 #include "BlockType.h"
9 
10 
11 
12 
13 
14 namespace
15 {
16  struct SectionIndices
17  {
18  size_t Section = 0; // Index into m_Sections
19  size_t Index = 0; // Index into a single sChunkSection
20  };
21 
22  inline SectionIndices IndicesFromRelPos(const Vector3i a_RelPos)
23  {
25 
26  return
27  {
28  static_cast<size_t>(a_RelPos.y / cChunkDef::SectionHeight),
29  cChunkDef::MakeIndex(a_RelPos.x, a_RelPos.y % cChunkDef::SectionHeight, a_RelPos.z)
30  };
31  }
32 
33  bool IsCompressed(const size_t ElementCount)
34  {
35  return ElementCount != ChunkBlockData::SectionBlockCount;
36  }
37 
38  template <size_t ElementCount, typename ValueType>
39  ValueType UnpackDefaultValue(const ValueType DefaultValue)
40  {
41  if (IsCompressed(ElementCount))
42  {
43  return DefaultValue & 0xF;
44  }
45 
46  return DefaultValue;
47  }
48 } // namespace (anonymous)
49 
50 
51 
52 
53 
54 template<class ElementType, size_t ElementCount, ElementType DefaultValue>
56 {
57  for (size_t Y = 0; Y != cChunkDef::NumSections; Y++)
58  {
59  Store[Y].reset();
60 
61  if (const auto & Other = a_Other.Store[Y]; Other != nullptr)
62  {
63  Store[Y] = std::make_unique<Type>(*Other);
64  }
65  }
66 }
67 
68 
69 
70 
71 
72 template<class ElementType, size_t ElementCount, ElementType DefaultValue>
74 {
75  const auto Indices = IndicesFromRelPos(a_Position);
76  const auto & Section = Store[Indices.Section];
77 
78  if (Section != nullptr)
79  {
80  if (IsCompressed(ElementCount))
81  {
82  return cChunkDef::ExpandNibble(Section->data(), Indices.Index);
83  }
84  else
85  {
86  return (*Section)[Indices.Index];
87  }
88  }
89 
90  return UnpackDefaultValue<ElementCount>(DefaultValue);
91 }
92 
93 
94 
95 
96 
97 template<class ElementType, size_t ElementCount, ElementType DefaultValue>
99 {
100  return Store[a_Y].get();
101 }
102 
103 
104 
105 
106 
107 template<class ElementType, size_t ElementCount, ElementType DefaultValue>
108 void ChunkDataStore<ElementType, ElementCount, DefaultValue>::Set(const Vector3i a_Position, const ElementType a_Value)
109 {
110  const auto Indices = IndicesFromRelPos(a_Position);
111  auto & Section = Store[Indices.Section];
112 
113  if (Section == nullptr)
114  {
115  if (a_Value == UnpackDefaultValue<ElementCount>(DefaultValue))
116  {
117  return;
118  }
119 
120  Section = cpp20::make_unique_for_overwrite<Type>();
121  std::fill(Section->begin(), Section->end(), DefaultValue);
122  }
123 
124  if (IsCompressed(ElementCount))
125  {
126  cChunkDef::PackNibble(Section->data(), Indices.Index, a_Value);
127  }
128  else
129  {
130  (*Section)[Indices.Index] = a_Value;
131  }
132 }
133 
134 
135 
136 
137 
138 template<class ElementType, size_t ElementCount, ElementType DefaultValue>
139 void ChunkDataStore<ElementType, ElementCount, DefaultValue>::SetSection(const ElementType (& a_Source)[ElementCount], const size_t a_Y)
140 {
141  auto & Section = Store[a_Y];
142  const auto SourceEnd = std::end(a_Source);
143 
144  if (Section != nullptr)
145  {
146  std::copy(a_Source, SourceEnd, Section->begin());
147  }
148  else if (std::any_of(a_Source, SourceEnd, [](const auto Value) { return Value != DefaultValue; }))
149  {
150  Section = cpp20::make_unique_for_overwrite<Type>();
151  std::copy(a_Source, SourceEnd, Section->begin());
152  }
153 }
154 
155 
156 
157 
158 
159 template<class ElementType, size_t ElementCount, ElementType DefaultValue>
161 {
162  for (size_t Y = 0; Y != cChunkDef::NumSections; Y++)
163  {
164  SetSection(*reinterpret_cast<const ElementType (*)[ElementCount]>(a_Source + Y * ElementCount), Y);
165  }
166 }
167 
168 
169 
170 
171 
173 {
174  m_Blocks.Assign(a_Other.m_Blocks);
175  m_Metas.Assign(a_Other.m_Metas);
176 }
177 
178 
179 
180 
181 
182 void ChunkBlockData::SetAll(const cChunkDef::BlockTypes & a_BlockSource, const cChunkDef::BlockNibbles & a_MetaSource)
183 {
184  m_Blocks.SetAll(a_BlockSource);
185  m_Metas.SetAll(a_MetaSource);
186 }
187 
188 
189 
190 
191 
192 void ChunkBlockData::SetSection(const SectionType & a_BlockSource, const SectionMetaType & a_MetaSource, const size_t a_Y)
193 {
194  m_Blocks.SetSection(a_BlockSource, a_Y);
195  m_Metas.SetSection(a_MetaSource, a_Y);
196 }
197 
198 
199 
200 
201 
203 {
205  m_SkyLights.Assign(a_Other.m_SkyLights);
206 }
207 
208 
209 
210 
211 
212 void ChunkLightData::SetAll(const cChunkDef::BlockNibbles & a_BlockLightSource, const cChunkDef::BlockNibbles & a_SkyLightSource)
213 {
214  m_BlockLights.SetAll(a_BlockLightSource);
215  m_SkyLights.SetAll(a_SkyLightSource);
216 }
217 
218 
219 
220 
221 
222 void ChunkLightData::SetSection(const SectionType & a_BlockLightSource, const SectionType & a_SkyLightSource, const size_t a_Y)
223 {
224  m_BlockLights.SetSection(a_BlockLightSource, a_Y);
225  m_SkyLights.SetSection(a_SkyLightSource, a_Y);
226 }
227 
228 
229 
230 
231 
#define ASSERT(x)
Definition: Globals.h:276
std::array< ElementType, ElementCount > Type
Definition: ChunkData.h:22
void SetSection(const ElementType(&a_Source)[ElementCount], size_t a_Y)
Copies the data from the specified flat section array into the internal representation.
Definition: ChunkData.cpp:139
Type * GetSection(size_t a_Y) const
Returns a raw pointer to the internal representation of the specified section.
Definition: ChunkData.cpp:98
ElementType Get(Vector3i a_Position) const
Gets one value at the given position.
Definition: ChunkData.cpp:73
void Assign(const ChunkDataStore< ElementType, ElementCount, DefaultValue > &a_Other)
Copy assign from another ChunkDataStore.
Definition: ChunkData.cpp:55
void SetAll(const ElementType(&a_Source)[cChunkDef::NumSections *ElementCount])
Copies the data from the specified flat array into the internal representation.
Definition: ChunkData.cpp:160
std::unique_ptr< Type > Store[cChunkDef::NumSections]
Contains all the sections this ChunkDataStore manages.
Definition: ChunkData.h:48
void Set(Vector3i a_Position, ElementType a_Value)
Sets one value at the given position.
Definition: ChunkData.cpp:108
void SetAll(const cChunkDef::BlockTypes &a_BlockSource, const cChunkDef::BlockNibbles &a_MetaSource)
Definition: ChunkData.cpp:182
static constexpr size_t SectionBlockCount
Definition: ChunkData.h:59
NIBBLETYPE[SectionMetaCount] SectionMetaType
Definition: ChunkData.h:66
void Assign(const ChunkBlockData &a_Other)
Definition: ChunkData.cpp:172
void SetSection(const SectionType &a_BlockSource, const SectionMetaType &a_MetaSource, size_t a_Y)
Definition: ChunkData.cpp:192
BLOCKTYPE[SectionBlockCount] SectionType
Definition: ChunkData.h:65
ChunkDataStore< NIBBLETYPE, SectionMetaCount, DefaultMetaValue > m_Metas
Definition: ChunkData.h:71
ChunkDataStore< BLOCKTYPE, SectionBlockCount, DefaultValue > m_Blocks
Definition: ChunkData.h:70
void SetAll(const cChunkDef::BlockNibbles &a_BlockLightSource, const cChunkDef::BlockNibbles &a_SkyLightSource)
Definition: ChunkData.cpp:212
NIBBLETYPE[SectionLightCount] SectionType
Definition: ChunkData.h:106
ChunkDataStore< NIBBLETYPE, SectionLightCount, DefaultBlockLightValue > m_BlockLights
Definition: ChunkData.h:110
void SetSection(const SectionType &a_BlockLightSource, const SectionType &a_SkyLightSource, size_t a_Y)
Definition: ChunkData.cpp:222
ChunkDataStore< NIBBLETYPE, SectionLightCount, DefaultSkyLightValue > m_SkyLights
Definition: ChunkData.h:111
void Assign(const ChunkLightData &a_Other)
Definition: ChunkData.cpp:202
BLOCKTYPE BlockTypes[NumBlocks]
The type used for block type operations and storage, AXIS_ORDER ordering.
Definition: ChunkDef.h:140
static bool IsValidRelPos(Vector3i a_RelPos)
Validates a chunk relative coordinate.
Definition: ChunkDef.h:199
static void PackNibble(NIBBLETYPE *const a_Buffer, const size_t a_Index, const NIBBLETYPE a_Nibble)
Definition: ChunkDef.h:346
static size_t MakeIndex(int x, int y, int z)
Definition: ChunkDef.h:227
static NIBBLETYPE ExpandNibble(const NIBBLETYPE *const a_Buffer, const size_t a_Index)
Definition: ChunkDef.h:357
NIBBLETYPE BlockNibbles[NumBlocks/2]
The type used for block data in nibble format, AXIS_ORDER ordering.
Definition: ChunkDef.h:143
static const size_t NumSections
Definition: ChunkDef.h:129
static const int SectionHeight
Definition: ChunkDef.h:128
T x
Definition: Vector3.h:17
T y
Definition: Vector3.h:17
T z
Definition: Vector3.h:17