diff options
author | Tiger Wang <ziwei.tiger@hotmail.co.uk> | 2016-08-20 14:34:29 +0200 |
---|---|---|
committer | Tiger Wang <ziwei.tiger@hotmail.co.uk> | 2016-08-20 14:34:29 +0200 |
commit | 7175b9e435a54cff33914d21384625a445cc5cf0 (patch) | |
tree | 7feb44f1e8e4ed7ea4d5bf0ba1d173abd3417f34 /src/ChunkMap.cpp | |
parent | Added cWorld:SetSpawn() API and Lua binding (#3316) (diff) | |
download | cuberite-7175b9e435a54cff33914d21384625a445cc5cf0.tar cuberite-7175b9e435a54cff33914d21384625a445cc5cf0.tar.gz cuberite-7175b9e435a54cff33914d21384625a445cc5cf0.tar.bz2 cuberite-7175b9e435a54cff33914d21384625a445cc5cf0.tar.lz cuberite-7175b9e435a54cff33914d21384625a445cc5cf0.tar.xz cuberite-7175b9e435a54cff33914d21384625a445cc5cf0.tar.zst cuberite-7175b9e435a54cff33914d21384625a445cc5cf0.zip |
Diffstat (limited to 'src/ChunkMap.cpp')
-rw-r--r-- | src/ChunkMap.cpp | 457 |
1 files changed, 249 insertions, 208 deletions
diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index 7c4162b25..abd4eb8bf 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -65,6 +65,8 @@ cChunkMap::~cChunkMap() cChunkPtr cChunkMap::ConstructChunk(int a_ChunkX, int a_ChunkZ) { + ASSERT(GetWorld()->IsInTickThread()); + auto Chunk = FindChunk(a_ChunkX, a_ChunkZ); if (Chunk == nullptr) { @@ -85,6 +87,7 @@ cChunkPtr cChunkMap::ConstructChunk(int a_ChunkX, int a_ChunkZ) ).first ).second.get(); } + return Chunk; } @@ -94,7 +97,7 @@ cChunkPtr cChunkMap::ConstructChunk(int a_ChunkX, int a_ChunkZ) cChunkPtr cChunkMap::GetChunk(int a_ChunkX, int a_ChunkZ) { - ASSERT(m_CSChunks.IsLockedByCurrentThread()); // m_CSChunks should already be locked by the operation that called us + ASSERT(GetWorld()->IsInTickThread()); auto Chunk = ConstructChunk(a_ChunkX, a_ChunkZ); if (Chunk == nullptr) @@ -116,7 +119,7 @@ cChunkPtr cChunkMap::GetChunk(int a_ChunkX, int a_ChunkZ) cChunkPtr cChunkMap::GetChunkNoGen(int a_ChunkX, int a_ChunkZ) { - ASSERT(m_CSChunks.IsLockedByCurrentThread()); // m_CSChunks should already be locked by the operation that called us + ASSERT(GetWorld()->IsInTickThread()); auto Chunk = ConstructChunk(a_ChunkX, a_ChunkZ); if (Chunk == nullptr) @@ -138,7 +141,7 @@ cChunkPtr cChunkMap::GetChunkNoGen(int a_ChunkX, int a_ChunkZ) cChunkPtr cChunkMap::GetChunkNoLoad(int a_ChunkX, int a_ChunkZ) { - ASSERT(m_CSChunks.IsLockedByCurrentThread()); // m_CSChunks should already be locked by the operation that called us + ASSERT(GetWorld()->IsInTickThread()); return ConstructChunk(a_ChunkX, a_ChunkZ); } @@ -148,8 +151,7 @@ cChunkPtr cChunkMap::GetChunkNoLoad(int a_ChunkX, int a_ChunkZ) bool cChunkMap::LockedGetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) { - // We already have m_CSChunks locked since this can be called only from within the tick thread - ASSERT(m_CSChunks.IsLockedByCurrentThread()); + ASSERT(GetWorld()->IsInTickThread()); int ChunkX, ChunkZ; cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); @@ -170,8 +172,7 @@ bool cChunkMap::LockedGetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTY bool cChunkMap::LockedGetBlockType(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType) { - // We already have m_CSChunks locked since this can be called only from within the tick thread - ASSERT(m_CSChunks.IsLockedByCurrentThread()); + ASSERT(GetWorld()->IsInTickThread()); int ChunkX, ChunkZ; cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); @@ -191,8 +192,7 @@ bool cChunkMap::LockedGetBlockType(int a_BlockX, int a_BlockY, int a_BlockZ, BLO bool cChunkMap::LockedGetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE & a_BlockMeta) { - // We already have m_CSChunks locked since this can be called only from within the tick thread - ASSERT(m_CSChunks.IsLockedByCurrentThread()); + ASSERT(GetWorld()->IsInTickThread()); int ChunkX, ChunkZ; cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); @@ -212,7 +212,8 @@ bool cChunkMap::LockedGetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ, NIB bool cChunkMap::LockedSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) { - // We already have m_CSChunks locked since this can be called only from within the tick thread + ASSERT(GetWorld()->IsInTickThread()); + int ChunkX, ChunkZ; cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ChunkZ); @@ -232,6 +233,7 @@ bool cChunkMap::LockedSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTY bool cChunkMap::LockedFastSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) { // We already have m_CSChunks locked since this can be called only from within the tick thread + int ChunkX, ChunkZ; cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ChunkZ); @@ -250,7 +252,7 @@ bool cChunkMap::LockedFastSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLO cChunk * cChunkMap::FindChunk(int a_ChunkX, int a_ChunkZ) { - ASSERT(m_CSChunks.IsLockedByCurrentThread()); + ASSERT(GetWorld()->IsInTickThread()); auto Chunk = m_Chunks.find({ a_ChunkX, a_ChunkZ }); return (Chunk == m_Chunks.end()) ? nullptr : Chunk->second.get(); @@ -262,7 +264,8 @@ cChunk * cChunkMap::FindChunk(int a_ChunkX, int a_ChunkZ) void cChunkMap::BroadcastAttachEntity(const cEntity & a_Entity, const cEntity & a_Vehicle) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); + cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ()); if (Chunk == nullptr) { @@ -278,7 +281,8 @@ void cChunkMap::BroadcastAttachEntity(const cEntity & a_Entity, const cEntity & void cChunkMap::BroadcastBlockAction(int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType, const cClientHandle * a_Exclude) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); + int x, z, ChunkX, ChunkZ; x = a_BlockX; z = a_BlockZ; @@ -298,7 +302,8 @@ void cChunkMap::BroadcastBlockAction(int a_BlockX, int a_BlockY, int a_BlockZ, c void cChunkMap::BroadcastBlockBreakAnimation(UInt32 a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage, const cClientHandle * a_Exclude) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); + int ChunkX, ChunkZ; cChunkDef::BlockToChunk(a_BlockX, a_BlockZ, ChunkX, ChunkZ); @@ -317,7 +322,8 @@ void cChunkMap::BroadcastBlockBreakAnimation(UInt32 a_EntityID, int a_BlockX, in void cChunkMap::BroadcastBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, const cClientHandle * a_Exclude) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); + int ChunkX, ChunkZ; cChunkDef::BlockToChunk(a_BlockX, a_BlockZ, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); @@ -334,7 +340,8 @@ void cChunkMap::BroadcastBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, c void cChunkMap::BroadcastCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player, const cClientHandle * a_Exclude) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); + cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ()); if (Chunk == nullptr) { @@ -350,7 +357,8 @@ void cChunkMap::BroadcastCollectEntity(const cEntity & a_Entity, const cPlayer & void cChunkMap::BroadcastDestroyEntity(const cEntity & a_Entity, const cClientHandle * a_Exclude) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); + cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ()); if (Chunk == nullptr) { @@ -366,7 +374,8 @@ void cChunkMap::BroadcastDestroyEntity(const cEntity & a_Entity, const cClientHa void cChunkMap::BroadcastDetachEntity(const cEntity & a_Entity, const cEntity & a_PreviousVehicle) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); + cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ()); if (Chunk == nullptr) { @@ -382,7 +391,8 @@ void cChunkMap::BroadcastDetachEntity(const cEntity & a_Entity, const cEntity & void cChunkMap::BroadcastEntityEffect(const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration, const cClientHandle * a_Exclude) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); + cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ()); if (Chunk == nullptr) { @@ -398,7 +408,8 @@ void cChunkMap::BroadcastEntityEffect(const cEntity & a_Entity, int a_EffectID, void cChunkMap::BroadcastEntityEquipment(const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item, const cClientHandle * a_Exclude) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); + cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ()); if (Chunk == nullptr) { @@ -414,7 +425,8 @@ void cChunkMap::BroadcastEntityEquipment(const cEntity & a_Entity, short a_SlotN void cChunkMap::BroadcastEntityHeadLook(const cEntity & a_Entity, const cClientHandle * a_Exclude) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); + cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ()); if (Chunk == nullptr) { @@ -430,7 +442,8 @@ void cChunkMap::BroadcastEntityHeadLook(const cEntity & a_Entity, const cClientH void cChunkMap::BroadcastEntityLook(const cEntity & a_Entity, const cClientHandle * a_Exclude) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); + cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ()); if (Chunk == nullptr) { @@ -446,7 +459,8 @@ void cChunkMap::BroadcastEntityLook(const cEntity & a_Entity, const cClientHandl void cChunkMap::BroadcastEntityMetadata(const cEntity & a_Entity, const cClientHandle * a_Exclude) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); + cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ()); if (Chunk == nullptr) { @@ -462,7 +476,8 @@ void cChunkMap::BroadcastEntityMetadata(const cEntity & a_Entity, const cClientH void cChunkMap::BroadcastEntityRelMove(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); + cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ()); if (Chunk == nullptr) { @@ -478,7 +493,8 @@ void cChunkMap::BroadcastEntityRelMove(const cEntity & a_Entity, char a_RelX, ch void cChunkMap::BroadcastEntityRelMoveLook(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); + cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ()); if (Chunk == nullptr) { @@ -494,7 +510,8 @@ void cChunkMap::BroadcastEntityRelMoveLook(const cEntity & a_Entity, char a_RelX void cChunkMap::BroadcastEntityStatus(const cEntity & a_Entity, char a_Status, const cClientHandle * a_Exclude) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); + cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ()); if (Chunk == nullptr) { @@ -510,7 +527,8 @@ void cChunkMap::BroadcastEntityStatus(const cEntity & a_Entity, char a_Status, c void cChunkMap::BroadcastEntityVelocity(const cEntity & a_Entity, const cClientHandle * a_Exclude) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); + cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ()); if (Chunk == nullptr) { @@ -526,7 +544,8 @@ void cChunkMap::BroadcastEntityVelocity(const cEntity & a_Entity, const cClientH void cChunkMap::BroadcastEntityAnimation(const cEntity & a_Entity, char a_Animation, const cClientHandle * a_Exclude) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); + cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ()); if (Chunk == nullptr) { @@ -542,7 +561,8 @@ void cChunkMap::BroadcastEntityAnimation(const cEntity & a_Entity, char a_Animat void cChunkMap::BroadcastParticleEffect(const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount, cClientHandle * a_Exclude) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); + int ChunkX, ChunkZ; cChunkDef::BlockToChunk(FloorC(a_SrcX), FloorC(a_SrcZ), ChunkX, ChunkZ); @@ -561,7 +581,8 @@ void cChunkMap::BroadcastParticleEffect(const AString & a_ParticleName, float a_ void cChunkMap::BroadcastRemoveEntityEffect(const cEntity & a_Entity, int a_EffectID, const cClientHandle * a_Exclude) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); + cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ()); if (Chunk == nullptr) @@ -578,7 +599,8 @@ void cChunkMap::BroadcastRemoveEntityEffect(const cEntity & a_Entity, int a_Effe void cChunkMap::BroadcastSoundEffect(const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); + int ChunkX, ChunkZ; cChunkDef::BlockToChunk(FloorC(std::floor(a_X)), FloorC(std::floor(a_Z)), ChunkX, ChunkZ); @@ -597,7 +619,8 @@ void cChunkMap::BroadcastSoundEffect(const AString & a_SoundName, double a_X, do void cChunkMap::BroadcastSoundParticleEffect(const EffectID a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data, const cClientHandle * a_Exclude) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); + int ChunkX, ChunkZ; cChunkDef::BlockToChunk(a_SrcX, a_SrcZ, ChunkX, ChunkZ); @@ -616,7 +639,8 @@ void cChunkMap::BroadcastSoundParticleEffect(const EffectID a_EffectID, int a_Sr void cChunkMap::BroadcastSpawnEntity(cEntity & a_Entity, const cClientHandle * a_Exclude) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); + cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ()); if (Chunk == nullptr) { @@ -632,7 +656,8 @@ void cChunkMap::BroadcastSpawnEntity(cEntity & a_Entity, const cClientHandle * a void cChunkMap::BroadcastThunderbolt(int a_BlockX, int a_BlockY, int a_BlockZ, const cClientHandle * a_Exclude) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); + int ChunkX, ChunkZ; cChunkDef::BlockToChunk(a_BlockX, a_BlockZ, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); @@ -650,7 +675,8 @@ void cChunkMap::BroadcastThunderbolt(int a_BlockX, int a_BlockY, int a_BlockZ, c void cChunkMap::BroadcastUseBed(const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); + int ChunkX, ChunkZ; cChunkDef::BlockToChunk(a_BlockX, a_BlockZ, ChunkX, ChunkZ); @@ -669,7 +695,8 @@ void cChunkMap::BroadcastUseBed(const cEntity & a_Entity, int a_BlockX, int a_Bl void cChunkMap::SendBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cClientHandle & a_Client) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); + int ChunkX, ChunkZ; cChunkDef::BlockToChunk(a_BlockX, a_BlockZ, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); @@ -686,8 +713,9 @@ void cChunkMap::SendBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cClien bool cChunkMap::UseBlockEntity(cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) { + ASSERT(GetWorld()->IsInTickThread()); // a_Player rclked block entity at the coords specified, handle it - cCSLock Lock(m_CSChunks); + int ChunkX, ChunkZ; cChunkDef::BlockToChunk(a_BlockX, a_BlockZ, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); @@ -704,7 +732,8 @@ bool cChunkMap::UseBlockEntity(cPlayer * a_Player, int a_BlockX, int a_BlockY, i bool cChunkMap::DoWithChunk(int a_ChunkX, int a_ChunkZ, cChunkCallback & a_Callback) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); + cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, a_ChunkZ); if (Chunk == nullptr) { @@ -716,6 +745,7 @@ bool cChunkMap::DoWithChunk(int a_ChunkX, int a_ChunkZ, cChunkCallback & a_Callb bool cChunkMap::DoWithChunkAt(Vector3i a_BlockPos, std::function<bool(cChunk &)> a_Callback) { + ASSERT(GetWorld()->IsInTickThread()); int ChunkX, ChunkZ; cChunkDef::BlockToChunk(a_BlockPos.x, a_BlockPos.z, ChunkX, ChunkZ); struct cCallBackWrapper : cChunkCallback @@ -741,7 +771,8 @@ bool cChunkMap::DoWithChunkAt(Vector3i a_BlockPos, std::function<bool(cChunk &)> void cChunkMap::WakeUpSimulators(int a_BlockX, int a_BlockY, int a_BlockZ) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); + int ChunkX, ChunkZ; cChunkDef::BlockToChunk(a_BlockX, a_BlockZ, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); @@ -758,6 +789,7 @@ void cChunkMap::WakeUpSimulators(int a_BlockX, int a_BlockY, int a_BlockZ) void cChunkMap::WakeUpSimulatorsInArea(int a_MinBlockX, int a_MaxBlockX, int a_MinBlockY, int a_MaxBlockY, int a_MinBlockZ, int a_MaxBlockZ) { + ASSERT(GetWorld()->IsInTickThread()); // Limit the Y coords: a_MinBlockY = std::max(a_MinBlockY, 0); a_MaxBlockY = std::min(a_MaxBlockY, cChunkDef::Height - 1); @@ -766,7 +798,7 @@ void cChunkMap::WakeUpSimulatorsInArea(int a_MinBlockX, int a_MaxBlockX, int a_M int MinChunkX, MinChunkZ, MaxChunkX, MaxChunkZ; cChunkDef::BlockToChunk(a_MinBlockX, a_MinBlockZ, MinChunkX, MinChunkZ); cChunkDef::BlockToChunk(a_MaxBlockX, a_MaxBlockZ, MaxChunkX, MaxChunkZ); - cCSLock Lock(m_CSChunks); + for (int z = MinChunkZ; z <= MaxChunkZ; z++) { int MinZ = std::max(a_MinBlockZ, z * cChunkDef::Width); @@ -800,7 +832,8 @@ void cChunkMap::WakeUpSimulatorsInArea(int a_MinBlockX, int a_MaxBlockX, int a_M void cChunkMap::MarkChunkDirty(int a_ChunkX, int a_ChunkZ) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); + cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ); if ((Chunk == nullptr) || !Chunk->IsValid()) { @@ -815,7 +848,8 @@ void cChunkMap::MarkChunkDirty(int a_ChunkX, int a_ChunkZ) void cChunkMap::MarkChunkSaving(int a_ChunkX, int a_ChunkZ) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); + cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ); if ((Chunk == nullptr) || !Chunk->IsValid()) { @@ -830,7 +864,8 @@ void cChunkMap::MarkChunkSaving(int a_ChunkX, int a_ChunkZ) void cChunkMap::MarkChunkSaved (int a_ChunkX, int a_ChunkZ) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); + cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ); if ((Chunk == nullptr) || !Chunk->IsValid()) { @@ -848,7 +883,8 @@ void cChunkMap::SetChunkData(cSetChunkData & a_SetChunkData) int ChunkX = a_SetChunkData.GetChunkX(); int ChunkZ = a_SetChunkData.GetChunkZ(); { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); + cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ChunkZ); if (Chunk == nullptr) { @@ -893,7 +929,8 @@ void cChunkMap::ChunkLighted( const cChunkDef::BlockNibbles & a_SkyLight ) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); + cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, a_ChunkZ); if (Chunk == nullptr) { @@ -909,7 +946,8 @@ void cChunkMap::ChunkLighted( bool cChunkMap::GetChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataCallback & a_Callback) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); + cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ); if ((Chunk == nullptr) || !Chunk->IsValid()) { @@ -925,7 +963,8 @@ bool cChunkMap::GetChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataCallback & a_ bool cChunkMap::GetChunkBlockTypes(int a_ChunkX, int a_ChunkZ, BLOCKTYPE * a_BlockTypes) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); + cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ); if ((Chunk == nullptr) || !Chunk->IsValid()) { @@ -941,7 +980,8 @@ bool cChunkMap::GetChunkBlockTypes(int a_ChunkX, int a_ChunkZ, BLOCKTYPE * a_Blo bool cChunkMap::IsChunkQueued(int a_ChunkX, int a_ChunkZ) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); + cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, a_ChunkZ); return (Chunk != nullptr) && Chunk->IsQueued(); } @@ -952,7 +992,8 @@ bool cChunkMap::IsChunkQueued(int a_ChunkX, int a_ChunkZ) bool cChunkMap::IsChunkValid(int a_ChunkX, int a_ChunkZ) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); + cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, a_ChunkZ); return (Chunk != nullptr) && Chunk->IsValid(); } @@ -963,7 +1004,8 @@ bool cChunkMap::IsChunkValid(int a_ChunkX, int a_ChunkZ) bool cChunkMap::HasChunkAnyClients(int a_ChunkX, int a_ChunkZ) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); + cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ); return (Chunk != nullptr) && Chunk->HasAnyClients(); } @@ -974,9 +1016,10 @@ bool cChunkMap::HasChunkAnyClients(int a_ChunkX, int a_ChunkZ) int cChunkMap::GetHeight(int a_BlockX, int a_BlockZ) { + ASSERT(GetWorld()->IsInTickThread()); + for (;;) { - cCSLock Lock(m_CSChunks); int ChunkX, ChunkZ, BlockY = 0; cChunkDef::AbsoluteToRelative(a_BlockX, BlockY, a_BlockZ, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunk(ChunkX, ChunkZ); @@ -991,7 +1034,6 @@ int cChunkMap::GetHeight(int a_BlockX, int a_BlockZ) } // The chunk is not valid, wait for it to become valid: - cCSUnlock Unlock(Lock); m_evtChunkValid.Wait(); } // while (true) } @@ -1002,8 +1044,9 @@ int cChunkMap::GetHeight(int a_BlockX, int a_BlockZ) bool cChunkMap::TryGetHeight(int a_BlockX, int a_BlockZ, int & a_Height) { + ASSERT(GetWorld()->IsInTickThread()); // Returns false if chunk not loaded / generated - cCSLock Lock(m_CSChunks); + int ChunkX, ChunkZ, BlockY = 0; cChunkDef::AbsoluteToRelative(a_BlockX, BlockY, a_BlockZ, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ChunkZ); @@ -1021,7 +1064,8 @@ bool cChunkMap::TryGetHeight(int a_BlockX, int a_BlockZ, int & a_Height) void cChunkMap::SetBlocks(const sSetBlockVector & a_Blocks) { - cCSLock lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); + cChunkPtr chunk = nullptr; int lastChunkX = 0x7fffffff; // Bogus coords so that chunk is updated on first pass int lastChunkZ = 0x7fffffff; @@ -1049,6 +1093,7 @@ void cChunkMap::SetBlocks(const sSetBlockVector & a_Blocks) void cChunkMap::CollectPickupsByPlayer(cPlayer & a_Player) { + ASSERT(GetWorld()->IsInTickThread()); int BlockX = static_cast<int>(a_Player.GetPosX()); // Truncating doesn't matter much; we're scanning entire chunks anyway int BlockY = static_cast<int>(a_Player.GetPosY()); int BlockZ = static_cast<int>(a_Player.GetPosZ()); @@ -1060,7 +1105,7 @@ void cChunkMap::CollectPickupsByPlayer(cPlayer & a_Player) // We suppose that each player keeps their chunks in memory, therefore it makes little sense to try to re-load or even generate them. // The only time the chunks are not valid is when the player is downloading the initial world and they should not call this at that moment - cCSLock Lock(m_CSChunks); + GetChunkNoLoad(ChunkX, ChunkZ)->CollectPickupsByPlayer(a_Player); // Check the neighboring chunks as well: @@ -1076,12 +1121,13 @@ void cChunkMap::CollectPickupsByPlayer(cPlayer & a_Player) BLOCKTYPE cChunkMap::GetBlock(int a_BlockX, int a_BlockY, int a_BlockZ) { + ASSERT(GetWorld()->IsInTickThread()); int X = a_BlockX, Y = a_BlockY, Z = a_BlockZ; int ChunkX, ChunkZ; cChunkDef::AbsoluteToRelative(X, Y, Z, ChunkX, ChunkZ); // Query the chunk, if loaded: - cCSLock Lock(m_CSChunks); + cChunkPtr Chunk = GetChunk(ChunkX, ChunkZ); if ((Chunk != nullptr) && Chunk->IsValid()) { @@ -1096,12 +1142,13 @@ BLOCKTYPE cChunkMap::GetBlock(int a_BlockX, int a_BlockY, int a_BlockZ) NIBBLETYPE cChunkMap::GetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ) { + ASSERT(GetWorld()->IsInTickThread()); int X = a_BlockX, Y = a_BlockY, Z = a_BlockZ; int ChunkX, ChunkZ; cChunkDef::AbsoluteToRelative(X, Y, Z, ChunkX, ChunkZ); // Query the chunk, if loaded: - cCSLock Lock(m_CSChunks); + cChunkPtr Chunk = GetChunk(ChunkX, ChunkZ); if ((Chunk != nullptr) && Chunk->IsValid()) { @@ -1116,10 +1163,11 @@ NIBBLETYPE cChunkMap::GetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ) NIBBLETYPE cChunkMap::GetBlockSkyLight(int a_BlockX, int a_BlockY, int a_BlockZ) { + ASSERT(GetWorld()->IsInTickThread()); int ChunkX, ChunkZ; cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); - cCSLock Lock(m_CSChunks); + cChunkPtr Chunk = GetChunk( ChunkX, ChunkZ); if ((Chunk != nullptr) && Chunk->IsValid()) { @@ -1134,10 +1182,11 @@ NIBBLETYPE cChunkMap::GetBlockSkyLight(int a_BlockX, int a_BlockY, int a_BlockZ) NIBBLETYPE cChunkMap::GetBlockBlockLight(int a_BlockX, int a_BlockY, int a_BlockZ) { + ASSERT(GetWorld()->IsInTickThread()); int ChunkX, ChunkZ; cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); - cCSLock Lock(m_CSChunks); + cChunkPtr Chunk = GetChunk( ChunkX, ChunkZ); if ((Chunk != nullptr) && Chunk->IsValid()) { @@ -1152,11 +1201,12 @@ NIBBLETYPE cChunkMap::GetBlockBlockLight(int a_BlockX, int a_BlockY, int a_Block void cChunkMap::SetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_BlockMeta, bool a_ShouldMarkDirty, bool a_ShouldInformClients) { + ASSERT(GetWorld()->IsInTickThread()); int ChunkX, ChunkZ; cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); // a_BlockXYZ now contains relative coords! - cCSLock Lock(m_CSChunks); + cChunkPtr Chunk = GetChunk(ChunkX, ChunkZ); if ((Chunk != nullptr) && Chunk->IsValid()) { @@ -1170,13 +1220,14 @@ void cChunkMap::SetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYP void cChunkMap::SetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, bool a_SendToClients) { + ASSERT(GetWorld()->IsInTickThread()); cChunkInterface ChunkInterface(this); BlockHandler(GetBlock(a_BlockX, a_BlockY, a_BlockZ))->OnDestroyed(ChunkInterface, *m_World, a_BlockX, a_BlockY, a_BlockZ); int ChunkX, ChunkZ, X = a_BlockX, Y = a_BlockY, Z = a_BlockZ; cChunkDef::AbsoluteToRelative( X, Y, Z, ChunkX, ChunkZ); - cCSLock Lock(m_CSChunks); + cChunkPtr Chunk = GetChunk( ChunkX, ChunkZ); if ((Chunk != nullptr) && Chunk->IsValid()) { @@ -1192,10 +1243,11 @@ void cChunkMap::SetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_B bool cChunkMap::GetBlockTypeMeta(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) { + ASSERT(GetWorld()->IsInTickThread()); int ChunkX, ChunkZ, X = a_BlockX, Y = a_BlockY, Z = a_BlockZ; cChunkDef::AbsoluteToRelative( X, Y, Z, ChunkX, ChunkZ); - cCSLock Lock(m_CSChunks); + cChunkPtr Chunk = GetChunk( ChunkX, ChunkZ); if ((Chunk != nullptr) && Chunk->IsValid()) { @@ -1211,10 +1263,11 @@ bool cChunkMap::GetBlockTypeMeta(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCK bool cChunkMap::GetBlockInfo(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_Meta, NIBBLETYPE & a_SkyLight, NIBBLETYPE & a_BlockLight) { + ASSERT(GetWorld()->IsInTickThread()); int ChunkX, ChunkZ, X = a_BlockX, Y = a_BlockY, Z = a_BlockZ; cChunkDef::AbsoluteToRelative( X, Y, Z, ChunkX, ChunkZ); - cCSLock Lock(m_CSChunks); + cChunkPtr Chunk = GetChunk( ChunkX, ChunkZ); if ((Chunk != nullptr) && Chunk->IsValid()) { @@ -1230,7 +1283,8 @@ bool cChunkMap::GetBlockInfo(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE void cChunkMap::ReplaceBlocks(const sSetBlockVector & a_Blocks, BLOCKTYPE a_FilterBlockType) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); + for (sSetBlockVector::const_iterator itr = a_Blocks.begin(); itr != a_Blocks.end(); ++itr) { cChunkPtr Chunk = GetChunk(itr->m_ChunkX, itr->m_ChunkZ); @@ -1251,7 +1305,8 @@ void cChunkMap::ReplaceBlocks(const sSetBlockVector & a_Blocks, BLOCKTYPE a_Filt void cChunkMap::ReplaceTreeBlocks(const sSetBlockVector & a_Blocks) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); + for (sSetBlockVector::const_iterator itr = a_Blocks.begin(); itr != a_Blocks.end(); ++itr) { cChunkPtr Chunk = GetChunk(itr->m_ChunkX, itr->m_ChunkZ); @@ -1285,10 +1340,11 @@ void cChunkMap::ReplaceTreeBlocks(const sSetBlockVector & a_Blocks) EMCSBiome cChunkMap::GetBiomeAt (int a_BlockX, int a_BlockZ) { + ASSERT(GetWorld()->IsInTickThread()); int ChunkX, ChunkZ, X = a_BlockX, Y = 0, Z = a_BlockZ; cChunkDef::AbsoluteToRelative(X, Y, Z, ChunkX, ChunkZ); - cCSLock Lock(m_CSChunks); + cChunkPtr Chunk = GetChunk(ChunkX, ChunkZ); if ((Chunk != nullptr) && Chunk->IsValid()) { @@ -1306,10 +1362,11 @@ EMCSBiome cChunkMap::GetBiomeAt (int a_BlockX, int a_BlockZ) bool cChunkMap::SetBiomeAt(int a_BlockX, int a_BlockZ, EMCSBiome a_Biome) { + ASSERT(GetWorld()->IsInTickThread()); int ChunkX, ChunkZ, X = a_BlockX, Y = 0, Z = a_BlockZ; cChunkDef::AbsoluteToRelative(X, Y, Z, ChunkX, ChunkZ); - cCSLock Lock(m_CSChunks); + cChunkPtr Chunk = GetChunk(ChunkX, ChunkZ); if ((Chunk != nullptr) && Chunk->IsValid()) { @@ -1325,6 +1382,7 @@ bool cChunkMap::SetBiomeAt(int a_BlockX, int a_BlockZ, EMCSBiome a_Biome) bool cChunkMap::SetAreaBiome(int a_MinX, int a_MaxX, int a_MinZ, int a_MaxZ, EMCSBiome a_Biome) { + ASSERT(GetWorld()->IsInTickThread()); // Translate coords to relative: int Y = 0; int MinChunkX, MinChunkZ, MinX = a_MinX, MinZ = a_MinZ; @@ -1334,7 +1392,7 @@ bool cChunkMap::SetAreaBiome(int a_MinX, int a_MaxX, int a_MinZ, int a_MaxZ, EMC // Go through all chunks, set: bool res = true; - cCSLock Lock(m_CSChunks); + for (int x = MinChunkX; x <= MaxChunkX; x++) { int MinRelX = (x == MinChunkX) ? MinX : 0; @@ -1363,8 +1421,9 @@ bool cChunkMap::SetAreaBiome(int a_MinX, int a_MaxX, int a_MinZ, int a_MaxZ, EMC bool cChunkMap::GetBlocks(sSetBlockVector & a_Blocks, bool a_ContinueOnFailure) { + ASSERT(GetWorld()->IsInTickThread()); bool res = true; - cCSLock Lock(m_CSChunks); + for (sSetBlockVector::iterator itr = a_Blocks.begin(); itr != a_Blocks.end(); ++itr) { cChunkPtr Chunk = GetChunk(itr->m_ChunkX, itr->m_ChunkZ); @@ -1389,22 +1448,18 @@ bool cChunkMap::GetBlocks(sSetBlockVector & a_Blocks, bool a_ContinueOnFailure) bool cChunkMap::DigBlock(int a_BlockX, int a_BlockY, int a_BlockZ) { + ASSERT(GetWorld()->IsInTickThread()); int PosX = a_BlockX, PosY = a_BlockY, PosZ = a_BlockZ, ChunkX, ChunkZ; cChunkDef::AbsoluteToRelative(PosX, PosY, PosZ, ChunkX, ChunkZ); - + cChunkPtr DestChunk = GetChunk( ChunkX, ChunkZ); + if ((DestChunk == nullptr) || !DestChunk->IsValid()) { - cCSLock Lock(m_CSChunks); - cChunkPtr DestChunk = GetChunk( ChunkX, ChunkZ); - if ((DestChunk == nullptr) || !DestChunk->IsValid()) - { - return false; - } - - DestChunk->SetBlock(PosX, PosY, PosZ, E_BLOCK_AIR, 0); - m_World->GetSimulatorManager()->WakeUp(a_BlockX, a_BlockY, a_BlockZ, DestChunk); + return false; } + DestChunk->SetBlock(PosX, PosY, PosZ, E_BLOCK_AIR, 0); + m_World->GetSimulatorManager()->WakeUp(a_BlockX, a_BlockY, a_BlockZ, DestChunk); return true; } @@ -1414,14 +1469,14 @@ bool cChunkMap::DigBlock(int a_BlockX, int a_BlockY, int a_BlockZ) void cChunkMap::SendBlockTo(int a_X, int a_Y, int a_Z, cPlayer * a_Player) { + ASSERT(GetWorld()->IsInTickThread()); int ChunkX, ChunkZ; cChunkDef::AbsoluteToRelative(a_X, a_Y, a_Z, ChunkX, ChunkZ); - cCSLock Lock(m_CSChunks); cChunkPtr Chunk = GetChunk(ChunkX, ChunkZ); - if ((Chunk != nullptr) && (Chunk->IsValid())) + if ((Chunk != nullptr) && Chunk->IsValid()) { - Chunk->SendBlockTo(a_X, a_Y, a_Z, a_Player->GetClientHandle()); + Chunk->SendBlockTo(a_X, a_Y, a_Z, a_Player->GetClientHandlePtr()); } } @@ -1431,7 +1486,8 @@ void cChunkMap::SendBlockTo(int a_X, int a_Y, int a_Z, cPlayer * a_Player) void cChunkMap::CompareChunkClients(int a_ChunkX1, int a_ChunkZ1, int a_ChunkX2, int a_ChunkZ2, cClientDiffCallback & a_Callback) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); + cChunkPtr Chunk1 = GetChunkNoGen(a_ChunkX1, a_ChunkZ1); if (Chunk1 == nullptr) { @@ -1452,16 +1508,15 @@ void cChunkMap::CompareChunkClients(int a_ChunkX1, int a_ChunkZ1, int a_ChunkX2, void cChunkMap::CompareChunkClients(cChunk * a_Chunk1, cChunk * a_Chunk2, cClientDiffCallback & a_Callback) { - cClientHandleList Clients1(a_Chunk1->GetAllClients()); - cClientHandleList Clients2(a_Chunk2->GetAllClients()); + ASSERT(GetWorld()->IsInTickThread()); // Find "removed" clients: - for (cClientHandleList::iterator itr1 = Clients1.begin(); itr1 != Clients1.end(); ++itr1) + for (const auto & LhsClient : a_Chunk1->GetAllStrongClientPtrs()) { bool Found = false; - for (cClientHandleList::iterator itr2 = Clients2.begin(); itr2 != Clients2.end(); ++itr2) + for (const auto & RhsClient : a_Chunk2->GetAllStrongClientPtrs()) { - if (*itr1 == *itr2) + if (LhsClient == RhsClient) { Found = true; break; @@ -1469,17 +1524,17 @@ void cChunkMap::CompareChunkClients(cChunk * a_Chunk1, cChunk * a_Chunk2, cClien } // for itr2 - Clients2[] if (!Found) { - a_Callback.Removed(*itr1); + a_Callback.Removed(LhsClient.get()); } } // for itr1 - Clients1[] // Find "added" clients: - for (cClientHandleList::iterator itr2 = Clients2.begin(); itr2 != Clients2.end(); ++itr2) + for (const auto & RhsClient : a_Chunk2->GetAllStrongClientPtrs()) { bool Found = false; - for (cClientHandleList::iterator itr1 = Clients1.begin(); itr1 != Clients1.end(); ++itr1) + for (const auto & LhsClient : a_Chunk1->GetAllStrongClientPtrs()) { - if (*itr1 == *itr2) + if (LhsClient == RhsClient) { Found = true; break; @@ -1487,7 +1542,7 @@ void cChunkMap::CompareChunkClients(cChunk * a_Chunk1, cChunk * a_Chunk2, cClien } // for itr1 - Clients1[] if (!Found) { - a_Callback.Added(*itr2); + a_Callback.Added(RhsClient.get()); } } // for itr2 - Clients2[] } @@ -1496,9 +1551,10 @@ void cChunkMap::CompareChunkClients(cChunk * a_Chunk1, cChunk * a_Chunk2, cClien -bool cChunkMap::AddChunkClient(int a_ChunkX, int a_ChunkZ, cClientHandle * a_Client) +bool cChunkMap::AddChunkClient(int a_ChunkX, int a_ChunkZ, const std::shared_ptr<cClientHandle> & a_Client) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); + cChunkPtr Chunk = GetChunk(a_ChunkX, a_ChunkZ); if (Chunk == nullptr) { @@ -1511,9 +1567,10 @@ bool cChunkMap::AddChunkClient(int a_ChunkX, int a_ChunkZ, cClientHandle * a_Cli -void cChunkMap::RemoveChunkClient(int a_ChunkX, int a_ChunkZ, cClientHandle * a_Client) +void cChunkMap::RemoveChunkClient(int a_ChunkX, int a_ChunkZ, const std::shared_ptr<cClientHandle> & a_Client) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); + cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ); if (Chunk == nullptr) { @@ -1525,53 +1582,19 @@ void cChunkMap::RemoveChunkClient(int a_ChunkX, int a_ChunkZ, cClientHandle * a_ - -void cChunkMap::RemoveClientFromChunks(cClientHandle * a_Client) +void cChunkMap::AddEntity(std::unique_ptr<cEntity> a_Entity) { - cCSLock Lock(m_CSChunks); - for (const auto & Chunk : m_Chunks) - { - Chunk.second->RemoveClient(a_Client); - } -} - - + ASSERT(GetWorld()->IsInTickThread()); - - -void cChunkMap::AddEntity(cEntity * a_Entity) -{ - cCSLock Lock(m_CSChunks); cChunkPtr Chunk = GetChunk(a_Entity->GetChunkX(), a_Entity->GetChunkZ()); if (Chunk == nullptr) // This will assert inside GetChunk in Debug builds { LOGWARNING("Entity at %p (%s, ID %d) spawning in a non-existent chunk, the entity is lost.", - static_cast<void *>(a_Entity), a_Entity->GetClass(), a_Entity->GetUniqueID() + static_cast<void *>(a_Entity.get()), a_Entity->GetClass(), a_Entity->GetUniqueID() ); return; } - Chunk->AddEntity(a_Entity); -} - - - - - -void cChunkMap::AddEntityIfNotPresent(cEntity * a_Entity) -{ - cCSLock Lock(m_CSChunks); - cChunkPtr Chunk = GetChunk(a_Entity->GetChunkX(), a_Entity->GetChunkZ()); - if (Chunk == nullptr) // This will assert inside GetChunk in Debug builds - { - LOGWARNING("Entity at %p (%s, ID %d) spawning in a non-existent chunk, the entity is lost.", - static_cast<void *>(a_Entity), a_Entity->GetClass(), a_Entity->GetUniqueID() - ); - return; - } - if (!Chunk->HasEntity(a_Entity->GetUniqueID())) - { - Chunk->AddEntity(a_Entity); - } + Chunk->AddEntity(std::move(a_Entity)); } @@ -1580,7 +1603,7 @@ void cChunkMap::AddEntityIfNotPresent(cEntity * a_Entity) bool cChunkMap::HasEntity(UInt32 a_UniqueID) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); for (const auto & Chunk : m_Chunks) { if (Chunk.second->IsValid() && Chunk.second->HasEntity(a_UniqueID)) @@ -1595,26 +1618,9 @@ bool cChunkMap::HasEntity(UInt32 a_UniqueID) -void cChunkMap::RemoveEntity(cEntity * a_Entity) -{ - cCSLock Lock(m_CSChunks); - cChunkPtr Chunk = a_Entity->GetParentChunk(); - - // Even if a chunk is not valid, it may still contain entities such as players; make sure to remove them (#1190) - if (Chunk == nullptr) - { - return; - } - Chunk->RemoveEntity(a_Entity); -} - - - - - bool cChunkMap::ForEachEntity(cEntityCallback & a_Callback) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); for (const auto & Chunk : m_Chunks) { if (Chunk.second->IsValid() && !Chunk.second->ForEachEntity(a_Callback)) @@ -1631,7 +1637,8 @@ bool cChunkMap::ForEachEntity(cEntityCallback & a_Callback) bool cChunkMap::ForEachEntityInChunk(int a_ChunkX, int a_ChunkZ, cEntityCallback & a_Callback) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); + cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ); if ((Chunk == nullptr) || !Chunk->IsValid()) { @@ -1646,6 +1653,7 @@ bool cChunkMap::ForEachEntityInChunk(int a_ChunkX, int a_ChunkZ, cEntityCallback bool cChunkMap::ForEachEntityInBox(const cBoundingBox & a_Box, cEntityCallback & a_Callback) { + ASSERT(GetWorld()->IsInTickThread()); // Calculate the chunk range for the box: int MinChunkX = FloorC(a_Box.GetMinX() / cChunkDef::Width); int MinChunkZ = FloorC(a_Box.GetMinZ() / cChunkDef::Width); @@ -1653,7 +1661,7 @@ bool cChunkMap::ForEachEntityInBox(const cBoundingBox & a_Box, cEntityCallback & int MaxChunkZ = FloorC((a_Box.GetMaxZ() + cChunkDef::Width) / cChunkDef::Width); // Iterate over each chunk in the range: - cCSLock Lock(m_CSChunks); + for (int z = MinChunkZ; z <= MaxChunkZ; z++) { for (int x = MinChunkX; x <= MaxChunkX; x++) @@ -1678,6 +1686,7 @@ bool cChunkMap::ForEachEntityInBox(const cBoundingBox & a_Box, cEntityCallback & void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_BlockY, double a_BlockZ, cVector3iArray & a_BlocksAffected) { + ASSERT(GetWorld()->IsInTickThread()); // Don't explode if outside of Y range (prevents the following test running into unallocated memory): if (!cChunkDef::IsValidHeight(FloorC(a_BlockY))) { @@ -1874,7 +1883,8 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_ bool cChunkMap::DoWithEntityByID(UInt32 a_UniqueID, cEntityCallback & a_Callback) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); + bool res = false; for (const auto & Chunk : m_Chunks) { @@ -1892,7 +1902,8 @@ bool cChunkMap::DoWithEntityByID(UInt32 a_UniqueID, cEntityCallback & a_Callback bool cChunkMap::ForEachBlockEntityInChunk(int a_ChunkX, int a_ChunkZ, cBlockEntityCallback & a_Callback) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); + cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ); if ((Chunk == nullptr) || !Chunk->IsValid()) { @@ -1907,7 +1918,6 @@ bool cChunkMap::ForEachBlockEntityInChunk(int a_ChunkX, int a_ChunkZ, cBlockEnti bool cChunkMap::ForEachBrewingstandInChunk(int a_ChunkX, int a_ChunkZ, cBrewingstandCallback & a_Callback) { - cCSLock Lock(m_CSChunks); cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ); if ((Chunk == nullptr) || !Chunk->IsValid()) { @@ -1922,7 +1932,8 @@ bool cChunkMap::ForEachBrewingstandInChunk(int a_ChunkX, int a_ChunkZ, cBrewings bool cChunkMap::ForEachChestInChunk(int a_ChunkX, int a_ChunkZ, cChestCallback & a_Callback) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); + cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ); if ((Chunk == nullptr) || !Chunk->IsValid()) { @@ -1937,7 +1948,8 @@ bool cChunkMap::ForEachChestInChunk(int a_ChunkX, int a_ChunkZ, cChestCallback & bool cChunkMap::ForEachDispenserInChunk(int a_ChunkX, int a_ChunkZ, cDispenserCallback & a_Callback) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); + cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ); if ((Chunk == nullptr) || !Chunk->IsValid()) { @@ -1952,7 +1964,8 @@ bool cChunkMap::ForEachDispenserInChunk(int a_ChunkX, int a_ChunkZ, cDispenserCa bool cChunkMap::ForEachDropperInChunk(int a_ChunkX, int a_ChunkZ, cDropperCallback & a_Callback) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); + cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ); if ((Chunk == nullptr) || !Chunk->IsValid()) { @@ -1967,7 +1980,8 @@ bool cChunkMap::ForEachDropperInChunk(int a_ChunkX, int a_ChunkZ, cDropperCallba bool cChunkMap::ForEachDropSpenserInChunk(int a_ChunkX, int a_ChunkZ, cDropSpenserCallback & a_Callback) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); + cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ); if ((Chunk == nullptr) || !Chunk->IsValid()) { @@ -1982,7 +1996,8 @@ bool cChunkMap::ForEachDropSpenserInChunk(int a_ChunkX, int a_ChunkZ, cDropSpens bool cChunkMap::ForEachFurnaceInChunk(int a_ChunkX, int a_ChunkZ, cFurnaceCallback & a_Callback) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); + cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ); if ((Chunk == nullptr) || !Chunk->IsValid()) { @@ -1997,10 +2012,11 @@ bool cChunkMap::ForEachFurnaceInChunk(int a_ChunkX, int a_ChunkZ, cFurnaceCallba bool cChunkMap::DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBlockEntityCallback & a_Callback) { + ASSERT(GetWorld()->IsInTickThread()); int ChunkX, ChunkZ; int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ; cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ); - cCSLock Lock(m_CSChunks); + cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); if ((Chunk == nullptr) || !Chunk->IsValid()) { @@ -2015,10 +2031,11 @@ bool cChunkMap::DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cB bool cChunkMap::DoWithBeaconAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBeaconCallback & a_Callback) { + ASSERT(GetWorld()->IsInTickThread()); int ChunkX, ChunkZ; int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ; cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ); - cCSLock Lock(m_CSChunks); + cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); if ((Chunk == nullptr) || !Chunk->IsValid()) { @@ -2036,7 +2053,6 @@ bool cChunkMap::DoWithBrewingstandAt(int a_BlockX, int a_BlockY, int a_BlockZ, c int ChunkX, ChunkZ; int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ; cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ); - cCSLock Lock(m_CSChunks); cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); if ((Chunk == nullptr) || !Chunk->IsValid()) { @@ -2051,10 +2067,11 @@ bool cChunkMap::DoWithBrewingstandAt(int a_BlockX, int a_BlockY, int a_BlockZ, c bool cChunkMap::DoWithChestAt(int a_BlockX, int a_BlockY, int a_BlockZ, cChestCallback & a_Callback) { + ASSERT(GetWorld()->IsInTickThread()); int ChunkX, ChunkZ; int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ; cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ); - cCSLock Lock(m_CSChunks); + cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); if ((Chunk == nullptr) || !Chunk->IsValid()) { @@ -2069,10 +2086,11 @@ bool cChunkMap::DoWithChestAt(int a_BlockX, int a_BlockY, int a_BlockZ, cChestCa bool cChunkMap::DoWithDispenserAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDispenserCallback & a_Callback) { + ASSERT(GetWorld()->IsInTickThread()); int ChunkX, ChunkZ; int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ; cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ); - cCSLock Lock(m_CSChunks); + cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); if ((Chunk == nullptr) || !Chunk->IsValid()) { @@ -2087,10 +2105,11 @@ bool cChunkMap::DoWithDispenserAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDis bool cChunkMap::DoWithDropperAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDropperCallback & a_Callback) { + ASSERT(GetWorld()->IsInTickThread()); int ChunkX, ChunkZ; int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ; cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ); - cCSLock Lock(m_CSChunks); + cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); if ((Chunk == nullptr) || !Chunk->IsValid()) { @@ -2105,10 +2124,11 @@ bool cChunkMap::DoWithDropperAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDropp bool cChunkMap::DoWithDropSpenserAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDropSpenserCallback & a_Callback) { + ASSERT(GetWorld()->IsInTickThread()); int ChunkX, ChunkZ; int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ; cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ); - cCSLock Lock(m_CSChunks); + cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); if ((Chunk == nullptr) || !Chunk->IsValid()) { @@ -2123,10 +2143,11 @@ bool cChunkMap::DoWithDropSpenserAt(int a_BlockX, int a_BlockY, int a_BlockZ, cD bool cChunkMap::DoWithFurnaceAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFurnaceCallback & a_Callback) { + ASSERT(GetWorld()->IsInTickThread()); int ChunkX, ChunkZ; int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ; cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ); - cCSLock Lock(m_CSChunks); + cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); if ((Chunk == nullptr) || !Chunk->IsValid()) { @@ -2140,10 +2161,11 @@ bool cChunkMap::DoWithFurnaceAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFurna bool cChunkMap::DoWithNoteBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cNoteBlockCallback & a_Callback) { + ASSERT(GetWorld()->IsInTickThread()); int ChunkX, ChunkZ; int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ; cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ); - cCSLock Lock(m_CSChunks); + cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); if ((Chunk == nullptr) || !Chunk->IsValid()) { @@ -2157,10 +2179,11 @@ bool cChunkMap::DoWithNoteBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cNot bool cChunkMap::DoWithCommandBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cCommandBlockCallback & a_Callback) { + ASSERT(GetWorld()->IsInTickThread()); int ChunkX, ChunkZ; int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ; cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ); - cCSLock Lock(m_CSChunks); + cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); if ((Chunk == nullptr) || !Chunk->IsValid()) { @@ -2175,10 +2198,11 @@ bool cChunkMap::DoWithCommandBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, c bool cChunkMap::DoWithMobHeadAt(int a_BlockX, int a_BlockY, int a_BlockZ, cMobHeadCallback & a_Callback) { + ASSERT(GetWorld()->IsInTickThread()); int ChunkX, ChunkZ; int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ; cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ); - cCSLock Lock(m_CSChunks); + cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); if ((Chunk == nullptr) || !Chunk->IsValid()) { @@ -2193,10 +2217,11 @@ bool cChunkMap::DoWithMobHeadAt(int a_BlockX, int a_BlockY, int a_BlockZ, cMobHe bool cChunkMap::DoWithFlowerPotAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFlowerPotCallback & a_Callback) { + ASSERT(GetWorld()->IsInTickThread()); int ChunkX, ChunkZ; int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ; cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ); - cCSLock Lock(m_CSChunks); + cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); if ((Chunk == nullptr) || !Chunk->IsValid()) { @@ -2211,10 +2236,11 @@ bool cChunkMap::DoWithFlowerPotAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFlo bool cChunkMap::GetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4) { + ASSERT(GetWorld()->IsInTickThread()); int ChunkX, ChunkZ; int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ; cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ); - cCSLock Lock(m_CSChunks); + cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); if ((Chunk == nullptr) || !Chunk->IsValid()) { @@ -2229,7 +2255,7 @@ bool cChunkMap::GetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, AString & void cChunkMap::TouchChunk(int a_ChunkX, int a_ChunkZ) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); GetChunk(a_ChunkX, a_ChunkZ); } @@ -2239,7 +2265,8 @@ void cChunkMap::TouchChunk(int a_ChunkX, int a_ChunkZ) void cChunkMap::PrepareChunk(int a_ChunkX, int a_ChunkZ, std::unique_ptr<cChunkCoordCallback> a_Callback) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); + cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, a_ChunkZ); // If the chunk is not prepared, queue it in the lighting thread, that will do all the needed processing: @@ -2262,7 +2289,8 @@ void cChunkMap::PrepareChunk(int a_ChunkX, int a_ChunkZ, std::unique_ptr<cChunkC bool cChunkMap::GenerateChunk(int a_ChunkX, int a_ChunkZ, cChunkCoordCallback * a_Callback) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); + cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, a_ChunkZ); if (Chunk == nullptr) { @@ -2298,7 +2326,6 @@ bool cChunkMap::GenerateChunk(int a_ChunkX, int a_ChunkZ, cChunkCoordCallback * } // The chunk failed to load, generate it: - cCSLock CBLock(m_ChunkMap.m_CSChunks); cChunkPtr CBChunk = m_ChunkMap.GetChunkNoLoad(a_CBChunkX, a_CBChunkZ); if (CBChunk == nullptr) @@ -2338,7 +2365,8 @@ bool cChunkMap::GenerateChunk(int a_ChunkX, int a_ChunkZ, cChunkCoordCallback * void cChunkMap::ChunkLoadFailed(int a_ChunkX, int a_ChunkZ) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); + cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, a_ChunkZ); if (Chunk == nullptr) { @@ -2353,7 +2381,8 @@ void cChunkMap::ChunkLoadFailed(int a_ChunkX, int a_ChunkZ) bool cChunkMap::SetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); + int ChunkX, ChunkZ; cChunkDef::BlockToChunk(a_BlockX, a_BlockZ, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); @@ -2370,7 +2399,8 @@ bool cChunkMap::SetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, const ASt void cChunkMap::MarkChunkRegenerating(int a_ChunkX, int a_ChunkZ) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); + cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, a_ChunkZ); if (Chunk == nullptr) { @@ -2386,7 +2416,8 @@ void cChunkMap::MarkChunkRegenerating(int a_ChunkX, int a_ChunkZ) bool cChunkMap::IsChunkLighted(int a_ChunkX, int a_ChunkZ) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); + cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, a_ChunkZ); if (Chunk == nullptr) { @@ -2402,8 +2433,9 @@ bool cChunkMap::IsChunkLighted(int a_ChunkX, int a_ChunkZ) bool cChunkMap::ForEachChunkInRect(int a_MinChunkX, int a_MaxChunkX, int a_MinChunkZ, int a_MaxChunkZ, cChunkDataCallback & a_Callback) { + ASSERT(GetWorld()->IsInTickThread()); bool Result = true; - cCSLock Lock(m_CSChunks); + for (int z = a_MinChunkZ; z <= a_MaxChunkZ; z++) { for (int x = a_MinChunkX; x <= a_MaxChunkX; x++) @@ -2431,7 +2463,7 @@ bool cChunkMap::ForEachChunkInRect(int a_MinChunkX, int a_MaxChunkX, int a_MinCh bool cChunkMap::ForEachLoadedChunk(std::function<bool(int, int)> a_Callback) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); for (const auto & Chunk : m_Chunks) { if (Chunk.second->IsValid()) @@ -2451,6 +2483,7 @@ bool cChunkMap::ForEachLoadedChunk(std::function<bool(int, int)> a_Callback) bool cChunkMap::WriteBlockArea(cBlockArea & a_Area, int a_MinBlockX, int a_MinBlockY, int a_MinBlockZ, int a_DataTypes) { + ASSERT(GetWorld()->IsInTickThread()); // Convert block coords to chunks coords: int MinChunkX, MaxChunkX; int MinChunkZ, MaxChunkZ; @@ -2465,7 +2498,7 @@ bool cChunkMap::WriteBlockArea(cBlockArea & a_Area, int a_MinBlockX, int a_MinBl // Iterate over chunks, write data into each: bool Result = true; - cCSLock Lock(m_CSChunks); + for (int z = MinChunkZ; z <= MaxChunkZ; z++) { for (int x = MinChunkX; x <= MaxChunkX; x++) @@ -2489,9 +2522,10 @@ bool cChunkMap::WriteBlockArea(cBlockArea & a_Area, int a_MinBlockX, int a_MinBl void cChunkMap::GetChunkStats(int & a_NumChunksValid, int & a_NumChunksDirty) { + ASSERT(GetWorld()->IsInTickThread()); a_NumChunksValid = 0; a_NumChunksDirty = 0; - cCSLock Lock(m_CSChunks); + for (const auto & Chunk : m_Chunks) { a_NumChunksValid++; @@ -2508,10 +2542,10 @@ void cChunkMap::GetChunkStats(int & a_NumChunksValid, int & a_NumChunksDirty) bool cChunkMap::GrowMelonPumpkin(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, MTRand & a_Rand) { + ASSERT(GetWorld()->IsInTickThread()); int ChunkX, ChunkZ; cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); - cCSLock Lock(m_CSChunks); cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ChunkZ); if (Chunk != nullptr) { @@ -2526,10 +2560,11 @@ bool cChunkMap::GrowMelonPumpkin(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCK int cChunkMap::GrowSugarcane(int a_BlockX, int a_BlockY, int a_BlockZ, int a_NumBlocksToGrow) { + ASSERT(GetWorld()->IsInTickThread()); int ChunkX, ChunkZ; cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); - cCSLock Lock(m_CSChunks); + cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ChunkZ); if (Chunk != nullptr) { @@ -2544,10 +2579,11 @@ int cChunkMap::GrowSugarcane(int a_BlockX, int a_BlockY, int a_BlockZ, int a_Num int cChunkMap::GrowCactus(int a_BlockX, int a_BlockY, int a_BlockZ, int a_NumBlocksToGrow) { + ASSERT(GetWorld()->IsInTickThread()); int ChunkX, ChunkZ; cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); - cCSLock Lock(m_CSChunks); + cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ChunkZ); if (Chunk != nullptr) { @@ -2562,10 +2598,11 @@ int cChunkMap::GrowCactus(int a_BlockX, int a_BlockY, int a_BlockZ, int a_NumBlo bool cChunkMap::GrowTallGrass(int a_BlockX, int a_BlockY, int a_BlockZ) { + ASSERT(GetWorld()->IsInTickThread()); int ChunkX, ChunkZ; cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); - cCSLock Lock(m_CSChunks); + cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ChunkZ); if (Chunk != nullptr) { @@ -2580,10 +2617,11 @@ bool cChunkMap::GrowTallGrass(int a_BlockX, int a_BlockY, int a_BlockZ) void cChunkMap::SetNextBlockTick(int a_BlockX, int a_BlockY, int a_BlockZ) { + ASSERT(GetWorld()->IsInTickThread()); int ChunkX, ChunkZ; cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); - cCSLock Lock(m_CSChunks); + cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ChunkZ); if (Chunk != nullptr) { @@ -2596,7 +2634,7 @@ void cChunkMap::SetNextBlockTick(int a_BlockX, int a_BlockY, int a_BlockZ) void cChunkMap::CollectMobCensus(cMobCensus & a_ToFill) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); for (const auto & Chunk : m_Chunks) { // We do count every Mobs in the world. But we are assuming that every chunk not loaded by any client @@ -2616,7 +2654,7 @@ void cChunkMap::CollectMobCensus(cMobCensus & a_ToFill) void cChunkMap::SpawnMobs(cMobSpawner & a_MobSpawner) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); for (const auto & Chunk : m_Chunks) { // We only spawn close to players @@ -2633,7 +2671,7 @@ void cChunkMap::SpawnMobs(cMobSpawner & a_MobSpawner) void cChunkMap::Tick(std::chrono::milliseconds a_Dt) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); for (const auto & Chunk : m_Chunks) { // Only tick chunks that are valid and should be ticked: @@ -2650,7 +2688,8 @@ void cChunkMap::Tick(std::chrono::milliseconds a_Dt) void cChunkMap::TickBlock(int a_BlockX, int a_BlockY, int a_BlockZ) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); + int ChunkX, ChunkZ; cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ChunkZ); @@ -2667,7 +2706,7 @@ void cChunkMap::TickBlock(int a_BlockX, int a_BlockY, int a_BlockZ) void cChunkMap::UnloadUnusedChunks(void) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); for (auto itr = m_Chunks.begin(); itr != m_Chunks.end();) { if ( @@ -2690,7 +2729,7 @@ void cChunkMap::UnloadUnusedChunks(void) void cChunkMap::SaveAllChunks(void) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); for (const auto & Chunk : m_Chunks) { if (Chunk.second->IsValid() && Chunk.second->IsDirty()) @@ -2706,9 +2745,8 @@ void cChunkMap::SaveAllChunks(void) int cChunkMap::GetNumChunks(void) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); return static_cast<int>(m_Chunks.size()); // TODO: change return value to unsigned type - } @@ -2717,6 +2755,7 @@ int cChunkMap::GetNumChunks(void) void cChunkMap::ChunkValidated(void) { + ASSERT(GetWorld()->IsInTickThread()); m_evtChunkValid.Set(); } @@ -2726,11 +2765,12 @@ void cChunkMap::ChunkValidated(void) void cChunkMap::QueueTickBlock(int a_BlockX, int a_BlockY, int a_BlockZ) { + ASSERT(GetWorld()->IsInTickThread()); int ChunkX, ChunkZ; cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); // a_BlockXYZ now contains relative coords! - cCSLock Lock(m_CSChunks); + cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ChunkZ); if (Chunk != nullptr) { @@ -2744,7 +2784,8 @@ void cChunkMap::QueueTickBlock(int a_BlockX, int a_BlockY, int a_BlockZ) void cChunkMap::SetChunkAlwaysTicked(int a_ChunkX, int a_ChunkZ, bool a_AlwaysTicked) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); + cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, a_ChunkZ); if (Chunk != nullptr) { @@ -2762,7 +2803,7 @@ void cChunkMap::FastSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE int ChunkX, ChunkZ, X = a_BlockX, Y = a_BlockY, Z = a_BlockZ; cChunkDef::AbsoluteToRelative(X, Y, Z, ChunkX, ChunkZ); - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); cChunkPtr Chunk = GetChunk(ChunkX, ChunkZ); if ((Chunk != nullptr) && Chunk->IsValid()) { @@ -2776,11 +2817,11 @@ void cChunkMap::FastSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE void cChunkMap::AddChunkStay(cChunkStay & a_ChunkStay) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); // Add it to the list: ASSERT(std::find(m_ChunkStays.begin(), m_ChunkStays.end(), &a_ChunkStay) == m_ChunkStays.end()); // Has not yet been added - m_ChunkStays.push_back(&a_ChunkStay); + m_ChunkStays.emplace_back(&a_ChunkStay); // Schedule all chunks to be loaded / generated, and mark each as locked: const cChunkCoordsVector & WantedChunks = a_ChunkStay.GetChunks(); @@ -2811,7 +2852,7 @@ void cChunkMap::AddChunkStay(cChunkStay & a_ChunkStay) /** Removes the specified cChunkStay descendant from the internal list of ChunkStays. */ void cChunkMap::DelChunkStay(cChunkStay & a_ChunkStay) { - cCSLock Lock(m_CSChunks); + ASSERT(GetWorld()->IsInTickThread()); // Remove from the list of active chunkstays: bool HasFound = false; |