summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authormadmaxoft@gmail.com <madmaxoft@gmail.com@0a769ca7-a7f5-676a-18bf-c427514a06d6>2012-02-18 21:10:57 +0100
committermadmaxoft@gmail.com <madmaxoft@gmail.com@0a769ca7-a7f5-676a-18bf-c427514a06d6>2012-02-18 21:10:57 +0100
commit3a8d2aa421fcfa11a84a911aaaa6b5aa4e16cab3 (patch)
treef33081a1326a09879b42e579ba4d6f560aeaeb19 /source
parentFixed previous commit: forgot to remove a debugging setting (diff)
downloadcuberite-3a8d2aa421fcfa11a84a911aaaa6b5aa4e16cab3.tar
cuberite-3a8d2aa421fcfa11a84a911aaaa6b5aa4e16cab3.tar.gz
cuberite-3a8d2aa421fcfa11a84a911aaaa6b5aa4e16cab3.tar.bz2
cuberite-3a8d2aa421fcfa11a84a911aaaa6b5aa4e16cab3.tar.lz
cuberite-3a8d2aa421fcfa11a84a911aaaa6b5aa4e16cab3.tar.xz
cuberite-3a8d2aa421fcfa11a84a911aaaa6b5aa4e16cab3.tar.zst
cuberite-3a8d2aa421fcfa11a84a911aaaa6b5aa4e16cab3.zip
Diffstat (limited to 'source')
-rw-r--r--source/cChunk.cpp36
-rw-r--r--source/cChunk.h17
-rw-r--r--source/cChunkMap.cpp51
-rw-r--r--source/cChunkMap.h1
-rw-r--r--source/cWorld.cpp29
-rw-r--r--source/cWorld.h17
6 files changed, 106 insertions, 45 deletions
diff --git a/source/cChunk.cpp b/source/cChunk.cpp
index afa69fb68..d070e82aa 100644
--- a/source/cChunk.cpp
+++ b/source/cChunk.cpp
@@ -47,6 +47,26 @@ extern bool g_bWaterPhysics;
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// sSetBlock:
+
+sSetBlock::sSetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_BlockMeta ) // absolute block position
+ : x( a_X )
+ , y( a_Y )
+ , z( a_Z )
+ , BlockType( a_BlockType )
+ , BlockMeta( a_BlockMeta )
+{
+ cChunkMap::AbsoluteToRelative(x, y, z, ChunkX, ChunkZ);
+}
+
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// cChunk:
+
cChunk::cChunk(int a_X, int a_Y, int a_Z, cWorld * a_World)
: m_bCalculateLighting( false )
, m_bCalculateHeightmap( false )
@@ -872,12 +892,9 @@ void cChunk::SetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_Block
-void cChunk::FastSetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_BlockMeta )
+void cChunk::FastSetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_BlockMeta)
{
- if(a_X < 0 || a_X >= 16 || a_Y < 0 || a_Y >= 128 || a_Z < 0 || a_Z >= 16)
- {
- return; // Clip
- }
+ assert(!((a_X < 0 || a_X >= 16 || a_Y < 0 || a_Y >= 128 || a_Z < 0 || a_Z >= 16)));
assert(IsValid());
@@ -897,12 +914,15 @@ void cChunk::FastSetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_B
m_PendingSendBlocks.push_back( index );
}
+ // It's called SetLight(), but it sets the Meta when passed the BlockMeta workspace
SetLight( m_BlockMeta, index, a_BlockMeta );
// ONLY recalculate lighting if it's necessary!
- if( g_BlockLightValue[ OldBlock ] != g_BlockLightValue[ a_BlockType ]
- || g_BlockSpreadLightFalloff[ OldBlock ] != g_BlockSpreadLightFalloff[ a_BlockType ]
- || g_BlockTransparent[ OldBlock ] != g_BlockTransparent[ a_BlockType ] )
+ if(
+ (g_BlockLightValue[ OldBlock ] != g_BlockLightValue[ a_BlockType ]) ||
+ (g_BlockSpreadLightFalloff[ OldBlock ] != g_BlockSpreadLightFalloff[ a_BlockType ]) ||
+ (g_BlockTransparent[ OldBlock ] != g_BlockTransparent[ a_BlockType ] )
+ )
{
RecalculateLighting();
}
diff --git a/source/cChunk.h b/source/cChunk.h
index 2576e2412..4453ed16a 100644
--- a/source/cChunk.h
+++ b/source/cChunk.h
@@ -70,6 +70,21 @@ public:
+struct sSetBlock
+{
+ int x, y, z;
+ int ChunkX, ChunkZ;
+ char BlockType, BlockMeta;
+
+ sSetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_BlockMeta ); // absolute block position
+};
+
+typedef std::list< sSetBlock > sSetBlockList;
+
+
+
+
+
class cChunk
{
public:
@@ -118,7 +133,7 @@ public:
void AsyncUnload( cClientHandle* a_Client );
void SetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_BlockMeta );
- void FastSetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_BlockMeta ); // Doesn't force block updates on neighbors, use for simple changes such as grass growing etc.
+ void FastSetBlock(int a_RelX, int a_RelY, int a_RelZ, char a_BlockType, char a_BlockMeta ); // Doesn't force block updates on neighbors, use for simple changes such as grass growing etc.
char GetBlock( int a_X, int a_Y, int a_Z );
char GetBlock( int a_BlockIdx );
diff --git a/source/cChunkMap.cpp b/source/cChunkMap.cpp
index c5512dd68..0657f51d3 100644
--- a/source/cChunkMap.cpp
+++ b/source/cChunkMap.cpp
@@ -351,6 +351,57 @@ int cChunkMap::GetHeight(int a_BlockX, int a_BlockZ)
+void cChunkMap::FastSetBlocks(sSetBlockList & a_BlockList)
+{
+ sSetBlockList Failed;
+
+ // Process all items from a_BlockList, either successfully or by placing into Failed
+ while (!a_BlockList.empty())
+ {
+ int ChunkX = a_BlockList.front().ChunkX;
+ int ChunkZ = a_BlockList.front().ChunkZ;
+ cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ);
+ if ((Chunk != NULL) && Chunk->IsValid())
+ {
+ for (sSetBlockList::iterator itr = a_BlockList.begin(); itr != a_BlockList.end();)
+ {
+ if ((itr->ChunkX == ChunkX) && (itr->ChunkZ == ChunkZ))
+ {
+ Chunk->FastSetBlock(itr->x, itr->y, itr->z, itr->BlockType, itr->BlockMeta);
+ itr = a_BlockList.erase(itr);
+ }
+ else
+ {
+ ++itr;
+ }
+ } // for itr - a_BlockList[]
+ }
+ else
+ {
+ // The chunk is not valid, move all blocks within this chunk to Failed
+ for (sSetBlockList::iterator itr = a_BlockList.begin(); itr != a_BlockList.end();)
+ {
+ if ((itr->ChunkX == ChunkX) && (itr->ChunkZ == ChunkZ))
+ {
+ Failed.push_back(*itr);
+ itr = a_BlockList.erase(itr);
+ }
+ else
+ {
+ ++itr;
+ }
+ } // for itr - a_BlockList[]
+ }
+ }
+
+ // Return the failed:
+ std::swap(Failed, a_BlockList);
+}
+
+
+
+
+
void cChunkMap::Tick( float a_Dt, MTRand & a_TickRandom )
{
cCSLock Lock(m_CSLayers);
diff --git a/source/cChunkMap.h b/source/cChunkMap.h
index 7c26a14c0..a9cb4d661 100644
--- a/source/cChunkMap.h
+++ b/source/cChunkMap.h
@@ -47,6 +47,7 @@ public:
bool HasChunkAnyClients (int a_ChunkX, int a_ChunkY, int a_ChunkZ);
void SpreadChunkLighting(int a_ChunkX, int a_ChunkY, int a_ChunkZ);
int GetHeight (int a_BlockX, int a_BlockZ);
+ void FastSetBlocks (sSetBlockList & a_BlockList);
void Tick( float a_Dt, MTRand & a_TickRand );
diff --git a/source/cWorld.cpp b/source/cWorld.cpp
index 41b9c5068..f5e40ec0b 100644
--- a/source/cWorld.cpp
+++ b/source/cWorld.cpp
@@ -503,17 +503,18 @@ void cWorld::Tick(float a_Dt)
TickWeather(a_Dt);
- // Asynchronously set blocks
- FastSetBlockList FastSetBlockQueueCopy;
+ // Asynchronously set blocks:
+ sSetBlockList FastSetBlockQueueCopy;
{
cCSLock Lock(m_CSFastSetBlock);
- FastSetBlockQueueCopy = m_FastSetBlockQueue;
- m_FastSetBlockQueue.clear();
+ std::swap(FastSetBlockQueueCopy, m_FastSetBlockQueue);
}
- for ( FastSetBlockList::iterator itr = FastSetBlockQueueCopy.begin(); itr != FastSetBlockQueueCopy.end(); ++itr )
+ m_ChunkMap->FastSetBlocks(FastSetBlockQueueCopy);
+ if (FastSetBlockQueueCopy.size() > 0)
{
- sSetBlockData & SetBlockData = *itr;
- FastSetBlock( SetBlockData.x, SetBlockData.y, SetBlockData.z, SetBlockData.BlockID, SetBlockData.BlockMeta ); // If unable to set block, it's added to FastSetBlockQueue again
+ // Some blocks failed, store them for next tick:
+ cCSLock Lock(m_CSFastSetBlock);
+ m_FastSetBlockQueue.splice(m_FastSetBlockQueue.end(), FastSetBlockQueueCopy);
}
if( m_Time - m_LastSave > 60 * 5 ) // Save each 5 minutes
@@ -847,20 +848,8 @@ void cWorld::SetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_Block
void cWorld::FastSetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_BlockMeta )
{
- int ChunkX, ChunkY, ChunkZ, X = a_X, Y = a_Y, Z = a_Z;
-
- AbsoluteToRelative( X, Y, Z, ChunkX, ChunkY, ChunkZ );
-
- cChunkPtr Chunk = GetChunkNoGen( ChunkX, ChunkY, ChunkZ );
- if (Chunk->IsValid())
- {
- Chunk->FastSetBlock(X, Y, Z, a_BlockType, a_BlockMeta );
- return;
- }
-
- // Unable to set block right now, try again later
cCSLock Lock(m_CSFastSetBlock);
- m_FastSetBlockQueue.push_back( sSetBlockData( a_X, a_Y, a_Z, a_BlockType, a_BlockMeta ) );
+ m_FastSetBlockQueue.push_back(sSetBlock(a_X, a_Y, a_Z, a_BlockType, a_BlockMeta));
}
diff --git a/source/cWorld.h b/source/cWorld.h
index 569fe8d32..a9c068336 100644
--- a/source/cWorld.h
+++ b/source/cWorld.h
@@ -183,21 +183,6 @@ private:
friend class cRoot;
- struct sSetBlockData
- {
- sSetBlockData( int a_X, int a_Y, int a_Z, char a_BlockID, char a_BlockMeta )
- : x( a_X )
- , y( a_Y )
- , z( a_Z )
- , BlockID( a_BlockID )
- , BlockMeta( a_BlockMeta )
- {}
- int x, y, z;
- char BlockID, BlockMeta;
- };
-
- typedef std::list< sSetBlockData > FastSetBlockList;
-
// This random generator is to be used only in the Tick() method, and thus only in the World-Tick-thread (MTRand is not exactly thread-safe)
MTRand m_TickRand;
@@ -252,7 +237,7 @@ private:
cChunkCoordsList m_SpreadQueue;
cCriticalSection m_CSFastSetBlock;
- FastSetBlockList m_FastSetBlockQueue;
+ sSetBlockList m_FastSetBlockQueue;
cChunkGenerator m_Generator;