Implemented chunk loading without generating on load-failure
git-svn-id: http://mc-server.googlecode.com/svn/trunk@331 0a769ca7-a7f5-676a-18bf-c427514a06d6
This commit is contained in:
parent
b902546863
commit
1f88db187b
@ -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
|
// Queues the chunk for loading; if not loaded, the chunk will be generated
|
||||||
cCSLock Lock(m_CSQueues);
|
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();
|
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);
|
cCSLock Lock(m_CSQueues);
|
||||||
m_LoadQueue.remove(a_Chunk);
|
for (sChunkLoadQueue::iterator itr = m_LoadQueue.begin(); itr != m_LoadQueue.end(); ++itr)
|
||||||
m_evtRemoved.Set();
|
{
|
||||||
|
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)
|
bool cWorldStorage::LoadOneChunk(void)
|
||||||
{
|
{
|
||||||
cChunkCoords ToLoad(0, 0, 0);
|
sChunkLoad ToLoad(0, 0, 0, false);
|
||||||
bool HasMore;
|
bool HasMore;
|
||||||
bool ShouldLoad = false;
|
bool ShouldLoad = false;
|
||||||
{
|
{
|
||||||
@ -319,10 +335,18 @@ bool cWorldStorage::LoadOneChunk(void)
|
|||||||
}
|
}
|
||||||
HasMore = (m_LoadQueue.size() > 0);
|
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:
|
if (ToLoad.m_Generate)
|
||||||
m_World->GetGenerator().GenerateChunk(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);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// TODO: Notify the world that the load has failed:
|
||||||
|
// m_World->ChunkLoadFailed(ToLoad.m_ChunkX, ToLoad.m_ChunkY, ToLoad.m_ChunkZ);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return HasMore;
|
return HasMore;
|
||||||
}
|
}
|
||||||
|
@ -97,10 +97,10 @@ public:
|
|||||||
cWorldStorage(void);
|
cWorldStorage(void);
|
||||||
~cWorldStorage();
|
~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 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);
|
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
|
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:
|
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;
|
cWorld * m_World;
|
||||||
AString m_StorageSchemaName;
|
AString m_StorageSchemaName;
|
||||||
|
|
||||||
// Both queues are locked by the same CS
|
// Both queues are locked by the same CS
|
||||||
cCriticalSection m_CSQueues;
|
cCriticalSection m_CSQueues;
|
||||||
cChunkCoordsList m_LoadQueue;
|
sChunkLoadQueue m_LoadQueue;
|
||||||
cChunkCoordsList m_SaveQueue;
|
cChunkCoordsList m_SaveQueue;
|
||||||
|
|
||||||
cEvent m_Event; // Set when there's any addition to the queues
|
cEvent m_Event; // Set when there's any addition to the queues
|
||||||
|
@ -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);
|
cChunkPtr Chunk = Layer->GetChunk(a_ChunkX, a_ChunkY, a_ChunkZ);
|
||||||
|
if (Chunk == NULL)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
if (!(Chunk->IsValid()))
|
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;
|
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);
|
cChunkPtr Chunk = Layer->GetChunk(a_ChunkX, a_ChunkY, a_ChunkZ);
|
||||||
|
if (Chunk == NULL)
|
||||||
// TODO: Load, but do not generate, if not valid
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (!(Chunk->IsValid()))
|
||||||
|
{
|
||||||
|
m_World->GetStorage().QueueLoadChunk(a_ChunkX, a_ChunkY, a_ChunkZ, false);
|
||||||
|
}
|
||||||
|
|
||||||
return Chunk;
|
return Chunk;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user