summaryrefslogtreecommitdiffstats
path: root/src/World.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/World.cpp148
1 files changed, 7 insertions, 141 deletions
diff --git a/src/World.cpp b/src/World.cpp
index 3c39de317..f7d2165c7 100644
--- a/src/World.cpp
+++ b/src/World.cpp
@@ -58,6 +58,7 @@
#endif
#include "Broadcaster.h"
+#include "SpawnPrepare.h"
@@ -72,140 +73,6 @@ const int TIME_SPAWN_DIVISOR = 148;
////////////////////////////////////////////////////////////////////////////////
-// cSpawnPrepare:
-
-/** Generates and lights the spawn area of the world. Runs as a separate thread. */
-class cSpawnPrepare:
- public cIsThread,
- public cChunkCoordCallback
-{
- typedef cIsThread super;
-
-public:
- cSpawnPrepare(cWorld & a_World, int a_SpawnChunkX, int a_SpawnChunkZ, int a_PrepareDistance):
- super("SpawnPrepare"),
- m_World(a_World),
- m_SpawnChunkX(a_SpawnChunkX),
- m_SpawnChunkZ(a_SpawnChunkZ),
- m_PrepareDistance(a_PrepareDistance),
- m_MaxIdx(a_PrepareDistance * a_PrepareDistance),
- m_NumPrepared(0),
- m_LastReportChunkCount(0)
- {
- // Start the thread:
- Start();
-
- // Wait for start confirmation, so that the thread can be waited-upon after the constructor returns:
- m_EvtStarted.Wait();
- }
-
-
- // cIsThread override:
- virtual void Execute(void) override
- {
- // Confirm thread start:
- m_EvtStarted.Set();
-
- // Queue the initial chunks:
- m_MaxIdx = m_PrepareDistance * m_PrepareDistance;
- int maxQueue = std::min(m_MaxIdx - 1, 100); // Number of chunks to queue at once
- m_NextIdx = maxQueue;
- m_LastReportTime = std::chrono::steady_clock::now();
- for (int i = 0; i < maxQueue; i++)
- {
- int chunkX, chunkZ;
- DecodeChunkCoords(i, chunkX, chunkZ);
- m_World.PrepareChunk(chunkX, chunkZ, this);
- } // for i
-
- // Wait for the lighting thread to prepare everything. Event is set in the Call() callback:
- m_EvtFinished.Wait();
- }
-
-protected:
- cWorld & m_World;
- int m_SpawnChunkX;
- int m_SpawnChunkZ;
- int m_PrepareDistance;
-
- /** The index of the next chunk to be queued in the lighting thread. */
- int m_NextIdx;
-
- /** The maximum index of the prepared chunks. Queueing stops when m_NextIdx reaches this number. */
- int m_MaxIdx;
-
- /** Total number of chunks already finished preparing. Preparation finishes when this number reaches m_MaxIdx. */
- int m_NumPrepared;
-
- /** Event used to signal that the thread has started. */
- cEvent m_EvtStarted;
-
- /** Event used to signal that the preparation is finished. */
- cEvent m_EvtFinished;
-
- /** The timestamp of the last progress report emitted. */
- std::chrono::steady_clock::time_point m_LastReportTime;
-
- /** Number of chunks prepared when the last progress report was emitted. */
- int m_LastReportChunkCount;
-
- // cChunkCoordCallback override:
- virtual void Call(int a_ChunkX, int a_ChunkZ) override
- {
- // Check if this was the last chunk:
- m_NumPrepared += 1;
- if (m_NumPrepared >= m_MaxIdx)
- {
- m_EvtFinished.Set();
- // Must return here, because "this" may have gotten deleted by the previous line
- return;
- }
-
- // Queue another chunk, if appropriate:
- if (m_NextIdx < m_MaxIdx)
- {
- int chunkX, chunkZ;
- DecodeChunkCoords(m_NextIdx, chunkX, chunkZ);
- m_World.GetLightingThread().QueueChunk(chunkX, chunkZ, this);
- m_NextIdx += 1;
- }
-
- // Report progress every 1 second:
- auto Now = std::chrono::steady_clock::now();
- if (Now - m_LastReportTime > std::chrono::seconds(1))
- {
- float PercentDone = static_cast<float>(m_NumPrepared * 100) / m_MaxIdx;
- float ChunkSpeed = static_cast<float>((m_NumPrepared - m_LastReportChunkCount) * 1000) / std::chrono::duration_cast<std::chrono::milliseconds>(Now - m_LastReportTime).count();
- LOG("Preparing spawn (%s): %.02f%% (%d/%d; %.02f chunks / sec)",
- m_World.GetName().c_str(), PercentDone, m_NumPrepared, m_MaxIdx, ChunkSpeed
- );
- m_LastReportTime = Now;
- m_LastReportChunkCount = m_NumPrepared;
- }
- }
-
-
- /** Decodes the index into chunk coords. Provides the specific chunk ordering. */
- void DecodeChunkCoords(int a_Idx, int & a_ChunkX, int & a_ChunkZ)
- {
- // A zigzag pattern from the top to bottom, each row alternating between forward-x and backward-x:
- int z = a_Idx / m_PrepareDistance;
- int x = a_Idx % m_PrepareDistance;
- if ((z & 1) == 0)
- {
- // Reverse every second row:
- x = m_PrepareDistance - 1 - x;
- }
- a_ChunkZ = m_SpawnChunkZ + z - m_PrepareDistance / 2;
- a_ChunkX = m_SpawnChunkX + x - m_PrepareDistance / 2;
- }
-};
-
-
-
-
-
-////////////////////////////////////////////////////////////////////////////////
// cWorld::cLock:
cWorld::cLock::cLock(cWorld & a_World) :
@@ -470,8 +337,7 @@ void cWorld::InitializeSpawn(void)
int ViewDist = IniFile.GetValueSetI("SpawnPosition", "PregenerateDistance", DefaultViewDist);
IniFile.WriteFile(m_IniFileName);
- cSpawnPrepare prep(*this, ChunkX, ChunkZ, ViewDist);
- prep.Wait();
+ cSpawnPrepare::PrepareChunks(*this, ChunkX, ChunkZ, ViewDist);
#ifdef TEST_LINEBLOCKTRACER
// DEBUG: Test out the cLineBlockTracer class by tracing a few lines:
@@ -2072,7 +1938,7 @@ void cWorld::BroadcastAttachEntity(const cEntity & a_Entity, const cEntity * a_V
-void cWorld::BroadcastBlockAction(int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType, const cClientHandle * a_Exclude)
+void cWorld::BroadcastBlockAction(int a_BlockX, int a_BlockY, int a_BlockZ, Byte a_Byte1, Byte a_Byte2, BLOCKTYPE a_BlockType, const cClientHandle * a_Exclude)
{
m_ChunkMap->BroadcastBlockAction(a_BlockX, a_BlockY, a_BlockZ, a_Byte1, a_Byte2, a_BlockType, a_Exclude);
}
@@ -3006,9 +2872,9 @@ void cWorld::TouchChunk(int a_ChunkX, int a_ChunkZ)
-void cWorld::PrepareChunk(int a_ChunkX, int a_ChunkZ, cChunkCoordCallback * a_CallAfter)
+void cWorld::PrepareChunk(int a_ChunkX, int a_ChunkZ, std::unique_ptr<cChunkCoordCallback> a_CallAfter)
{
- m_ChunkMap->PrepareChunk(a_ChunkX, a_ChunkZ, a_CallAfter);
+ m_ChunkMap->PrepareChunk(a_ChunkX, a_ChunkZ, std::move(a_CallAfter));
}
@@ -3132,9 +2998,9 @@ void cWorld::GenerateChunk(int a_ChunkX, int a_ChunkZ)
-void cWorld::QueueLightChunk(int a_ChunkX, int a_ChunkZ, cChunkCoordCallback * a_Callback)
+void cWorld::QueueLightChunk(int a_ChunkX, int a_ChunkZ, std::unique_ptr<cChunkCoordCallback> a_Callback)
{
- m_Lighting.QueueChunk(a_ChunkX, a_ChunkZ, a_Callback);
+ m_Lighting.QueueChunk(a_ChunkX, a_ChunkZ, std::move(a_Callback));
}