summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormadmaxoft@gmail.com <madmaxoft@gmail.com@0a769ca7-a7f5-676a-18bf-c427514a06d6>2012-02-26 17:46:23 +0100
committermadmaxoft@gmail.com <madmaxoft@gmail.com@0a769ca7-a7f5-676a-18bf-c427514a06d6>2012-02-26 17:46:23 +0100
commit1f88db187bbc1bacc29a2f263c73ff383aa06e91 (patch)
treed8332cf8d866223b47b579a65fb3e2a2d41e92fc
parentNew cChunkStay class for temporarily keeping chunks loaded even when then have no clients. For now unused, will be used by generator and lighting in the future. (diff)
downloadcuberite-1f88db187bbc1bacc29a2f263c73ff383aa06e91.tar
cuberite-1f88db187bbc1bacc29a2f263c73ff383aa06e91.tar.gz
cuberite-1f88db187bbc1bacc29a2f263c73ff383aa06e91.tar.bz2
cuberite-1f88db187bbc1bacc29a2f263c73ff383aa06e91.tar.lz
cuberite-1f88db187bbc1bacc29a2f263c73ff383aa06e91.tar.xz
cuberite-1f88db187bbc1bacc29a2f263c73ff383aa06e91.tar.zst
cuberite-1f88db187bbc1bacc29a2f263c73ff383aa06e91.zip
-rw-r--r--source/WorldStorage.cpp44
-rw-r--r--source/WorldStorage.h18
-rw-r--r--source/cChunkMap.cpp16
3 files changed, 62 insertions, 16 deletions
diff --git a/source/WorldStorage.cpp b/source/WorldStorage.cpp
index 58c6527ca..2d8d5bbc7 100644
--- a/source/WorldStorage.cpp
+++ b/source/WorldStorage.cpp
@@ -196,12 +196,20 @@ int cWorldStorage::GetSaveQueueLength(void)
-void cWorldStorage::QueueLoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
+void cWorldStorage::QueueLoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, bool a_Generate)
{
// Queues the chunk for loading; if not loaded, the chunk will be generated
cCSLock Lock(m_CSQueues);
- m_LoadQueue.remove (cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ)); // Don't add twice
- m_LoadQueue.push_back(cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ));
+
+ // Check if already in the queue:
+ for (sChunkLoadQueue::iterator itr = m_LoadQueue.begin(); itr != m_LoadQueue.end(); ++itr)
+ {
+ if ((itr->m_ChunkX == a_ChunkX) && (itr->m_ChunkY == a_ChunkY) && (itr->m_ChunkZ == a_ChunkZ) && (itr->m_Generate == a_Generate))
+ {
+ return;
+ }
+ }
+ m_LoadQueue.push_back(sChunkLoad(a_ChunkX, a_ChunkY, a_ChunkZ, a_Generate));
m_Event.Set();
}
@@ -221,11 +229,19 @@ void cWorldStorage::QueueSaveChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
-void cWorldStorage::UnqueueLoad(const cChunkCoords & a_Chunk)
+void cWorldStorage::UnqueueLoad(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
{
cCSLock Lock(m_CSQueues);
- m_LoadQueue.remove(a_Chunk);
- m_evtRemoved.Set();
+ for (sChunkLoadQueue::iterator itr = m_LoadQueue.begin(); itr != m_LoadQueue.end(); ++itr)
+ {
+ if ((itr->m_ChunkX != a_ChunkX) || (itr->m_ChunkY != a_ChunkY) || (itr->m_ChunkZ != a_ChunkZ))
+ {
+ continue;
+ }
+ m_LoadQueue.erase(itr);
+ m_evtRemoved.Set();
+ return;
+ } // for itr - m_LoadQueue[]
}
@@ -306,7 +322,7 @@ void cWorldStorage::Execute(void)
bool cWorldStorage::LoadOneChunk(void)
{
- cChunkCoords ToLoad(0, 0, 0);
+ sChunkLoad ToLoad(0, 0, 0, false);
bool HasMore;
bool ShouldLoad = false;
{
@@ -319,10 +335,18 @@ bool cWorldStorage::LoadOneChunk(void)
}
HasMore = (m_LoadQueue.size() > 0);
}
- if (ShouldLoad && !LoadChunk(ToLoad))
+ if (ShouldLoad && !LoadChunk(cChunkCoords(ToLoad.m_ChunkX, ToLoad.m_ChunkY, ToLoad.m_ChunkZ)))
{
- // The chunk couldn't be loaded, generate it:
- m_World->GetGenerator().GenerateChunk(ToLoad.m_ChunkX, ToLoad.m_ChunkY, ToLoad.m_ChunkZ);
+ if (ToLoad.m_Generate)
+ {
+ // The chunk couldn't be loaded, generate it:
+ m_World->GetGenerator().GenerateChunk(ToLoad.m_ChunkX, ToLoad.m_ChunkY, ToLoad.m_ChunkZ);
+ }
+ else
+ {
+ // TODO: Notify the world that the load has failed:
+ // m_World->ChunkLoadFailed(ToLoad.m_ChunkX, ToLoad.m_ChunkY, ToLoad.m_ChunkZ);
+ }
}
return HasMore;
}
diff --git a/source/WorldStorage.h b/source/WorldStorage.h
index 1ea39cf66..9c3a38771 100644
--- a/source/WorldStorage.h
+++ b/source/WorldStorage.h
@@ -97,10 +97,10 @@ public:
cWorldStorage(void);
~cWorldStorage();
- void QueueLoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ); // Queues the chunk for loading; if not loaded, the chunk will be generated
+ void QueueLoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, bool a_Generate); // Queues the chunk for loading; if not loaded, the chunk will be generated if a_Generate is true
void QueueSaveChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ);
- void UnqueueLoad(const cChunkCoords & a_Chunk);
+ void UnqueueLoad(int a_ChunkX, int a_ChunkY, int a_ChunkZ);
void UnqueueSave(const cChunkCoords & a_Chunk);
bool Start(cWorld * a_World, const AString & a_StorageSchemaName); // Hide the cIsThread's Start() method, we need to provide args
@@ -112,12 +112,24 @@ public:
protected:
+ struct sChunkLoad
+ {
+ int m_ChunkX;
+ int m_ChunkY;
+ int m_ChunkZ;
+ bool m_Generate; // If true, the chunk will be generated if it cannot be loaded
+
+ sChunkLoad(int a_ChunkX, int a_ChunkY, int a_ChunkZ, bool a_Generate) : m_ChunkX(a_ChunkX), m_ChunkY(a_ChunkY), m_ChunkZ(a_ChunkZ), m_Generate(a_Generate) {}
+ } ;
+
+ typedef std::list<sChunkLoad> sChunkLoadQueue;
+
cWorld * m_World;
AString m_StorageSchemaName;
// Both queues are locked by the same CS
cCriticalSection m_CSQueues;
- cChunkCoordsList m_LoadQueue;
+ sChunkLoadQueue m_LoadQueue;
cChunkCoordsList m_SaveQueue;
cEvent m_Event; // Set when there's any addition to the queues
diff --git a/source/cChunkMap.cpp b/source/cChunkMap.cpp
index 548040724..52e124107 100644
--- a/source/cChunkMap.cpp
+++ b/source/cChunkMap.cpp
@@ -115,9 +115,13 @@ cChunkPtr cChunkMap::GetChunk( int a_ChunkX, int a_ChunkY, int a_ChunkZ )
}
cChunkPtr Chunk = Layer->GetChunk(a_ChunkX, a_ChunkY, a_ChunkZ);
+ if (Chunk == NULL)
+ {
+ return NULL;
+ }
if (!(Chunk->IsValid()))
{
- m_World->GetStorage().QueueLoadChunk(a_ChunkX, a_ChunkY, a_ChunkZ);
+ m_World->GetStorage().QueueLoadChunk(a_ChunkX, a_ChunkY, a_ChunkZ, true);
}
return Chunk;
}
@@ -137,8 +141,14 @@ cChunkPtr cChunkMap::GetChunkNoGen( int a_ChunkX, int a_ChunkY, int a_ChunkZ )
}
cChunkPtr Chunk = Layer->GetChunk(a_ChunkX, a_ChunkY, a_ChunkZ);
-
- // TODO: Load, but do not generate, if not valid
+ if (Chunk == NULL)
+ {
+ return NULL;
+ }
+ if (!(Chunk->IsValid()))
+ {
+ m_World->GetStorage().QueueLoadChunk(a_ChunkX, a_ChunkY, a_ChunkZ, false);
+ }
return Chunk;
}