Rewritten chunk status to specify whether the chunk is in queue.
This fixes #1370.
This commit is contained in:
parent
e15b8600a6
commit
137b021d26
@ -71,7 +71,7 @@ cChunk::cChunk(
|
||||
cChunk * a_NeighborXM, cChunk * a_NeighborXP, cChunk * a_NeighborZM, cChunk * a_NeighborZP,
|
||||
cAllocationPool<cChunkData::sChunkSection> & a_Pool
|
||||
) :
|
||||
m_IsValid(false),
|
||||
m_Presence(cpInvalid),
|
||||
m_IsLightValid(false),
|
||||
m_IsDirty(false),
|
||||
m_IsSaving(false),
|
||||
@ -165,11 +165,22 @@ cChunk::~cChunk()
|
||||
|
||||
|
||||
|
||||
void cChunk::SetValid(void)
|
||||
void cChunk::SetPresence(cChunk::ePresence a_Presence)
|
||||
{
|
||||
m_IsValid = true;
|
||||
|
||||
m_World->GetChunkMap()->ChunkValidated();
|
||||
m_Presence = a_Presence;
|
||||
if (a_Presence == cpPresent)
|
||||
{
|
||||
m_World->GetChunkMap()->ChunkValidated();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunk::SetShouldGenerateIfLoadFailed(bool a_ShouldGenerateIfLoadFailed)
|
||||
{
|
||||
m_ShouldGenerateIfLoadFailed = a_ShouldGenerateIfLoadFailed;
|
||||
}
|
||||
|
||||
|
||||
@ -178,6 +189,9 @@ void cChunk::SetValid(void)
|
||||
|
||||
void cChunk::MarkRegenerating(void)
|
||||
{
|
||||
// Set as queued again:
|
||||
SetPresence(cpQueued);
|
||||
|
||||
// Tell all clients attached to this chunk that they want this chunk:
|
||||
for (cClientHandleList::iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
|
||||
{
|
||||
@ -191,7 +205,11 @@ void cChunk::MarkRegenerating(void)
|
||||
|
||||
bool cChunk::CanUnload(void)
|
||||
{
|
||||
return m_LoadedByClient.empty() && !m_IsDirty && (m_StayCount == 0);
|
||||
return
|
||||
m_LoadedByClient.empty() && // The chunk is not used by any client
|
||||
!m_IsDirty && // The chunk has been saved properly or hasn't been touched since the load / gen
|
||||
(m_StayCount == 0) && // The chunk is not in a ChunkStay
|
||||
(m_Presence != cpQueued) ; // The chunk is not queued for loading / generating (otherwise multi-load / multi-gen could occur)
|
||||
}
|
||||
|
||||
|
||||
@ -223,7 +241,7 @@ void cChunk::MarkSaved(void)
|
||||
void cChunk::MarkLoaded(void)
|
||||
{
|
||||
m_IsDirty = false;
|
||||
SetValid();
|
||||
SetPresence(cpPresent);
|
||||
}
|
||||
|
||||
|
||||
@ -232,12 +250,17 @@ void cChunk::MarkLoaded(void)
|
||||
|
||||
void cChunk::MarkLoadFailed(void)
|
||||
{
|
||||
if (m_IsValid)
|
||||
ASSERT(m_Presence == cpQueued);
|
||||
|
||||
// If the chunk is marked as needed, generate it:
|
||||
if (m_ShouldGenerateIfLoadFailed)
|
||||
{
|
||||
return;
|
||||
m_World->GetGenerator().QueueGenerateChunk(m_PosX, m_PosZ, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Presence = cpInvalid;
|
||||
}
|
||||
|
||||
m_HasLoadFailed = true;
|
||||
}
|
||||
|
||||
|
||||
@ -246,6 +269,8 @@ void cChunk::MarkLoadFailed(void)
|
||||
|
||||
void cChunk::GetAllData(cChunkDataCallback & a_Callback)
|
||||
{
|
||||
ASSERT(m_Presence == cpPresent);
|
||||
|
||||
a_Callback.HeightMap(&m_HeightMap);
|
||||
a_Callback.BiomeData(&m_BiomeMap);
|
||||
|
||||
@ -272,6 +297,7 @@ void cChunk::SetAllData(cSetChunkData & a_SetChunkData)
|
||||
{
|
||||
ASSERT(a_SetChunkData.IsHeightMapValid());
|
||||
ASSERT(a_SetChunkData.AreBiomesValid());
|
||||
ASSERT(IsQueued());
|
||||
|
||||
memcpy(m_BiomeMap, a_SetChunkData.GetBiomes(), sizeof(m_BiomeMap));
|
||||
memcpy(m_HeightMap, a_SetChunkData.GetHeightMap(), sizeof(m_HeightMap));
|
||||
@ -317,7 +343,7 @@ void cChunk::SetAllData(cSetChunkData & a_SetChunkData)
|
||||
CreateBlockEntities();
|
||||
|
||||
// Set the chunk data as valid. This may be needed for some simulators that perform actions upon block adding (Vaporize)
|
||||
SetValid();
|
||||
SetPresence(cpPresent);
|
||||
|
||||
// Wake up all simulators for their respective blocks:
|
||||
WakeUpSimulators();
|
||||
|
44
src/Chunk.h
44
src/Chunk.h
@ -66,6 +66,14 @@ class cChunk :
|
||||
public cChunkDef // The inheritance is "misused" here only to inherit the functions and constants defined in cChunkDef
|
||||
{
|
||||
public:
|
||||
/** Represents the presence state of the chunk */
|
||||
enum ePresence
|
||||
{
|
||||
cpInvalid, /**< The chunk is not present at all and is not queued in the loader / generator */
|
||||
cpQueued, /**< The chunk is not present, but is queued for loading / generation */
|
||||
cpPresent, /**< The chunk is present */
|
||||
};
|
||||
|
||||
cChunk(
|
||||
int a_ChunkX, int a_ChunkZ, // Chunk coords
|
||||
cChunkMap * a_ChunkMap, cWorld * a_World, // Parent objects
|
||||
@ -75,11 +83,25 @@ public:
|
||||
cChunk(cChunk & other);
|
||||
~cChunk();
|
||||
|
||||
bool IsValid(void) const {return m_IsValid; } // Returns true if the chunk block data is valid (loaded / generated)
|
||||
void SetValid(void); // Also wakes up any calls to cChunkMap::GetHeight()
|
||||
void MarkRegenerating(void); // Marks all clients attached to this chunk as wanting this chunk
|
||||
bool IsDirty(void) const {return m_IsDirty; } // Returns true if the chunk has changed since it was last saved
|
||||
bool HasLoadFailed(void) const {return m_HasLoadFailed; } // Returns true if the chunk failed to load and hasn't been generated since then
|
||||
/** Returns true iff the chunk block data is valid (loaded / generated) */
|
||||
bool IsValid(void) const {return (m_Presence == cpPresent); }
|
||||
|
||||
/** Returns true iff the chunk is in the queue for loading / generating */
|
||||
bool IsQueued(void) const {return (m_Presence == cpQueued); }
|
||||
|
||||
/** Sets the chunk's presence.
|
||||
Wakes up any calls to cChunkMap::GetHeight() when setting to cpPresent. */
|
||||
void SetPresence(ePresence a_Presence);
|
||||
|
||||
/** Called to indicate whether the chunk should be queued in the generator if it fails to load. Set by cChunkMap::GetChunk(). */
|
||||
void SetShouldGenerateIfLoadFailed(bool a_ShouldGenerateIfLoadFailed);
|
||||
|
||||
/** Marks all clients attached to this chunk as wanting this chunk. Also sets presence to cpQueued. */
|
||||
void MarkRegenerating(void);
|
||||
|
||||
/** Returns true iff the chunk has changed since it was last saved. */
|
||||
bool IsDirty(void) const {return m_IsDirty; }
|
||||
|
||||
bool CanUnload(void);
|
||||
|
||||
bool IsLightValid(void) const {return m_IsLightValid; }
|
||||
@ -94,7 +116,10 @@ public:
|
||||
void MarkSaving(void); // Marks the chunk as being saved.
|
||||
void MarkSaved(void); // Marks the chunk as saved, if it didn't change from the last call to MarkSaving()
|
||||
void MarkLoaded(void); // Marks the chunk as freshly loaded. Fails if the chunk is already valid
|
||||
void MarkLoadFailed(void); // Marks the chunk as failed to load. Ignored is the chunk is already valid
|
||||
|
||||
/** Marks the chunk as failed to load.
|
||||
If m_ShouldGenerateIfLoadFailed is set, queues the chunk for generating. */
|
||||
void MarkLoadFailed(void);
|
||||
|
||||
/** Gets all chunk data, calls the a_Callback's methods for each data type */
|
||||
void GetAllData(cChunkDataCallback & a_Callback);
|
||||
@ -434,7 +459,12 @@ private:
|
||||
typedef std::vector<sSetBlockQueueItem> sSetBlockQueueVector;
|
||||
|
||||
|
||||
bool m_IsValid; // True if the chunk is loaded / generated
|
||||
/** Holds the presence status of the chunk - if it is present, or in the loader / generator queue, or unloaded */
|
||||
ePresence m_Presence;
|
||||
|
||||
/** If the chunk fails to load, should it be queued in the generator or reset back to invalid? */
|
||||
bool m_ShouldGenerateIfLoadFailed;
|
||||
|
||||
bool m_IsLightValid; // True if the blocklight and skylight are calculated
|
||||
bool m_IsDirty; // True if the chunk has changed since it was last saved
|
||||
bool m_IsSaving; // True if the chunk is being saved
|
||||
|
@ -145,10 +145,9 @@ cChunkMap::cChunkLayer * cChunkMap::GetLayerForChunk(int a_ChunkX, int a_ChunkZ)
|
||||
|
||||
cChunkPtr cChunkMap::GetChunk(int a_ChunkX, int a_ChunkZ)
|
||||
{
|
||||
// No need to lock m_CSLayers, since it's already locked by the operation that called us
|
||||
ASSERT(m_CSLayers.IsLockedByCurrentThread());
|
||||
ASSERT(m_CSLayers.IsLockedByCurrentThread()); // m_CSLayers should already be locked by the operation that called us
|
||||
|
||||
cChunkLayer * Layer = GetLayerForChunk( a_ChunkX, a_ChunkZ);
|
||||
cChunkLayer * Layer = GetLayerForChunk(a_ChunkX, a_ChunkZ);
|
||||
if (Layer == NULL)
|
||||
{
|
||||
// An error must have occurred, since layers are automatically created if they don't exist
|
||||
@ -160,8 +159,10 @@ cChunkPtr cChunkMap::GetChunk(int a_ChunkX, int a_ChunkZ)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
if (!(Chunk->IsValid()))
|
||||
if (!Chunk->IsValid() && !Chunk->IsQueued())
|
||||
{
|
||||
Chunk->SetPresence(cChunk::cpQueued);
|
||||
Chunk->SetShouldGenerateIfLoadFailed(true);
|
||||
m_World->GetStorage().QueueLoadChunk(a_ChunkX, a_ChunkZ, true);
|
||||
}
|
||||
return Chunk;
|
||||
@ -171,10 +172,11 @@ cChunkPtr cChunkMap::GetChunk(int a_ChunkX, int a_ChunkZ)
|
||||
|
||||
|
||||
|
||||
cChunkPtr cChunkMap::GetChunkNoGen( int a_ChunkX, int a_ChunkZ)
|
||||
cChunkPtr cChunkMap::GetChunkNoGen(int a_ChunkX, int a_ChunkZ)
|
||||
{
|
||||
// No need to lock m_CSLayers, since it's already locked by the operation that called us
|
||||
cChunkLayer * Layer = GetLayerForChunk( a_ChunkX, a_ChunkZ);
|
||||
ASSERT(m_CSLayers.IsLockedByCurrentThread()); // m_CSLayers should already be locked by the operation that called us
|
||||
|
||||
cChunkLayer * Layer = GetLayerForChunk(a_ChunkX, a_ChunkZ);
|
||||
if (Layer == NULL)
|
||||
{
|
||||
// An error must have occurred, since layers are automatically created if they don't exist
|
||||
@ -186,8 +188,9 @@ cChunkPtr cChunkMap::GetChunkNoGen( int a_ChunkX, int a_ChunkZ)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
if (!(Chunk->IsValid()))
|
||||
if (!Chunk->IsValid() && !Chunk->IsQueued())
|
||||
{
|
||||
Chunk->SetPresence(cChunk::cpQueued);
|
||||
m_World->GetStorage().QueueLoadChunk(a_ChunkX, a_ChunkZ, false);
|
||||
}
|
||||
|
||||
@ -200,7 +203,8 @@ cChunkPtr cChunkMap::GetChunkNoGen( int a_ChunkX, int a_ChunkZ)
|
||||
|
||||
cChunkPtr cChunkMap::GetChunkNoLoad( int a_ChunkX, int a_ChunkZ)
|
||||
{
|
||||
// No need to lock m_CSLayers, since it's already locked by the operation that called us
|
||||
ASSERT(m_CSLayers.IsLockedByCurrentThread()); // m_CSLayers should already be locked by the operation that called us
|
||||
|
||||
cChunkLayer * Layer = GetLayerForChunk( a_ChunkX, a_ChunkZ);
|
||||
if (Layer == NULL)
|
||||
{
|
||||
@ -1009,6 +1013,17 @@ bool cChunkMap::GetChunkBlockTypes(int a_ChunkX, int a_ChunkZ, BLOCKTYPE * a_Blo
|
||||
|
||||
|
||||
|
||||
bool cChunkMap::IsChunkQueued(int a_ChunkX, int a_ChunkZ)
|
||||
{
|
||||
cCSLock Lock(m_CSLayers);
|
||||
cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, a_ChunkZ);
|
||||
return (Chunk != NULL) && Chunk->IsQueued();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cChunkMap::IsChunkValid(int a_ChunkX, int a_ChunkZ)
|
||||
{
|
||||
cCSLock Lock(m_CSLayers);
|
||||
@ -2332,48 +2347,6 @@ void cChunkMap::TouchChunk(int a_ChunkX, int a_ChunkZ)
|
||||
|
||||
|
||||
|
||||
/// Loads the chunk synchronously, if not already loaded. Doesn't generate. Returns true if chunk valid (even if already loaded before)
|
||||
bool cChunkMap::LoadChunk(int a_ChunkX, int a_ChunkZ)
|
||||
{
|
||||
{
|
||||
cCSLock Lock(m_CSLayers);
|
||||
cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ);
|
||||
if (Chunk == NULL)
|
||||
{
|
||||
// Internal error
|
||||
return false;
|
||||
}
|
||||
if (Chunk->IsValid())
|
||||
{
|
||||
// Already loaded
|
||||
return true;
|
||||
}
|
||||
if (Chunk->HasLoadFailed())
|
||||
{
|
||||
// Already tried loading and it failed
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return m_World->GetStorage().LoadChunk(a_ChunkX, a_ChunkZ);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// Loads the chunks specified. Doesn't report failure, other than chunks being !IsValid()
|
||||
void cChunkMap::LoadChunks(const cChunkCoordsList & a_Chunks)
|
||||
{
|
||||
for (cChunkCoordsList::const_iterator itr = a_Chunks.begin(); itr != a_Chunks.end(); ++itr)
|
||||
{
|
||||
LoadChunk(itr->m_ChunkX, itr->m_ChunkZ);
|
||||
} // for itr - a_Chunks[]
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunkMap::ChunkLoadFailed(int a_ChunkX, int a_ChunkZ)
|
||||
{
|
||||
cCSLock Lock(m_CSLayers);
|
||||
|
@ -133,6 +133,9 @@ public:
|
||||
/** Copies the chunk's blocktypes into a_Blocks; returns true if successful */
|
||||
bool GetChunkBlockTypes (int a_ChunkX, int a_ChunkZ, BLOCKTYPE * a_Blocks);
|
||||
|
||||
/** Returns true iff the chunk is in the loader / generator queue. */
|
||||
bool IsChunkQueued(int a_ChunkX, int a_ChunkZ);
|
||||
|
||||
bool IsChunkValid (int a_ChunkX, int a_ChunkZ);
|
||||
bool HasChunkAnyClients (int a_ChunkX, int a_ChunkZ);
|
||||
int GetHeight (int a_BlockX, int a_BlockZ); // Waits for the chunk to get loaded / generated
|
||||
@ -278,12 +281,6 @@ public:
|
||||
/** Touches the chunk, causing it to be loaded or generated */
|
||||
void TouchChunk(int a_ChunkX, int a_ChunkZ);
|
||||
|
||||
/** Loads the chunk, if not already loaded. Doesn't generate. Returns true if chunk valid (even if already loaded before) */
|
||||
bool LoadChunk(int a_ChunkX, int a_ChunkZ);
|
||||
|
||||
/** Loads the chunks specified. Doesn't report failure, other than chunks being !IsValid() */
|
||||
void LoadChunks(const cChunkCoordsList & a_Chunks);
|
||||
|
||||
/** Marks the chunk as failed-to-load */
|
||||
void ChunkLoadFailed(int a_ChunkX, int a_ChunkZ);
|
||||
|
||||
|
@ -283,7 +283,8 @@ void cChunkGenerator::DoGenerate(int a_ChunkX, int a_ChunkZ)
|
||||
{
|
||||
ASSERT(m_PluginInterface != NULL);
|
||||
ASSERT(m_ChunkSink != NULL);
|
||||
|
||||
ASSERT(m_ChunkSink->IsChunkQueued(a_ChunkX, a_ChunkZ));
|
||||
|
||||
cChunkDesc ChunkDesc(a_ChunkX, a_ChunkZ);
|
||||
m_PluginInterface->CallHookChunkGenerating(ChunkDesc);
|
||||
m_Generator->DoGenerate(a_ChunkX, a_ChunkZ, ChunkDesc);
|
||||
|
@ -106,6 +106,10 @@ public:
|
||||
If this callback returns false, the chunk is not generated.
|
||||
*/
|
||||
virtual bool HasChunkAnyClients(int a_ChunkX, int a_ChunkZ) = 0;
|
||||
|
||||
/** Called to check whether the specified chunk is in the queued state.
|
||||
Currently used only in Debug-mode asserts. */
|
||||
virtual bool IsChunkQueued(int a_ChunkX, int a_ChunkZ) = 0;
|
||||
} ;
|
||||
|
||||
|
||||
|
@ -2374,6 +2374,8 @@ void cWorld::MarkChunkSaved (int a_ChunkX, int a_ChunkZ)
|
||||
|
||||
void cWorld::QueueSetChunkData(const cSetChunkDataPtr & a_SetChunkData)
|
||||
{
|
||||
ASSERT(IsChunkQueued(a_SetChunkData->GetChunkX(), a_SetChunkData->GetChunkZ()));
|
||||
|
||||
// Validate biomes, if needed:
|
||||
if (!a_SetChunkData->AreBiomesValid())
|
||||
{
|
||||
@ -2463,6 +2465,15 @@ bool cWorld::GetChunkBlockTypes(int a_ChunkX, int a_ChunkZ, BLOCKTYPE * a_BlockT
|
||||
|
||||
|
||||
|
||||
bool cWorld::IsChunkQueued(int a_ChunkX, int a_ChunkZ) const
|
||||
{
|
||||
return m_ChunkMap->IsChunkQueued(a_ChunkX, a_ChunkZ);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cWorld::IsChunkValid(int a_ChunkX, int a_ChunkZ) const
|
||||
{
|
||||
return m_ChunkMap->IsChunkValid(a_ChunkX, a_ChunkZ);
|
||||
@ -2787,24 +2798,6 @@ void cWorld::TouchChunk(int a_ChunkX, int a_ChunkZ)
|
||||
|
||||
|
||||
|
||||
bool cWorld::LoadChunk(int a_ChunkX, int a_ChunkZ)
|
||||
{
|
||||
return m_ChunkMap->LoadChunk(a_ChunkX, a_ChunkZ);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::LoadChunks(const cChunkCoordsList & a_Chunks)
|
||||
{
|
||||
m_ChunkMap->LoadChunks(a_Chunks);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::ChunkLoadFailed(int a_ChunkX, int a_ChunkZ)
|
||||
{
|
||||
m_ChunkMap->ChunkLoadFailed(a_ChunkX, a_ChunkZ);
|
||||
@ -3520,6 +3513,15 @@ bool cWorld::cChunkGeneratorCallbacks::IsChunkValid(int a_ChunkX, int a_ChunkZ)
|
||||
|
||||
|
||||
|
||||
bool cWorld::cChunkGeneratorCallbacks::IsChunkQueued(int a_ChunkX, int a_ChunkZ)
|
||||
{
|
||||
return m_World->IsChunkQueued(a_ChunkX, a_ChunkZ);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cWorld::cChunkGeneratorCallbacks::HasChunkAnyClients(int a_ChunkX, int a_ChunkZ)
|
||||
{
|
||||
return m_World->HasChunkAnyClients(a_ChunkX, a_ChunkZ);
|
||||
|
14
src/World.h
14
src/World.h
@ -279,7 +279,12 @@ public:
|
||||
/** Gets the chunk's blocks, only the block types */
|
||||
bool GetChunkBlockTypes(int a_ChunkX, int a_ChunkZ, BLOCKTYPE * a_BlockTypes);
|
||||
|
||||
bool IsChunkValid (int a_ChunkX, int a_ChunkZ) const;
|
||||
/** Returns true iff the chunk is in the loader / generator queue. */
|
||||
bool IsChunkQueued(int a_ChunkX, int a_ChunkZ) const;
|
||||
|
||||
/** Returns true iff the chunk is present and valid. */
|
||||
bool IsChunkValid(int a_ChunkX, int a_ChunkZ) const;
|
||||
|
||||
bool HasChunkAnyClients(int a_ChunkX, int a_ChunkZ) const;
|
||||
|
||||
/** Queues a task to unload unused chunks onto the tick thread. The prefferred way of unloading*/
|
||||
@ -358,12 +363,6 @@ public:
|
||||
/** Touches the chunk, causing it to be loaded or generated */
|
||||
void TouchChunk(int a_ChunkX, int a_ChunkZ);
|
||||
|
||||
/** Loads the chunk, if not already loaded. Doesn't generate. Returns true if chunk valid (even if already loaded before) */
|
||||
bool LoadChunk(int a_ChunkX, int a_ChunkZ);
|
||||
|
||||
/** Loads the chunks specified. Doesn't report failure, other than chunks being !IsValid() */
|
||||
void LoadChunks(const cChunkCoordsList & a_Chunks);
|
||||
|
||||
/** Marks the chunk as failed-to-load: */
|
||||
void ChunkLoadFailed(int a_ChunkX, int a_ChunkZ);
|
||||
|
||||
@ -822,6 +821,7 @@ private:
|
||||
virtual void OnChunkGenerated (cChunkDesc & a_ChunkDesc) override;
|
||||
virtual bool IsChunkValid (int a_ChunkX, int a_ChunkZ) override;
|
||||
virtual bool HasChunkAnyClients(int a_ChunkX, int a_ChunkZ) override;
|
||||
virtual bool IsChunkQueued (int a_ChunkX, int a_ChunkZ) override;
|
||||
|
||||
// cPluginInterface overrides:
|
||||
virtual void CallHookChunkGenerating(cChunkDesc & a_ChunkDesc) override;
|
||||
|
@ -143,6 +143,8 @@ size_t cWorldStorage::GetSaveQueueLength(void)
|
||||
|
||||
void cWorldStorage::QueueLoadChunk(int a_ChunkX, int a_ChunkZ, bool a_Generate)
|
||||
{
|
||||
ASSERT(m_World->IsChunkQueued(a_ChunkX, a_ChunkZ));
|
||||
|
||||
m_LoadQueue.EnqueueItem(sChunkLoad(a_ChunkX, a_ChunkZ, a_Generate));
|
||||
m_Event.Set();
|
||||
}
|
||||
@ -153,6 +155,8 @@ void cWorldStorage::QueueLoadChunk(int a_ChunkX, int a_ChunkZ, bool a_Generate)
|
||||
|
||||
void cWorldStorage::QueueSaveChunk(int a_ChunkX, int a_ChunkZ)
|
||||
{
|
||||
ASSERT(m_World->IsChunkValid(a_ChunkX, a_ChunkZ));
|
||||
|
||||
m_SaveQueue.EnqueueItemIfNotPresent(cChunkCoords(a_ChunkX, a_ChunkZ));
|
||||
m_Event.Set();
|
||||
}
|
||||
@ -244,6 +248,7 @@ bool cWorldStorage::LoadOneChunk(void)
|
||||
{
|
||||
sChunkLoad ToLoad(0, 0, false);
|
||||
bool ShouldLoad = m_LoadQueue.TryDequeueItem(ToLoad);
|
||||
|
||||
if (ShouldLoad && !LoadChunk(ToLoad.m_ChunkX, ToLoad.m_ChunkZ))
|
||||
{
|
||||
if (ToLoad.m_Generate)
|
||||
@ -285,11 +290,7 @@ bool cWorldStorage::SaveOneChunk(void)
|
||||
|
||||
bool cWorldStorage::LoadChunk(int a_ChunkX, int a_ChunkZ)
|
||||
{
|
||||
if (m_World->IsChunkValid(a_ChunkX, a_ChunkZ))
|
||||
{
|
||||
// Already loaded (can happen, since the queue is async)
|
||||
return true;
|
||||
}
|
||||
ASSERT(m_World->IsChunkQueued(a_ChunkX, a_ChunkZ));
|
||||
|
||||
cChunkCoords Coords(a_ChunkX, a_ChunkZ);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user