Implemented Allocation Pool use by cChunkData
This commit is contained in:
parent
6991c2dd84
commit
8be3a8f7dc
@ -1,36 +1,52 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
template<class T, size_t BufferSize, class StarvationCallbacks>
|
||||
class AllocationPool {
|
||||
#include <memory>
|
||||
|
||||
template<class T, size_t BufferSize>
|
||||
class cAllocationPool {
|
||||
public:
|
||||
|
||||
class cStarvationCallbacks
|
||||
{
|
||||
public:
|
||||
virtual ~cStarvationCallbacks() {}
|
||||
virtual void OnStartingUsingBuffer() = 0;
|
||||
virtual void OnStopUsingBuffer() = 0;
|
||||
virtual void OnBufferEmpty() = 0;
|
||||
};
|
||||
|
||||
~AllocationPool()
|
||||
cAllocationPool(std::auto_ptr<cStarvationCallbacks> a_Callbacks) :
|
||||
m_Callbacks(a_Callbacks)
|
||||
{
|
||||
}
|
||||
|
||||
~cAllocationPool()
|
||||
{
|
||||
while (!m_FreeList.empty())
|
||||
{
|
||||
delete m_FreeList.front();
|
||||
free (m_FreeList.front());
|
||||
m_FreeList.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
T* Allocate()
|
||||
{
|
||||
if (m_FreeList.Size() <= BufferSize)
|
||||
if (m_FreeList.size() <= BufferSize)
|
||||
{
|
||||
try
|
||||
{
|
||||
return new T;
|
||||
return new(malloc(sizeof(T))) T;
|
||||
}
|
||||
catch (std::bad_alloc& ex)
|
||||
catch (std::bad_alloc&)
|
||||
{
|
||||
if (m_FreeList.size() == BufferSize)
|
||||
{
|
||||
StarvationCallbacks.OnStartingUsingBuffer();
|
||||
m_Callbacks->OnStartingUsingBuffer();
|
||||
}
|
||||
else if (m_FreeList.empty())
|
||||
{
|
||||
StarvationCallbacks.OnBufferEmpty();
|
||||
m_Callbacks->OnBufferEmpty();
|
||||
// Try again until the memory is avalable
|
||||
return Allocate();
|
||||
}
|
||||
@ -48,10 +64,11 @@ class AllocationPool {
|
||||
m_FreeList.push_front(ptr);
|
||||
if (m_FreeList.size() == BufferSize)
|
||||
{
|
||||
StarvationCallbacks.OnStopUsingBuffer();
|
||||
m_Callbacks->OnStopUsingBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::list<void *> m_FreeList;
|
||||
}
|
||||
std::auto_ptr<cStarvationCallbacks> m_Callbacks;
|
||||
};
|
||||
|
@ -64,7 +64,8 @@ sSetBlock::sSetBlock( int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_Bloc
|
||||
cChunk::cChunk(
|
||||
int a_ChunkX, int a_ChunkY, int a_ChunkZ,
|
||||
cChunkMap * a_ChunkMap, cWorld * a_World,
|
||||
cChunk * a_NeighborXM, cChunk * a_NeighborXP, cChunk * a_NeighborZM, cChunk * a_NeighborZP
|
||||
cChunk * a_NeighborXM, cChunk * a_NeighborXP, cChunk * a_NeighborZM, cChunk * a_NeighborZP,
|
||||
cAllocationPool<cChunkData::sChunkSection,1600>& a_Pool
|
||||
) :
|
||||
m_IsValid(false),
|
||||
m_IsLightValid(false),
|
||||
@ -77,6 +78,7 @@ cChunk::cChunk(
|
||||
m_PosZ(a_ChunkZ),
|
||||
m_World(a_World),
|
||||
m_ChunkMap(a_ChunkMap),
|
||||
m_ChunkData(a_Pool),
|
||||
m_BlockTickX(0),
|
||||
m_BlockTickY(0),
|
||||
m_BlockTickZ(0),
|
||||
|
@ -65,7 +65,8 @@ public:
|
||||
cChunk(
|
||||
int a_ChunkX, int a_ChunkY, int a_ChunkZ, // Chunk coords
|
||||
cChunkMap * a_ChunkMap, cWorld * a_World, // Parent objects
|
||||
cChunk * a_NeighborXM, cChunk * a_NeighborXP, cChunk * a_NeighborZM, cChunk * a_NeighborZP // Neighbor chunks
|
||||
cChunk * a_NeighborXM, cChunk * a_NeighborXP, cChunk * a_NeighborZM, cChunk * a_NeighborZP, // Neighbor chunks
|
||||
cAllocationPool<cChunkData::sChunkSection,1600>& a_Pool
|
||||
);
|
||||
cChunk(cChunk& other);
|
||||
~cChunk();
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
cChunkData cChunkData::Copy() const
|
||||
{
|
||||
cChunkData copy;
|
||||
cChunkData copy(m_Pool);
|
||||
for (int i = 0; i < CHUNK_SECTION_NUM; i++)
|
||||
{
|
||||
if (m_Sections[i] != NULL)
|
||||
@ -360,14 +360,14 @@ void cChunkData::SetSkyLight (const NIBBLETYPE * a_src)
|
||||
cChunkData::sChunkSection * cChunkData::Allocate() const
|
||||
{
|
||||
// TODO: use a allocation pool
|
||||
return new cChunkData::sChunkSection;
|
||||
return m_Pool.Allocate();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void cChunkData::Free(cChunkData::sChunkSection * ptr) const
|
||||
{
|
||||
delete ptr;
|
||||
m_Pool.Free(ptr);
|
||||
}
|
||||
|
||||
|
||||
|
@ -7,6 +7,8 @@
|
||||
|
||||
#include "ChunkDef.h"
|
||||
|
||||
#include "AllocationPool.h"
|
||||
|
||||
|
||||
#define CHUNK_SECTION_HEIGHT 16
|
||||
#define CHUNK_SECTION_NUM (256 / CHUNK_SECTION_HEIGHT)
|
||||
@ -21,11 +23,14 @@ class cChunkData
|
||||
{
|
||||
public:
|
||||
|
||||
cChunkData()
|
||||
struct sChunkSection;
|
||||
|
||||
cChunkData(cAllocationPool<cChunkData::sChunkSection, 1600>& a_Pool) :
|
||||
#if __cplusplus < 201103L
|
||||
// auto_ptr style interface for memory management
|
||||
: IsOwner(true)
|
||||
IsOwner(true),
|
||||
#endif
|
||||
m_Pool(a_Pool)
|
||||
{
|
||||
memset(m_Sections, 0, sizeof(m_Sections));
|
||||
}
|
||||
@ -44,7 +49,8 @@ public:
|
||||
#if __cplusplus < 201103L
|
||||
// auto_ptr style interface for memory management
|
||||
cChunkData(const cChunkData& other) :
|
||||
IsOwner(true)
|
||||
IsOwner(true),
|
||||
m_Pool(other.m_Pool)
|
||||
{
|
||||
for (int i = 0; i < CHUNK_SECTION_NUM; i++)
|
||||
{
|
||||
@ -70,13 +76,15 @@ public:
|
||||
m_Sections[i] = other.m_Sections[i];
|
||||
}
|
||||
other.IsOwner = false;
|
||||
ASSERT(&m_Pool == &other.m_Pool);
|
||||
}
|
||||
return *this;
|
||||
|
||||
}
|
||||
#else
|
||||
// unique_ptr style interface for memory management
|
||||
cChunkData(cChunkData&& other)
|
||||
cChunkData(cChunkData&& other) :
|
||||
m_Pool(other.m_Pool)
|
||||
{
|
||||
for (int i = 0; i < CHUNK_SECTION_NUM; i++)
|
||||
{
|
||||
@ -95,6 +103,7 @@ public:
|
||||
m_Sections[i] = other.m_Sections[i];
|
||||
other.m_Sections[i] = 0;
|
||||
}
|
||||
ASSERT(&m_Pool == &other.m_Pool);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
@ -252,13 +261,6 @@ public:
|
||||
void SetLight (const NIBBLETYPE * a_src);
|
||||
void SetSkyLight (const NIBBLETYPE * a_src);
|
||||
|
||||
private:
|
||||
|
||||
#if __cplusplus < 201103L
|
||||
// auto_ptr style interface for memory management
|
||||
mutable bool IsOwner;
|
||||
#endif
|
||||
|
||||
struct sChunkSection {
|
||||
BLOCKTYPE m_BlockTypes [CHUNK_SECTION_HEIGHT * 16 * 16] ;
|
||||
NIBBLETYPE m_BlockMeta [CHUNK_SECTION_HEIGHT * 16 * 16 / 2];
|
||||
@ -266,12 +268,21 @@ private:
|
||||
NIBBLETYPE m_BlockSkyLight[CHUNK_SECTION_HEIGHT * 16 * 16 / 2];
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
#if __cplusplus < 201103L
|
||||
// auto_ptr style interface for memory management
|
||||
mutable bool IsOwner;
|
||||
#endif
|
||||
|
||||
sChunkSection *m_Sections[CHUNK_SECTION_NUM];
|
||||
|
||||
sChunkSection * Allocate() const;
|
||||
void Free(sChunkSection * ptr) const;
|
||||
|
||||
void ZeroSection(sChunkSection * ptr) const;
|
||||
|
||||
cAllocationPool<cChunkData::sChunkSection, 1600>& m_Pool;
|
||||
};
|
||||
|
||||
|
||||
|
@ -34,7 +34,8 @@
|
||||
// cChunkMap:
|
||||
|
||||
cChunkMap::cChunkMap(cWorld * a_World )
|
||||
: m_World( a_World )
|
||||
: m_World( a_World ),
|
||||
m_Pool(std::auto_ptr<cAllocationPool<cChunkData::sChunkSection,1600>::cStarvationCallbacks>(new cStarvationCallbacks()))
|
||||
{
|
||||
}
|
||||
|
||||
@ -78,7 +79,7 @@ cChunkMap::cChunkLayer * cChunkMap::GetLayer(int a_LayerX, int a_LayerZ)
|
||||
}
|
||||
|
||||
// Not found, create new:
|
||||
cChunkLayer * Layer = new cChunkLayer(a_LayerX, a_LayerZ, this);
|
||||
cChunkLayer * Layer = new cChunkLayer(a_LayerX, a_LayerZ, this, m_Pool);
|
||||
if (Layer == NULL)
|
||||
{
|
||||
LOGERROR("cChunkMap: Cannot create new layer, server out of memory?");
|
||||
@ -2646,11 +2647,13 @@ void cChunkMap::QueueTickBlock(int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// cChunkMap::cChunkLayer:
|
||||
|
||||
cChunkMap::cChunkLayer::cChunkLayer(int a_LayerX, int a_LayerZ, cChunkMap * a_Parent)
|
||||
cChunkMap::cChunkLayer::cChunkLayer(int a_LayerX, int a_LayerZ, cChunkMap * a_Parent,
|
||||
cAllocationPool<cChunkData::sChunkSection,1600>& a_Pool)
|
||||
: m_LayerX( a_LayerX )
|
||||
, m_LayerZ( a_LayerZ )
|
||||
, m_Parent( a_Parent )
|
||||
, m_NumChunksLoaded( 0 )
|
||||
, m_Pool(a_Pool)
|
||||
{
|
||||
memset(m_Chunks, 0, sizeof(m_Chunks));
|
||||
}
|
||||
@ -2692,7 +2695,7 @@ cChunkPtr cChunkMap::cChunkLayer::GetChunk( int a_ChunkX, int a_ChunkY, int a_Ch
|
||||
cChunk * neixp = (LocalX < LAYER_SIZE - 1) ? m_Chunks[Index + 1] : m_Parent->FindChunk(a_ChunkX + 1, a_ChunkZ);
|
||||
cChunk * neizm = (LocalZ > 0) ? m_Chunks[Index - LAYER_SIZE] : m_Parent->FindChunk(a_ChunkX , a_ChunkZ - 1);
|
||||
cChunk * neizp = (LocalZ < LAYER_SIZE - 1) ? m_Chunks[Index + LAYER_SIZE] : m_Parent->FindChunk(a_ChunkX , a_ChunkZ + 1);
|
||||
m_Chunks[Index] = new cChunk(a_ChunkX, 0, a_ChunkZ, m_Parent, m_Parent->GetWorld(), neixm, neixp, neizm, neizp);
|
||||
m_Chunks[Index] = new cChunk(a_ChunkX, 0, a_ChunkZ, m_Parent, m_Parent->GetWorld(), neixm, neixp, neizm, neizp, m_Pool);
|
||||
}
|
||||
return m_Chunks[Index];
|
||||
}
|
||||
|
@ -347,7 +347,8 @@ private:
|
||||
class cChunkLayer
|
||||
{
|
||||
public:
|
||||
cChunkLayer(int a_LayerX, int a_LayerZ, cChunkMap * a_Parent);
|
||||
cChunkLayer(int a_LayerX, int a_LayerZ, cChunkMap * a_Parent,
|
||||
cAllocationPool<cChunkData::sChunkSection,1600>& a_Pool);
|
||||
~cChunkLayer();
|
||||
|
||||
/** Always returns an assigned chunkptr, but the chunk needn't be valid (loaded / generated) - callers must check */
|
||||
@ -391,6 +392,16 @@ private:
|
||||
int m_LayerZ;
|
||||
cChunkMap * m_Parent;
|
||||
int m_NumChunksLoaded;
|
||||
|
||||
cAllocationPool<cChunkData::sChunkSection,1600> & m_Pool;
|
||||
};
|
||||
|
||||
class cStarvationCallbacks
|
||||
: public cAllocationPool<cChunkData::sChunkSection,1600>::cStarvationCallbacks
|
||||
{
|
||||
virtual void OnStartingUsingBuffer() {}
|
||||
virtual void OnStopUsingBuffer() {}
|
||||
virtual void OnBufferEmpty() {}
|
||||
};
|
||||
|
||||
typedef std::list<cChunkLayer *> cChunkLayerList;
|
||||
@ -423,6 +434,8 @@ private:
|
||||
/** The cChunkStay descendants that are currently enabled in this chunkmap */
|
||||
cChunkStays m_ChunkStays;
|
||||
|
||||
cAllocationPool<cChunkData::sChunkSection,1600> m_Pool;
|
||||
|
||||
cChunkPtr GetChunk (int a_ChunkX, int a_ChunkY, int a_ChunkZ); // Also queues the chunk for loading / generating if not valid
|
||||
cChunkPtr GetChunkNoGen (int a_ChunkX, int a_ChunkY, int a_ChunkZ); // Also queues the chunk for loading if not valid; doesn't generate
|
||||
cChunkPtr GetChunkNoLoad(int a_ChunkX, int a_ChunkY, int a_ChunkZ); // Doesn't load, doesn't generate
|
||||
|
@ -6,9 +6,18 @@
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
class cStarvationCallbacks
|
||||
: public cAllocationPool<cChunkData::sChunkSection,1600>::cStarvationCallbacks
|
||||
{
|
||||
virtual void OnStartingUsingBuffer() {}
|
||||
virtual void OnStopUsingBuffer() {}
|
||||
virtual void OnBufferEmpty() {}
|
||||
};
|
||||
cAllocationPool<cChunkData::sChunkSection,1600> Pool(std::auto_ptr<cAllocationPool<cChunkData::sChunkSection,1600>::cStarvationCallbacks>(new cStarvationCallbacks()));
|
||||
{
|
||||
|
||||
// Test first segment
|
||||
cChunkData buffer;
|
||||
cChunkData buffer(Pool);
|
||||
|
||||
BLOCKTYPE* SrcBlockBuffer = new BLOCKTYPE[16 * 16 * 256];
|
||||
memset(SrcBlockBuffer, 0x00, 16 * 16 * 256);
|
||||
@ -45,7 +54,7 @@ int main(int argc, char** argv)
|
||||
|
||||
{
|
||||
// test following segment
|
||||
cChunkData buffer;
|
||||
cChunkData buffer(Pool);
|
||||
|
||||
BLOCKTYPE* SrcBlockBuffer = new BLOCKTYPE[16 * 16 * 256];
|
||||
memset(SrcBlockBuffer, 0x00, 16 * 16 * 256);
|
||||
@ -82,7 +91,7 @@ int main(int argc, char** argv)
|
||||
|
||||
{
|
||||
// test zeros
|
||||
cChunkData buffer;
|
||||
cChunkData buffer(Pool);
|
||||
|
||||
BLOCKTYPE* SrcBlockBuffer = new BLOCKTYPE[16 * 16 * 256];
|
||||
memset(SrcBlockBuffer, 0x00, 16 * 16 * 256);
|
||||
|
@ -6,8 +6,16 @@
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
class cStarvationCallbacks
|
||||
: public cAllocationPool<cChunkData::sChunkSection,1600>::cStarvationCallbacks
|
||||
{
|
||||
cChunkData buffer;
|
||||
virtual void OnStartingUsingBuffer() {}
|
||||
virtual void OnStopUsingBuffer() {}
|
||||
virtual void OnBufferEmpty() {}
|
||||
};
|
||||
cAllocationPool<cChunkData::sChunkSection,1600> Pool(std::auto_ptr<cAllocationPool<cChunkData::sChunkSection,1600>::cStarvationCallbacks>(new cStarvationCallbacks()));
|
||||
{
|
||||
cChunkData buffer(Pool);
|
||||
|
||||
// Empty chunks
|
||||
buffer.SetBlock(0,0,0, 0xAB);
|
||||
@ -105,7 +113,7 @@ int main(int argc, char** argv)
|
||||
}
|
||||
|
||||
{
|
||||
cChunkData buffer;
|
||||
cChunkData buffer(Pool);
|
||||
|
||||
// Zero's
|
||||
buffer.SetBlock(0,0,0, 0x0);
|
||||
@ -122,9 +130,9 @@ int main(int argc, char** argv)
|
||||
|
||||
{
|
||||
// Operator =
|
||||
cChunkData buffer;
|
||||
cChunkData buffer(Pool);
|
||||
buffer.SetBlock(0,0,0,0x42);
|
||||
cChunkData copy;
|
||||
cChunkData copy(Pool);
|
||||
#if __cplusplus < 201103L
|
||||
copy = buffer;
|
||||
#else
|
||||
|
@ -6,8 +6,16 @@
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
class cStarvationCallbacks
|
||||
: public cAllocationPool<cChunkData::sChunkSection,1600>::cStarvationCallbacks
|
||||
{
|
||||
cChunkData buffer;
|
||||
virtual void OnStartingUsingBuffer() {}
|
||||
virtual void OnStopUsingBuffer() {}
|
||||
virtual void OnBufferEmpty() {}
|
||||
};
|
||||
cAllocationPool<cChunkData::sChunkSection,1600> Pool(std::auto_ptr<cAllocationPool<cChunkData::sChunkSection,1600>::cStarvationCallbacks>(new cStarvationCallbacks()));
|
||||
{
|
||||
cChunkData buffer(Pool);
|
||||
|
||||
buffer.SetBlock(3,1,4,0xDE);
|
||||
buffer.SetMeta(3,1,4,0xA);
|
||||
@ -47,7 +55,7 @@ int main(int argc, char** argv)
|
||||
|
||||
}
|
||||
{
|
||||
cChunkData buffer;
|
||||
cChunkData buffer(Pool);
|
||||
|
||||
NIBBLETYPE * SrcNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/2];
|
||||
for (int i = 0; i < 16 * 16 * 256 / 2; i += 4)
|
||||
@ -80,7 +88,7 @@ int main(int argc, char** argv)
|
||||
|
||||
}
|
||||
{
|
||||
cChunkData buffer;
|
||||
cChunkData buffer(Pool);
|
||||
|
||||
NIBBLETYPE * SrcNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/2];
|
||||
for (int i = 0; i < 16 * 16 * 256 / 2; i += 4)
|
||||
@ -114,7 +122,7 @@ int main(int argc, char** argv)
|
||||
|
||||
}
|
||||
{
|
||||
cChunkData buffer;
|
||||
cChunkData buffer(Pool);
|
||||
|
||||
NIBBLETYPE * SrcNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/2];
|
||||
for (int i = 0; i < 16 * 16 * 256 / 2; i += 4)
|
||||
@ -148,7 +156,7 @@ int main(int argc, char** argv)
|
||||
|
||||
}
|
||||
{
|
||||
cChunkData buffer;
|
||||
cChunkData buffer(Pool);
|
||||
|
||||
BLOCKTYPE * SrcBlockBuffer = new BLOCKTYPE[16 * 16 * 256];
|
||||
memset(SrcBlockBuffer, 0x00, 16 * 16 * 256);
|
||||
|
@ -4,6 +4,14 @@
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
cChunkData buffer;
|
||||
class cStarvationCallbacks
|
||||
: public cAllocationPool<cChunkData::sChunkSection,1600>::cStarvationCallbacks
|
||||
{
|
||||
virtual void OnStartingUsingBuffer() {}
|
||||
virtual void OnStopUsingBuffer() {}
|
||||
virtual void OnBufferEmpty() {}
|
||||
};
|
||||
cAllocationPool<cChunkData::sChunkSection,1600> Pool(std::auto_ptr<cAllocationPool<cChunkData::sChunkSection,1600>::cStarvationCallbacks>(new cStarvationCallbacks()));
|
||||
cChunkData buffer(Pool);
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user