summaryrefslogtreecommitdiffstats
path: root/src/ChunkMap.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/ChunkMap.cpp98
1 files changed, 98 insertions, 0 deletions
diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp
index 595040a54..222a756b1 100644
--- a/src/ChunkMap.cpp
+++ b/src/ChunkMap.cpp
@@ -822,6 +822,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_CSLayers);
for (int z = MinChunkZ; z <= MaxChunkZ; z++)
{
int MinZ = std::max(a_MinBlockZ, z * cChunkDef::Width);
@@ -2348,6 +2349,103 @@ void cChunkMap::TouchChunk(int a_ChunkX, int a_ChunkZ)
+void cChunkMap::PrepareChunk(int a_ChunkX, int a_ChunkZ, cChunkCoordCallback * a_Callback)
+{
+ cCSLock Lock(m_CSLayers);
+ 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:
+ if ((Chunk == nullptr) || !Chunk->IsValid() || !Chunk->IsLightValid())
+ {
+ m_World->GetLightingThread().QueueChunk(a_ChunkX, a_ChunkZ, a_Callback);
+ return;
+ }
+
+ // The chunk is present and lit, just call the callback:
+ if (a_Callback != nullptr)
+ {
+ a_Callback->Call(a_ChunkX, a_ChunkZ);
+ }
+}
+
+
+
+
+
+bool cChunkMap::GenerateChunk(int a_ChunkX, int a_ChunkZ, cChunkCoordCallback * a_Callback)
+{
+ cCSLock Lock(m_CSLayers);
+ cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, a_ChunkZ);
+ if (Chunk == nullptr)
+ {
+ // Generic error while getting the chunk - out of memory?
+ return false;
+ }
+
+ // Try loading the chunk:
+ if ((Chunk == nullptr) || (!Chunk->IsValid()))
+ {
+ class cPrepareLoadCallback: public cChunkCoordCallback
+ {
+ public:
+ cPrepareLoadCallback(cWorld & a_World, cChunkMap & a_ChunkMap, cChunkCoordCallback * a_Callback):
+ m_World(a_World),
+ m_ChunkMap(a_ChunkMap),
+ m_Callback(a_Callback)
+ {
+ }
+
+ // cChunkCoordCallback override:
+ virtual void Call(int a_CBChunkX, int a_CBChunkZ) override
+ {
+ // The chunk has been loaded or an error occurred, check if it's valid now:
+ cChunkPtr CBChunk = m_ChunkMap.GetChunkNoLoad(a_CBChunkX, a_CBChunkZ);
+
+ if (CBChunk == nullptr)
+ {
+ // An error occurred, but we promised to call the callback, so call it even when there's no real chunk data:
+ if (m_Callback != nullptr)
+ {
+ m_Callback->Call(a_CBChunkX, a_CBChunkZ);
+ }
+ return;
+ }
+
+ // If the chunk is not valid, queue it in the generator:
+ if (!CBChunk->IsValid())
+ {
+ m_World.GetGenerator().QueueGenerateChunk(a_CBChunkX, a_CBChunkZ, false, m_Callback);
+ return;
+ }
+
+ // The chunk was loaded, call the callback:
+ if (m_Callback != nullptr)
+ {
+ m_Callback->Call(a_CBChunkX, a_CBChunkZ);
+ }
+ }
+
+ protected:
+ cWorld & m_World;
+ cChunkMap & m_ChunkMap;
+ cChunkCoordCallback * m_Callback;
+ };
+ m_World->GetStorage().QueueLoadChunk(a_ChunkX, a_ChunkZ, new cPrepareLoadCallback(*m_World, *this, a_Callback));
+ return true;
+ }
+
+ // The chunk is valid, just call the callback:
+ if (a_Callback != nullptr)
+ {
+ a_Callback->Call(a_ChunkX, a_ChunkZ);
+ }
+ return true;
+}
+
+
+
+
+
void cChunkMap::ChunkLoadFailed(int a_ChunkX, int a_ChunkZ)
{
cCSLock Lock(m_CSLayers);