Simplified cChunkMap chunk storage (#2565)
This commit is contained in:
parent
032dafd7fd
commit
38368f361d
808
src/ChunkMap.cpp
808
src/ChunkMap.cpp
File diff suppressed because it is too large
Load Diff
115
src/ChunkMap.h
115
src/ChunkMap.h
@ -64,8 +64,6 @@ class cChunkMap
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static const int LAYER_SIZE = 32;
|
|
||||||
|
|
||||||
cChunkMap(cWorld * a_World);
|
cChunkMap(cWorld * a_World);
|
||||||
~cChunkMap();
|
~cChunkMap();
|
||||||
|
|
||||||
@ -76,7 +74,6 @@ public:
|
|||||||
void BroadcastBlockBreakAnimation(UInt32 a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage, const cClientHandle * a_Exclude = nullptr);
|
void BroadcastBlockBreakAnimation(UInt32 a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage, const cClientHandle * a_Exclude = nullptr);
|
||||||
void BroadcastBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, const cClientHandle * a_Exclude);
|
void BroadcastBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, const cClientHandle * a_Exclude);
|
||||||
void BroadcastCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player, const cClientHandle * a_Exclude = nullptr);
|
void BroadcastCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player, const cClientHandle * a_Exclude = nullptr);
|
||||||
void BroadcastCollectPickup(const cPickup & a_Pickup, const cPlayer & a_Player, const cClientHandle * a_Exclude = nullptr);
|
|
||||||
void BroadcastDestroyEntity(const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr);
|
void BroadcastDestroyEntity(const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr);
|
||||||
void BroadcastDetachEntity(const cEntity & a_Entity, const cEntity & a_PreviousVehicle);
|
void BroadcastDetachEntity(const cEntity & a_Entity, const cEntity & a_PreviousVehicle);
|
||||||
void BroadcastEntityEffect(const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration, const cClientHandle * a_Exclude = nullptr);
|
void BroadcastEntityEffect(const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration, const cClientHandle * a_Exclude = nullptr);
|
||||||
@ -399,7 +396,7 @@ public:
|
|||||||
void QueueTickBlock(int a_BlockX, int a_BlockY, int a_BlockZ);
|
void QueueTickBlock(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||||
|
|
||||||
/** Returns the CS for locking the chunkmap; only cWorld::cLock may use this function! */
|
/** Returns the CS for locking the chunkmap; only cWorld::cLock may use this function! */
|
||||||
cCriticalSection & GetCS(void) { return m_CSLayers; }
|
cCriticalSection & GetCS(void) { return m_CSChunks; }
|
||||||
|
|
||||||
/** Increments (a_AlwaysTicked == true) or decrements (false) the m_AlwaysTicked counter for the specified chunk.
|
/** Increments (a_AlwaysTicked == true) or decrements (false) the m_AlwaysTicked counter for the specified chunk.
|
||||||
If the m_AlwaysTicked counter is greater than zero, the chunk is ticked in the tick-thread regardless of
|
If the m_AlwaysTicked counter is greater than zero, the chunk is ticked in the tick-thread regardless of
|
||||||
@ -417,64 +414,6 @@ private:
|
|||||||
friend class cChunkStay;
|
friend class cChunkStay;
|
||||||
|
|
||||||
|
|
||||||
class cChunkLayer
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
cChunkLayer(
|
|
||||||
int a_LayerX, int a_LayerZ,
|
|
||||||
cChunkMap * a_Parent,
|
|
||||||
cAllocationPool<cChunkData::sChunkSection> & a_Pool
|
|
||||||
);
|
|
||||||
~cChunkLayer();
|
|
||||||
|
|
||||||
cChunkLayer(const cChunkLayer & a_That) = delete;
|
|
||||||
|
|
||||||
/** Always returns an assigned chunkptr, but the chunk needn't be valid (loaded / generated) - callers must check */
|
|
||||||
cChunkPtr GetChunk( int a_ChunkX, int a_ChunkZ);
|
|
||||||
|
|
||||||
/** Returns the specified chunk, or nullptr if not created yet */
|
|
||||||
cChunk * FindChunk(int a_ChunkX, int a_ChunkZ);
|
|
||||||
|
|
||||||
int GetX(void) const {return m_LayerX; }
|
|
||||||
int GetZ(void) const {return m_LayerZ; }
|
|
||||||
|
|
||||||
int GetNumChunksLoaded(void) const ;
|
|
||||||
|
|
||||||
void GetChunkStats(int & a_NumChunksValid, int & a_NumChunksDirty) const;
|
|
||||||
|
|
||||||
void Save(void);
|
|
||||||
void UnloadUnusedChunks(void);
|
|
||||||
|
|
||||||
/** Collect a mob census, of all mobs, their megatype, their chunk and their distance o closest player */
|
|
||||||
void CollectMobCensus(cMobCensus & a_ToFill);
|
|
||||||
|
|
||||||
/** Try to Spawn Monsters inside all Chunks */
|
|
||||||
void SpawnMobs(cMobSpawner & a_MobSpawner);
|
|
||||||
|
|
||||||
void Tick(std::chrono::milliseconds a_Dt);
|
|
||||||
|
|
||||||
void RemoveClient(cClientHandle * a_Client);
|
|
||||||
|
|
||||||
/** Calls the callback for each entity in the entire world; returns true if all entities processed, false if the callback aborted by returning true */
|
|
||||||
bool ForEachEntity(cEntityCallback & a_Callback); // Lua-accessible
|
|
||||||
|
|
||||||
/** Calls the callback if the entity with the specified ID is found, with the entity object as the callback param. Returns true if entity found. */
|
|
||||||
bool DoWithEntityByID(UInt32 a_EntityID, cEntityCallback & a_Callback, bool & a_CallbackReturn); // Lua-accessible
|
|
||||||
|
|
||||||
/** Returns true if there is an entity with the specified ID within this layer's chunks */
|
|
||||||
bool HasEntity(UInt32 a_EntityID);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
cChunkPtr m_Chunks[LAYER_SIZE * LAYER_SIZE];
|
|
||||||
int m_LayerX;
|
|
||||||
int m_LayerZ;
|
|
||||||
cChunkMap * m_Parent;
|
|
||||||
int m_NumChunksLoaded;
|
|
||||||
|
|
||||||
cAllocationPool<cChunkData::sChunkSection> & m_Pool;
|
|
||||||
};
|
|
||||||
|
|
||||||
class cStarvationCallbacks
|
class cStarvationCallbacks
|
||||||
: public cAllocationPool<cChunkData::sChunkSection>::cStarvationCallbacks
|
: public cAllocationPool<cChunkData::sChunkSection>::cStarvationCallbacks
|
||||||
{
|
{
|
||||||
@ -492,27 +431,29 @@ private:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::list<cChunkLayer *> cChunkLayerList;
|
struct ChunkCoordinate
|
||||||
|
{
|
||||||
|
struct Comparer
|
||||||
|
{
|
||||||
|
bool operator() (const ChunkCoordinate & a_Lhs, const ChunkCoordinate & a_Rhs) const
|
||||||
|
{
|
||||||
|
return ((a_Lhs.ChunkX == a_Rhs.ChunkX) ? (a_Lhs.ChunkZ < a_Rhs.ChunkZ) : (a_Lhs.ChunkX < a_Rhs.ChunkX));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
int ChunkX;
|
||||||
|
int ChunkZ;
|
||||||
|
};
|
||||||
|
|
||||||
typedef std::list<cChunkStay *> cChunkStays;
|
typedef std::list<cChunkStay *> cChunkStays;
|
||||||
|
|
||||||
/** Finds the cChunkLayer object responsible for the specified chunk; returns nullptr if not found. Assumes m_CSLayers is locked. */
|
cCriticalSection m_CSChunks;
|
||||||
cChunkLayer * FindLayerForChunk(int a_ChunkX, int a_ChunkZ);
|
|
||||||
|
|
||||||
/** Returns the specified cChunkLayer object; returns nullptr if not found. Assumes m_CSLayers is locked. */
|
/** A map of chunk coordinates to chunk pointers
|
||||||
cChunkLayer * FindLayer(int a_LayerX, int a_LayerZ);
|
Uses a map (as opposed to unordered_map) because sorted maps are apparently faster */
|
||||||
|
std::map<ChunkCoordinate, std::unique_ptr<cChunk>, ChunkCoordinate::Comparer> m_Chunks;
|
||||||
|
|
||||||
/** Returns the cChunkLayer object responsible for the specified chunk; creates it if not found. */
|
cEvent m_evtChunkValid; // Set whenever any chunk becomes valid, via ChunkValidated()
|
||||||
cChunkLayer * GetLayerForChunk (int a_ChunkX, int a_ChunkZ);
|
|
||||||
|
|
||||||
/** Returns the specified cChunkLayer object; creates it if not found. */
|
|
||||||
cChunkLayer * GetLayer(int a_LayerX, int a_LayerZ);
|
|
||||||
|
|
||||||
void RemoveLayer(cChunkLayer * a_Layer);
|
|
||||||
|
|
||||||
cCriticalSection m_CSLayers;
|
|
||||||
std::map<std::pair<int, int>, cChunkLayer> m_Layers;
|
|
||||||
cEvent m_evtChunkValid; // Set whenever any chunk becomes valid, via ChunkValidated()
|
|
||||||
|
|
||||||
cWorld * m_World;
|
cWorld * m_World;
|
||||||
|
|
||||||
@ -521,9 +462,19 @@ private:
|
|||||||
|
|
||||||
std::unique_ptr<cAllocationPool<cChunkData::sChunkSection> > m_Pool;
|
std::unique_ptr<cAllocationPool<cChunkData::sChunkSection> > m_Pool;
|
||||||
|
|
||||||
cChunkPtr GetChunk (int a_ChunkX, int a_ChunkZ); // Also queues the chunk for loading / generating if not valid
|
/** Returns or creates and returns a chunk pointer corresponding to the given chunk coordinates.
|
||||||
cChunkPtr GetChunkNoGen (int a_ChunkX, int a_ChunkZ); // Also queues the chunk for loading if not valid; doesn't generate
|
Emplaces this chunk in the chunk map.
|
||||||
cChunkPtr GetChunkNoLoad(int a_ChunkX, int a_ChunkZ); // Doesn't load, doesn't generate
|
Developers SHOULD use the GetChunk variants instead of this function. */
|
||||||
|
cChunkPtr ConstructChunk(int a_ChunkX, int a_ChunkZ);
|
||||||
|
|
||||||
|
/** Constructs a chunk and queues it for loading / generating if not valid, returning it */
|
||||||
|
cChunkPtr GetChunk(int a_ChunkX, int a_ChunkZ);
|
||||||
|
|
||||||
|
/** Constructs a chunk and queues the chunk for loading if not valid, returning it; doesn't generate */
|
||||||
|
cChunkPtr GetChunkNoGen(int a_ChunkX, int a_ChunkZ);
|
||||||
|
|
||||||
|
/** Constructs a chunk, returning it. Doesn't load, doesn't generate */
|
||||||
|
cChunkPtr GetChunkNoLoad(int a_ChunkX, int a_ChunkZ);
|
||||||
|
|
||||||
/** Gets a block in any chunk while in the cChunk's Tick() method; returns true if successful, false if chunk not loaded (doesn't queue load) */
|
/** Gets a block in any chunk while in the cChunk's Tick() method; returns true if successful, false if chunk not loaded (doesn't queue load) */
|
||||||
bool LockedGetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta);
|
bool LockedGetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta);
|
||||||
@ -540,7 +491,7 @@ private:
|
|||||||
/** Fast-sets a block in any chunk while in the cChunk's Tick() method; returns true if successful, false if chunk not loaded (doesn't queue load) */
|
/** Fast-sets a block in any chunk while in the cChunk's Tick() method; returns true if successful, false if chunk not loaded (doesn't queue load) */
|
||||||
bool LockedFastSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
|
bool LockedFastSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
|
||||||
|
|
||||||
/** Locates a chunk ptr in the chunkmap; doesn't create it when not found; assumes m_CSLayers is locked. To be called only from cChunkMap. */
|
/** Locates a chunk ptr in the chunkmap; doesn't create it when not found; assumes m_CSChunks is locked. To be called only from cChunkMap. */
|
||||||
cChunk * FindChunk(int a_ChunkX, int a_ChunkZ);
|
cChunk * FindChunk(int a_ChunkX, int a_ChunkZ);
|
||||||
|
|
||||||
/** Adds a new cChunkStay descendant to the internal list of ChunkStays; loads its chunks.
|
/** Adds a new cChunkStay descendant to the internal list of ChunkStays; loads its chunks.
|
||||||
|
Loading…
Reference in New Issue
Block a user