1
0
Fork 0

Optimise chunk set (#4260)

Closes #1244

Initially I was just going to add the cChunkData to cSetChunkData but profiling revealed 
that the copying wasn't even the biggest slowdown. Much more time was being spent in 
cChunk::CreateBlockEntities and cChunk::WakeUpSimulators than was in memcpy so I've made 
those significantly faster as well.

Optimisations performed:
 * cSetChunkData now stores blocks in a cChunkData object
 * cChunkData objects can now perform moves even if they are using different pools
 * cChunk::CreateBlockEntities now iterates in the correct order and only over present chunk sections
 * Similarly for cChunk::WakeUpSimulators
 * cSetChunkData::CalculateHeightMap now shortcuts to the highest present chunk section before checking blocks directly
This commit is contained in:
peterbell10 2018-07-23 19:12:51 +01:00 committed by GitHub
parent e27290f7d2
commit 31a11a6df4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 194 additions and 166 deletions

View File

@ -32,6 +32,25 @@ public:
/** Frees the pointer passed in a_ptr, invalidating it */ /** Frees the pointer passed in a_ptr, invalidating it */
virtual void Free(T * a_ptr) = 0; virtual void Free(T * a_ptr) = 0;
/** Two pools compare equal if memory allocated by one can be freed by the other */
bool IsEqual(const cAllocationPool & a_Other) const NOEXCEPT
{
return ((this == &a_Other) || DoIsEqual(a_Other) || a_Other.DoIsEqual(*this));
}
friend bool operator == (const cAllocationPool & a_Lhs, const cAllocationPool & a_Rhs)
{
return a_Lhs.IsEqual(a_Rhs);
}
friend bool operator != (const cAllocationPool & a_Lhs, const cAllocationPool & a_Rhs)
{
return !a_Lhs.IsEqual(a_Rhs);
}
private:
virtual bool DoIsEqual(const cAllocationPool & a_Other) const NOEXCEPT = 0;
}; };
@ -40,16 +59,17 @@ public:
/** Allocates memory storing unused elements in a linked list. Keeps at least NumElementsInReserve /** Allocates memory storing unused elements in a linked list. Keeps at least NumElementsInReserve
elements in the list unless malloc fails so that the program has a reserve to handle OOM. */ elements in the list unless malloc fails so that the program has a reserve to handle OOM. */
template <class T, size_t NumElementsInReserve> template <class T>
class cListAllocationPool: class cListAllocationPool:
public cAllocationPool<T> public cAllocationPool<T>
{ {
public: public:
cListAllocationPool(std::unique_ptr<typename cAllocationPool<T>::cStarvationCallbacks> a_Callbacks): cListAllocationPool(std::unique_ptr<typename cAllocationPool<T>::cStarvationCallbacks> a_Callbacks, size_t a_NumElementsInReserve):
m_NumElementsInReserve(a_NumElementsInReserve),
m_Callbacks(std::move(a_Callbacks)) m_Callbacks(std::move(a_Callbacks))
{ {
for (size_t i = 0; i < NumElementsInReserve; i++) for (size_t i = 0; i < m_NumElementsInReserve; i++)
{ {
void * space = malloc(sizeof(T)); void * space = malloc(sizeof(T));
if (space == nullptr) if (space == nullptr)
@ -74,7 +94,7 @@ public:
virtual T * Allocate() override virtual T * Allocate() override
{ {
if (m_FreeList.size() <= NumElementsInReserve) if (m_FreeList.size() <= m_NumElementsInReserve)
{ {
void * space = malloc(sizeof(T)); void * space = malloc(sizeof(T));
if (space != nullptr) if (space != nullptr)
@ -93,7 +113,7 @@ public:
#pragma pop_macro("new") #pragma pop_macro("new")
#endif #endif
} }
else if (m_FreeList.size() == NumElementsInReserve) else if (m_FreeList.size() == m_NumElementsInReserve)
{ {
m_Callbacks->OnStartUsingReserve(); m_Callbacks->OnStartUsingReserve();
} }
@ -134,15 +154,22 @@ public:
// placement destruct. // placement destruct.
a_ptr->~T(); a_ptr->~T();
m_FreeList.push_front(a_ptr); m_FreeList.push_front(a_ptr);
if (m_FreeList.size() == NumElementsInReserve) if (m_FreeList.size() == m_NumElementsInReserve)
{ {
m_Callbacks->OnEndUsingReserve(); m_Callbacks->OnEndUsingReserve();
} }
} }
private: private:
/** The minimum number of elements to keep in the free list before malloc fails */
size_t m_NumElementsInReserve;
std::list<void *> m_FreeList; std::list<void *> m_FreeList;
std::unique_ptr<typename cAllocationPool<T>::cStarvationCallbacks> m_Callbacks; std::unique_ptr<typename cAllocationPool<T>::cStarvationCallbacks> m_Callbacks;
virtual bool DoIsEqual(const cAllocationPool<T> & a_Other) const NOEXCEPT override
{
return (dynamic_cast<const cListAllocationPool<T>*>(&a_Other) != nullptr);
}
}; };

View File

@ -322,26 +322,15 @@ void cChunk::SetAllData(cSetChunkData & a_SetChunkData)
memcpy(m_BiomeMap, a_SetChunkData.GetBiomes(), sizeof(m_BiomeMap)); memcpy(m_BiomeMap, a_SetChunkData.GetBiomes(), sizeof(m_BiomeMap));
memcpy(m_HeightMap, a_SetChunkData.GetHeightMap(), sizeof(m_HeightMap)); memcpy(m_HeightMap, a_SetChunkData.GetHeightMap(), sizeof(m_HeightMap));
m_ChunkData.SetBlockTypes(a_SetChunkData.GetBlockTypes()); m_ChunkData.Assign(std::move(a_SetChunkData.GetChunkData()));
m_ChunkData.SetMetas(a_SetChunkData.GetBlockMetas()); m_IsLightValid = a_SetChunkData.IsLightValid();
if (a_SetChunkData.IsLightValid())
{
m_ChunkData.SetBlockLight(a_SetChunkData.GetBlockLight());
m_ChunkData.SetSkyLight(a_SetChunkData.GetSkyLight());
m_IsLightValid = true;
}
else
{
m_IsLightValid = false;
}
// Clear the block entities present - either the loader / saver has better, or we'll create empty ones: // Clear the block entities present - either the loader / saver has better, or we'll create empty ones:
for (auto & KeyPair : m_BlockEntities) for (auto & KeyPair : m_BlockEntities)
{ {
delete KeyPair.second; delete KeyPair.second;
} }
m_BlockEntities.clear(); m_BlockEntities = std::move(a_SetChunkData.GetBlockEntities());
std::swap(a_SetChunkData.GetBlockEntities(), m_BlockEntities);
// Check that all block entities have a valid blocktype at their respective coords (DEBUG-mode only): // Check that all block entities have a valid blocktype at their respective coords (DEBUG-mode only):
#ifdef _DEBUG #ifdef _DEBUG
@ -504,9 +493,9 @@ void cChunk::WriteBlockArea(cBlockArea & a_Area, int a_MinBlockX, int a_MinBlock
bool cChunk::HasBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ) bool cChunk::HasBlockEntityAt(Vector3i a_BlockPos)
{ {
return (GetBlockEntity(a_BlockX, a_BlockY, a_BlockZ) != nullptr); return (GetBlockEntity(a_BlockPos) != nullptr);
} }
@ -1433,48 +1422,32 @@ int cChunk::GetHeight(int a_X, int a_Z)
void cChunk::CreateBlockEntities(void) void cChunk::CreateBlockEntities(void)
{ {
for (int x = 0; x < Width; x++) for (size_t SectionIdx = 0; SectionIdx != cChunkData::NumSections; ++SectionIdx)
{ {
for (int z = 0; z < Width; z++) const auto * Section = m_ChunkData.GetSection(SectionIdx);
if (Section == nullptr)
{ {
for (int y = 0; y < Height; y++) continue;
}
for (size_t BlockIdx = 0; BlockIdx != cChunkData::SectionBlockCount; ++BlockIdx)
{
auto BlockType = Section->m_BlockTypes[BlockIdx];
if (cBlockEntity::IsBlockEntityBlockType(BlockType))
{ {
BLOCKTYPE BlockType = GetBlock(x, y, z); auto RelPos = IndexToCoordinate(BlockIdx);
switch (BlockType) RelPos.y += SectionIdx * cChunkData::SectionHeight;
auto WorldPos = RelativeToAbsolute(RelPos, m_PosX, m_PosZ);
if (!HasBlockEntityAt(WorldPos))
{ {
case E_BLOCK_BEACON: AddBlockEntityClean(cBlockEntity::CreateByBlockType(
case E_BLOCK_BED: BlockType, GetMeta(RelPos), WorldPos.x, WorldPos.y, WorldPos.z, m_World
case E_BLOCK_TRAPPED_CHEST: ));
case E_BLOCK_CHEST: }
case E_BLOCK_COMMAND_BLOCK: }
case E_BLOCK_DISPENSER: }
case E_BLOCK_DROPPER: }
case E_BLOCK_ENDER_CHEST:
case E_BLOCK_LIT_FURNACE:
case E_BLOCK_FURNACE:
case E_BLOCK_HOPPER:
case E_BLOCK_SIGN_POST:
case E_BLOCK_WALLSIGN:
case E_BLOCK_HEAD:
case E_BLOCK_NOTE_BLOCK:
case E_BLOCK_JUKEBOX:
case E_BLOCK_FLOWER_POT:
case E_BLOCK_MOB_SPAWNER:
case E_BLOCK_BREWING_STAND:
{
if (!HasBlockEntityAt(x + m_PosX * Width, y, z + m_PosZ * Width))
{
AddBlockEntityClean(cBlockEntity::CreateByBlockType(
BlockType, GetMeta(x, y, z),
x + m_PosX * Width, y, z + m_PosZ * Width, m_World
));
}
break;
}
} // switch (BlockType)
} // for y
} // for z
} // for x
} }
@ -1483,48 +1456,56 @@ void cChunk::CreateBlockEntities(void)
void cChunk::WakeUpSimulators(void) void cChunk::WakeUpSimulators(void)
{ {
cSimulator * WaterSimulator = m_World->GetWaterSimulator(); auto * WaterSimulator = m_World->GetWaterSimulator();
cSimulator * LavaSimulator = m_World->GetLavaSimulator(); auto * LavaSimulator = m_World->GetLavaSimulator();
cSimulator * RedstoneSimulator = m_World->GetRedstoneSimulator(); auto * RedstoneSimulator = m_World->GetRedstoneSimulator();
int BaseX = m_PosX * cChunkDef::Width;
int BaseZ = m_PosZ * cChunkDef::Width; for (size_t SectionIdx = 0; SectionIdx != cChunkData::NumSections; ++SectionIdx)
for (int x = 0; x < Width; x++)
{ {
int BlockX = x + BaseX; const auto * Section = m_ChunkData.GetSection(SectionIdx);
for (int z = 0; z < Width; z++) if (Section == nullptr)
{ {
int BlockZ = z + BaseZ; continue;
for (int y = GetHeight(x, z); y >= 0; y--) }
for (size_t BlockIdx = 0; BlockIdx != cChunkData::SectionBlockCount; ++BlockIdx)
{
auto BlockType = Section->m_BlockTypes[BlockIdx];
// Defer calculation until it's actually needed
auto WorldPos = [&]
{ {
BLOCKTYPE Block = GetBlock(x, y, z); auto RelPos = IndexToCoordinate(BlockIdx);
RelPos.y += SectionIdx * cChunkData::SectionHeight;
return RelativeToAbsolute(RelPos, m_PosX, m_PosZ);
};
// The redstone sim takes multiple blocks, use the inbuilt checker // The redstone sim takes multiple blocks, use the inbuilt checker
if (RedstoneSimulator->IsAllowedBlock(Block)) if (RedstoneSimulator->IsAllowedBlock(BlockType))
{
RedstoneSimulator->AddBlock(WorldPos(), this);
continue;
}
switch (BlockType)
{
case E_BLOCK_WATER:
{ {
RedstoneSimulator->AddBlock({BlockX, y, BlockZ}, this); WaterSimulator->AddBlock(WorldPos(), this);
continue; break;
} }
case E_BLOCK_LAVA:
switch (Block)
{ {
case E_BLOCK_WATER: LavaSimulator->AddBlock(WorldPos(), this);
{ break;
WaterSimulator->AddBlock({BlockX, y, BlockZ}, this); }
break; default:
} {
case E_BLOCK_LAVA: break;
{ }
LavaSimulator->AddBlock({BlockX, y, BlockZ}, this); } // switch (BlockType)
break; }
} }
default:
{
break;
}
} // switch (BlockType)
} // for y
} // for z
} // for x
} }

View File

@ -129,7 +129,7 @@ public:
void WriteBlockArea(cBlockArea & a_Area, int a_MinBlockX, int a_MinBlockY, int a_MinBlockZ, int a_DataTypes); void WriteBlockArea(cBlockArea & a_Area, int a_MinBlockX, int a_MinBlockY, int a_MinBlockZ, int a_DataTypes);
/** Returns true if there is a block entity at the coords specified */ /** Returns true if there is a block entity at the coords specified */
bool HasBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ); bool HasBlockEntityAt(Vector3i a_BlockPos);
/** Sets or resets the internal flag that prevents chunk from being unloaded. /** Sets or resets the internal flag that prevents chunk from being unloaded.
The flag is cumulative - it can be set multiple times and then needs to be un-set that many times The flag is cumulative - it can be set multiple times and then needs to be un-set that many times

View File

@ -113,7 +113,7 @@ void cChunkData::Assign(cChunkData && a_Other)
return; return;
} }
if (&m_Pool != &a_Other.m_Pool) if (m_Pool != a_Other.m_Pool)
{ {
// Cannot transfer the memory, do a copy instead // Cannot transfer the memory, do a copy instead
const cChunkData & CopyOther = a_Other; const cChunkData & CopyOther = a_Other;

View File

@ -115,13 +115,13 @@ public:
}; };
cChunkDataCopyCollector(): cChunkDataCopyCollector():
m_Pool(cpp14::make_unique<MemCallbacks>()), m_Pool(cpp14::make_unique<MemCallbacks>(), cChunkData::NumSections), // Keep 1 chunk worth of reserve
m_Data(m_Pool) m_Data(m_Pool)
{ {
} }
cListAllocationPool<cChunkData::sChunkSection, cChunkData::NumSections> m_Pool; // Keep 1 chunk worth of reserve cListAllocationPool<cChunkData::sChunkSection> m_Pool;
cChunkData m_Data; cChunkData m_Data;
protected: protected:

View File

@ -207,19 +207,19 @@ public:
} }
inline static Vector3i IndexToCoordinate( unsigned int index) inline static Vector3i IndexToCoordinate(size_t index)
{ {
#if AXIS_ORDER == AXIS_ORDER_XZY #if AXIS_ORDER == AXIS_ORDER_XZY
return Vector3i( // 1.2 return Vector3i( // 1.2
index % cChunkDef::Width, // X static_cast<int>(index % cChunkDef::Width), // X
index / (cChunkDef::Width * cChunkDef::Width), // Y static_cast<int>(index / (cChunkDef::Width * cChunkDef::Width)), // Y
(index / cChunkDef::Width) % cChunkDef::Width // Z static_cast<int>((index / cChunkDef::Width) % cChunkDef::Width) // Z
); );
#elif AXIS_ORDER == AXIS_ORDER_YZX #elif AXIS_ORDER == AXIS_ORDER_YZX
return Vector3i( // 1.1 return Vector3i( // 1.1
index / (cChunkDef::Height * cChunkDef::Width), // X static_cast<int>(index / (cChunkDef::Height * cChunkDef::Width)), // X
index % cChunkDef::Height, // Y static_cast<int>(index % cChunkDef::Height), // Y
(index / cChunkDef::Height) % cChunkDef::Width // Z static_cast<int>((index / cChunkDef::Height) % cChunkDef::Width) // Z
); );
#endif #endif
} }

View File

@ -38,10 +38,8 @@
cChunkMap::cChunkMap(cWorld * a_World) : cChunkMap::cChunkMap(cWorld * a_World) :
m_World(a_World), m_World(a_World),
m_Pool( m_Pool(
new cListAllocationPool<cChunkData::sChunkSection, 1600>( cpp14::make_unique<cListAllocationPool<cChunkData::sChunkSection>>(
std::unique_ptr<cAllocationPool<cChunkData::sChunkSection>::cStarvationCallbacks>( cpp14::make_unique<cStarvationCallbacks>(), 1600u
new cStarvationCallbacks()
)
) )
) )
{ {

View File

@ -8,6 +8,17 @@
#include "BlockEntities/BlockEntity.h" #include "BlockEntities/BlockEntity.h"
#include "Entities/Entity.h" #include "Entities/Entity.h"
namespace
{
struct sMemCallbacks:
cAllocationPool<cChunkData::sChunkSection>::cStarvationCallbacks
{
virtual void OnStartUsingReserve() override {}
virtual void OnEndUsingReserve() override {}
virtual void OnOutOfReserve() override {}
};
} // namespace (anonymous)
@ -15,6 +26,8 @@
cSetChunkData::cSetChunkData(int a_ChunkX, int a_ChunkZ, bool a_ShouldMarkDirty) : cSetChunkData::cSetChunkData(int a_ChunkX, int a_ChunkZ, bool a_ShouldMarkDirty) :
m_ChunkX(a_ChunkX), m_ChunkX(a_ChunkX),
m_ChunkZ(a_ChunkZ), m_ChunkZ(a_ChunkZ),
m_Pool(cpp14::make_unique<sMemCallbacks>(), cChunkData::NumSections),
m_ChunkData(m_Pool),
m_IsLightValid(false), m_IsLightValid(false),
m_IsHeightMapValid(false), m_IsHeightMapValid(false),
m_AreBiomesValid(false), m_AreBiomesValid(false),
@ -38,29 +51,23 @@ cSetChunkData::cSetChunkData(
cBlockEntities && a_BlockEntities, cBlockEntities && a_BlockEntities,
bool a_ShouldMarkDirty bool a_ShouldMarkDirty
) : ) :
m_ChunkX(a_ChunkX), cSetChunkData(a_ChunkX, a_ChunkZ, a_ShouldMarkDirty)
m_ChunkZ(a_ChunkZ),
m_ShouldMarkDirty(a_ShouldMarkDirty)
{ {
// Check the params' validity: // Check the params' validity:
ASSERT(a_BlockTypes != nullptr); ASSERT(a_BlockTypes != nullptr);
ASSERT(a_BlockMetas != nullptr); ASSERT(a_BlockMetas != nullptr);
// Copy block types and metas: // Copy block types and metas:
memcpy(m_BlockTypes, a_BlockTypes, sizeof(cChunkDef::BlockTypes)); m_ChunkData.SetBlockTypes(a_BlockTypes);
memcpy(m_BlockMetas, a_BlockMetas, sizeof(cChunkDef::BlockNibbles)); m_ChunkData.SetMetas(a_BlockMetas);
// Copy lights, if both given: // Copy lights, if both given:
if ((a_BlockLight != nullptr) && (a_SkyLight != nullptr)) if ((a_BlockLight != nullptr) && (a_SkyLight != nullptr))
{ {
memcpy(m_BlockLight, a_BlockLight, sizeof(m_BlockLight)); m_ChunkData.SetBlockLight(a_BlockLight);
memcpy(m_SkyLight, a_SkyLight, sizeof(m_SkyLight)); m_ChunkData.SetSkyLight(a_SkyLight);
m_IsLightValid = true; m_IsLightValid = true;
} }
else
{
m_IsLightValid = false;
}
// Copy the heightmap, if available: // Copy the heightmap, if available:
if (a_HeightMap != nullptr) if (a_HeightMap != nullptr)
@ -68,10 +75,6 @@ cSetChunkData::cSetChunkData(
memcpy(m_HeightMap, a_HeightMap, sizeof(m_HeightMap)); memcpy(m_HeightMap, a_HeightMap, sizeof(m_HeightMap));
m_IsHeightMapValid = true; m_IsHeightMapValid = true;
} }
else
{
m_IsHeightMapValid = false;
}
// Copy biomes, if available: // Copy biomes, if available:
if (a_Biomes != nullptr) if (a_Biomes != nullptr)
@ -79,10 +82,6 @@ cSetChunkData::cSetChunkData(
memcpy(m_Biomes, a_Biomes, sizeof(m_Biomes)); memcpy(m_Biomes, a_Biomes, sizeof(m_Biomes));
m_AreBiomesValid = true; m_AreBiomesValid = true;
} }
else
{
m_AreBiomesValid = false;
}
// Move entities and blockentities: // Move entities and blockentities:
m_Entities = std::move(a_Entities); m_Entities = std::move(a_Entities);
@ -95,14 +94,25 @@ cSetChunkData::cSetChunkData(
void cSetChunkData::CalculateHeightMap(void) void cSetChunkData::CalculateHeightMap(void)
{ {
// Find the heighest present section in the chunk
size_t MaxSection = 0;
for (size_t i = cChunkData::NumSections - 1; i != 0; --i)
{
if (m_ChunkData.GetSection(i) != nullptr)
{
MaxSection = i;
break;
}
}
const int MaxHeight = static_cast<int>(MaxSection + 1) * cChunkData::SectionHeight - 1;
for (int x = 0; x < cChunkDef::Width; x++) for (int x = 0; x < cChunkDef::Width; x++)
{ {
for (int z = 0; z < cChunkDef::Width; z++) for (int z = 0; z < cChunkDef::Width; z++)
{ {
for (int y = cChunkDef::Height - 1; y > -1; y--) for (int y = MaxHeight; y > -1; y--)
{ {
int index = cChunkDef::MakeIndexNoCheck(x, y, z); if (m_ChunkData.GetBlock({x, y, z}) != E_BLOCK_AIR)
if (m_BlockTypes[index] != E_BLOCK_AIR)
{ {
m_HeightMap[x + z * cChunkDef::Width] = static_cast<HEIGHTTYPE>(y); m_HeightMap[x + z * cChunkDef::Width] = static_cast<HEIGHTTYPE>(y);
break; break;
@ -124,7 +134,7 @@ void cSetChunkData::RemoveInvalidBlockEntities(void)
{ {
cBlockEntity * BlockEntity = itr->second; cBlockEntity * BlockEntity = itr->second;
BLOCKTYPE EntityBlockType = BlockEntity->GetBlockType(); BLOCKTYPE EntityBlockType = BlockEntity->GetBlockType();
BLOCKTYPE WorldBlockType = cChunkDef::GetBlock(m_BlockTypes, BlockEntity->GetRelX(), BlockEntity->GetPosY(), BlockEntity->GetRelZ()); BLOCKTYPE WorldBlockType = m_ChunkData.GetBlock({BlockEntity->GetRelX(), BlockEntity->GetPosY(), BlockEntity->GetRelZ()});
if (EntityBlockType != WorldBlockType) if (EntityBlockType != WorldBlockType)
{ {
// Bad blocktype, remove the block entity: // Bad blocktype, remove the block entity:

View File

@ -3,12 +3,10 @@
// Declares the cSetChunkData class used for sending loaded / generated chunk data into cWorld // Declares the cSetChunkData class used for sending loaded / generated chunk data into cWorld
#pragma once #pragma once
#include "ChunkData.h"
@ -51,17 +49,8 @@ public:
int GetChunkX(void) const { return m_ChunkX; } int GetChunkX(void) const { return m_ChunkX; }
int GetChunkZ(void) const { return m_ChunkZ; } int GetChunkZ(void) const { return m_ChunkZ; }
/** Returns the internal storage of the block types, read-only. */ /** Returns the internal storage of block types, metas and lighting. */
const cChunkDef::BlockTypes & GetBlockTypes(void) const { return m_BlockTypes; } cChunkData & GetChunkData(void) { return m_ChunkData; }
/** Returns the internal storage of the block types, read-only. */
const cChunkDef::BlockNibbles & GetBlockMetas(void) const { return m_BlockMetas; }
/** Returns the internal storage of the block light, read-only. */
const cChunkDef::BlockNibbles & GetBlockLight(void) const { return m_BlockLight; }
/** Returns the internal storage of the block types, read-only. */
const cChunkDef::BlockNibbles & GetSkyLight(void) const { return m_SkyLight; }
/** Returns the internal storage for heightmap, read-only. */ /** Returns the internal storage for heightmap, read-only. */
const cChunkDef::HeightMap & GetHeightMap(void) const { return m_HeightMap; } const cChunkDef::HeightMap & GetHeightMap(void) const { return m_HeightMap; }
@ -101,10 +90,8 @@ protected:
int m_ChunkX; int m_ChunkX;
int m_ChunkZ; int m_ChunkZ;
cChunkDef::BlockTypes m_BlockTypes; cListAllocationPool<cChunkData::sChunkSection> m_Pool;
cChunkDef::BlockNibbles m_BlockMetas; cChunkData m_ChunkData;
cChunkDef::BlockNibbles m_BlockLight;
cChunkDef::BlockNibbles m_SkyLight;
cChunkDef::HeightMap m_HeightMap; cChunkDef::HeightMap m_HeightMap;
cChunkDef::BiomeMap m_Biomes; cChunkDef::BiomeMap m_Biomes;
cEntityList m_Entities; cEntityList m_Entities;

View File

@ -11,15 +11,20 @@ int main(int argc, char** argv)
class cMockAllocationPool class cMockAllocationPool
: public cAllocationPool<cChunkData::sChunkSection> : public cAllocationPool<cChunkData::sChunkSection>
{ {
virtual cChunkData::sChunkSection * Allocate() virtual cChunkData::sChunkSection * Allocate() override
{ {
return new cChunkData::sChunkSection(); return new cChunkData::sChunkSection();
} }
virtual void Free(cChunkData::sChunkSection * a_Ptr) virtual void Free(cChunkData::sChunkSection * a_Ptr) override
{ {
delete a_Ptr; delete a_Ptr;
} }
virtual bool DoIsEqual(const cAllocationPool<cChunkData::sChunkSection> &) const NOEXCEPT override
{
return false;
}
} Pool; } Pool;
{ {

View File

@ -11,15 +11,20 @@ int main(int argc, char** argv)
class cMockAllocationPool class cMockAllocationPool
: public cAllocationPool<cChunkData::sChunkSection> : public cAllocationPool<cChunkData::sChunkSection>
{ {
virtual cChunkData::sChunkSection * Allocate() virtual cChunkData::sChunkSection * Allocate() override
{ {
return new cChunkData::sChunkSection(); return new cChunkData::sChunkSection();
} }
virtual void Free(cChunkData::sChunkSection * a_Ptr) virtual void Free(cChunkData::sChunkSection * a_Ptr) override
{ {
delete a_Ptr; delete a_Ptr;
} }
virtual bool DoIsEqual(const cAllocationPool<cChunkData::sChunkSection> &) const NOEXCEPT override
{
return false;
}
} Pool; } Pool;
{ {
cChunkData buffer(Pool); cChunkData buffer(Pool);

View File

@ -11,15 +11,20 @@ int main(int argc, char** argv)
class cMockAllocationPool class cMockAllocationPool
: public cAllocationPool<cChunkData::sChunkSection> : public cAllocationPool<cChunkData::sChunkSection>
{ {
virtual cChunkData::sChunkSection * Allocate() virtual cChunkData::sChunkSection * Allocate() override
{ {
return new cChunkData::sChunkSection(); return new cChunkData::sChunkSection();
} }
virtual void Free(cChunkData::sChunkSection * a_Ptr) virtual void Free(cChunkData::sChunkSection * a_Ptr) override
{ {
delete a_Ptr; delete a_Ptr;
} }
virtual bool DoIsEqual(const cAllocationPool<cChunkData::sChunkSection>&) const NOEXCEPT override
{
return false;
}
} Pool; } Pool;
{ {
cChunkData buffer(Pool); cChunkData buffer(Pool);

View File

@ -21,16 +21,21 @@ int main(int argc, char ** argv)
// Set up a cChunkData with known contents - all blocks 0x01, all metas 0x02: // Set up a cChunkData with known contents - all blocks 0x01, all metas 0x02:
class cMockAllocationPool class cMockAllocationPool
: public cAllocationPool<cChunkData::sChunkSection> : public cAllocationPool<cChunkData::sChunkSection>
{ {
virtual cChunkData::sChunkSection * Allocate() virtual cChunkData::sChunkSection * Allocate() override
{ {
return new cChunkData::sChunkSection(); return new cChunkData::sChunkSection();
} }
virtual void Free(cChunkData::sChunkSection * a_Ptr) virtual void Free(cChunkData::sChunkSection * a_Ptr) override
{ {
delete a_Ptr; delete a_Ptr;
} }
virtual bool DoIsEqual(const cAllocationPool<cChunkData::sChunkSection> &) const NOEXCEPT override
{
return false;
}
} Pool; } Pool;
cChunkData Data(Pool); cChunkData Data(Pool);
cChunkDef::BlockTypes BlockTypes; cChunkDef::BlockTypes BlockTypes;

View File

@ -8,16 +8,21 @@ int main(int argc, char** argv)
class cMockAllocationPool class cMockAllocationPool
: public cAllocationPool<cChunkData::sChunkSection> : public cAllocationPool<cChunkData::sChunkSection>
{ {
virtual cChunkData::sChunkSection * Allocate() virtual cChunkData::sChunkSection * Allocate() override
{ {
return new cChunkData::sChunkSection(); return new cChunkData::sChunkSection();
} }
virtual void Free(cChunkData::sChunkSection * a_Ptr) virtual void Free(cChunkData::sChunkSection * a_Ptr) override
{ {
delete a_Ptr; delete a_Ptr;
} }
virtual bool DoIsEqual(const cAllocationPool<cChunkData::sChunkSection> &) const NOEXCEPT override
{
return false;
}
} Pool; } Pool;
cChunkData buffer(Pool); cChunkData buffer(Pool);
return 0; return 0;