summaryrefslogtreecommitdiffstats
path: root/src/Generating/ChunkGenerator.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Generating/ChunkGenerator.cpp')
-rw-r--r--src/Generating/ChunkGenerator.cpp108
1 files changed, 27 insertions, 81 deletions
diff --git a/src/Generating/ChunkGenerator.cpp b/src/Generating/ChunkGenerator.cpp
index e7c2e4125..c5d830d0d 100644
--- a/src/Generating/ChunkGenerator.cpp
+++ b/src/Generating/ChunkGenerator.cpp
@@ -15,9 +15,6 @@
/** If the generation queue size exceeds this number, a warning will be output */
const unsigned int QUEUE_WARNING_LIMIT = 1000;
-/** If the generation queue size exceeds this number, chunks with no clients will be skipped */
-const unsigned int QUEUE_SKIP_LIMIT = 500;
-
@@ -114,6 +111,11 @@ void cChunkGenerator::QueueGenerateChunk(int a_ChunkX, int a_ChunkZ, bool a_Forc
{
ASSERT(m_ChunkSink->IsChunkQueued(a_ChunkX, a_ChunkZ));
+ if (!a_ForceGenerate && m_ChunkSink->IsChunkValid(a_ChunkX, a_ChunkZ))
+ {
+ return;
+ }
+
{
cCSLock Lock(m_CS);
@@ -122,7 +124,7 @@ void cChunkGenerator::QueueGenerateChunk(int a_ChunkX, int a_ChunkZ, bool a_Forc
{
LOGWARN("WARNING: Adding chunk [%i, %i] to generation queue; Queue is too big! (" SIZE_T_FMT ")", a_ChunkX, a_ChunkZ, m_Queue.size());
}
- m_Queue.push_back(cQueueItem{a_ChunkX, a_ChunkZ, a_ForceGenerate, a_Callback});
+ m_Queue.emplace_back(sQueueItem{ a_ChunkX, a_ChunkZ, a_Callback });
}
m_Event.Set();
@@ -144,20 +146,6 @@ void cChunkGenerator::GenerateBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::Biom
-void cChunkGenerator::WaitForQueueEmpty(void)
-{
- cCSLock Lock(m_CS);
- while (!m_ShouldTerminate && !m_Queue.empty())
- {
- cCSUnlock Unlock(Lock);
- m_evtRemoved.Wait();
- }
-}
-
-
-
-
-
int cChunkGenerator::GetQueueLength(void)
{
cCSLock Lock(m_CS);
@@ -204,80 +192,39 @@ void cChunkGenerator::Execute(void)
while (!m_ShouldTerminate)
{
- cCSLock Lock(m_CS);
- while (m_Queue.empty())
- {
- if ((NumChunksGenerated > 16) && (clock() - LastReportTick > CLOCKS_PER_SEC))
- {
- /* LOG("Chunk generator performance: %.2f ch / sec (%d ch total)",
- static_cast<double>(NumChunksGenerated) * CLOCKS_PER_SEC/ (clock() - GenerationStart),
- NumChunksGenerated
- ); */
- }
- cCSUnlock Unlock(Lock);
- m_Event.Wait();
- if (m_ShouldTerminate)
- {
- return;
- }
- NumChunksGenerated = 0;
- GenerationStart = clock();
- LastReportTick = clock();
- }
+ m_Event.Wait();
- if (m_Queue.empty())
+ decltype(m_Queue) QueuedChunks;
{
- // Sometimes the queue remains empty
- // If so, we can't do any front() operations on it!
- continue;
+ cCSLock Lock(m_CS);
+ std::swap(QueuedChunks, m_Queue);
}
- cQueueItem item = m_Queue.front(); // Get next chunk from the queue
- bool SkipEnabled = (m_Queue.size() > QUEUE_SKIP_LIMIT);
- m_Queue.erase(m_Queue.begin()); // Remove the item from the queue
- Lock.Unlock(); // Unlock ASAP
- m_evtRemoved.Set();
-
- // Display perf info once in a while:
- if ((NumChunksGenerated > 512) && (clock() - LastReportTick > 2 * CLOCKS_PER_SEC))
- {
- LOG("Chunk generator performance: %.2f ch / sec (%d ch total)",
- static_cast<double>(NumChunksGenerated) * CLOCKS_PER_SEC / (clock() - GenerationStart),
- NumChunksGenerated
- );
- LastReportTick = clock();
- }
+ NumChunksGenerated = 0;
+ GenerationStart = clock();
+ LastReportTick = clock();
- // Skip the chunk if it's already generated and regeneration is not forced. Report as success:
- if (!item.m_ForceGenerate && m_ChunkSink->IsChunkValid(item.m_ChunkX, item.m_ChunkZ))
+ for (const auto & Item : QueuedChunks)
{
- LOGD("Chunk [%d, %d] already generated, skipping generation", item.m_ChunkX, item.m_ChunkZ);
- if (item.m_Callback != nullptr)
+ // Display perf info once in a while:
+ if ((NumChunksGenerated > 512) && (clock() - LastReportTick > 2 * CLOCKS_PER_SEC))
{
- item.m_Callback->Call(item.m_ChunkX, item.m_ChunkZ, true);
+ LOG("Chunk generator performance: %.2f ch / sec (%d ch total)",
+ static_cast<double>(NumChunksGenerated) * CLOCKS_PER_SEC / (clock() - GenerationStart),
+ NumChunksGenerated
+ );
+ LastReportTick = clock();
}
- continue;
- }
- // Skip the chunk if the generator is overloaded:
- if (SkipEnabled && !m_ChunkSink->HasChunkAnyClients(item.m_ChunkX, item.m_ChunkZ))
- {
- LOGWARNING("Chunk generator overloaded, skipping chunk [%d, %d]", item.m_ChunkX, item.m_ChunkZ);
- if (item.m_Callback != nullptr)
+ // Generate the chunk:
+ // LOGD("Generating chunk [%d, %d]", Item.m_ChunkX, Item.m_ChunkZ);
+ DoGenerate(Item.m_ChunkX, Item.m_ChunkZ);
+ if (Item.m_Callback != nullptr)
{
- item.m_Callback->Call(item.m_ChunkX, item.m_ChunkZ, false);
+ Item.m_Callback->Call(Item.m_ChunkX, Item.m_ChunkZ, true);
}
- continue;
+ NumChunksGenerated++;
}
-
- // Generate the chunk:
- // LOGD("Generating chunk [%d, %d]", item.m_ChunkX, item.m_ChunkZ);
- DoGenerate(item.m_ChunkX, item.m_ChunkZ);
- if (item.m_Callback != nullptr)
- {
- item.m_Callback->Call(item.m_ChunkX, item.m_ChunkZ, true);
- }
- NumChunksGenerated++;
} // while (!bStop)
}
@@ -288,7 +235,6 @@ void cChunkGenerator::DoGenerate(int a_ChunkX, int a_ChunkZ)
{
ASSERT(m_PluginInterface != nullptr);
ASSERT(m_ChunkSink != nullptr);
- ASSERT(m_ChunkSink->IsChunkQueued(a_ChunkX, a_ChunkZ));
cChunkDesc ChunkDesc(a_ChunkX, a_ChunkZ);
m_PluginInterface->CallHookChunkGenerating(ChunkDesc);