summaryrefslogtreecommitdiffstats
path: root/src/Generating
diff options
context:
space:
mode:
authorHowaner <franzi.moos@googlemail.com>2014-09-09 01:55:21 +0200
committerHowaner <franzi.moos@googlemail.com>2014-09-09 01:55:21 +0200
commit6fb0a76b1eab47a806723b0a856609e19c5c14f9 (patch)
treec6d8712bdc4167e51d030277b28256c9bb0efe7c /src/Generating
parentPlayerSpawn packet: Send the correct uuid. (diff)
parentcapitalisation error (diff)
downloadcuberite-6fb0a76b1eab47a806723b0a856609e19c5c14f9.tar
cuberite-6fb0a76b1eab47a806723b0a856609e19c5c14f9.tar.gz
cuberite-6fb0a76b1eab47a806723b0a856609e19c5c14f9.tar.bz2
cuberite-6fb0a76b1eab47a806723b0a856609e19c5c14f9.tar.lz
cuberite-6fb0a76b1eab47a806723b0a856609e19c5c14f9.tar.xz
cuberite-6fb0a76b1eab47a806723b0a856609e19c5c14f9.tar.zst
cuberite-6fb0a76b1eab47a806723b0a856609e19c5c14f9.zip
Diffstat (limited to 'src/Generating')
-rw-r--r--src/Generating/BioGen.cpp55
-rw-r--r--src/Generating/BioGen.h30
-rw-r--r--src/Generating/ChunkGenerator.cpp43
-rw-r--r--src/Generating/ChunkGenerator.h16
-rw-r--r--src/Generating/ComposableGenerator.cpp32
5 files changed, 144 insertions, 32 deletions
diff --git a/src/Generating/BioGen.cpp b/src/Generating/BioGen.cpp
index 8fad9f5c9..60ad4e3eb 100644
--- a/src/Generating/BioGen.cpp
+++ b/src/Generating/BioGen.cpp
@@ -151,7 +151,7 @@ void cBioGenCache::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a
LOGD("BioGenCache: %d hits, %d misses, saved %.2f %%", m_NumHits, m_NumMisses, 100.0 * m_NumHits / (m_NumHits + m_NumMisses));
LOGD("BioGenCache: Avg cache chain length: %.2f", (float)m_TotalChain / m_NumHits);
}
-
+
for (int i = 0; i < m_CacheSize; i++)
{
if (
@@ -208,6 +208,59 @@ void cBioGenCache::InitializeBiomeGen(cIniFile & a_IniFile)
+////////////////////////////////////////////////////////////////////////////////
+// cBioGenMulticache:
+
+cBioGenMulticache::cBioGenMulticache(cBiomeGen * a_BioGenToCache, size_t a_CacheSize, size_t a_CachesLength) :
+ m_CachesLength(a_CachesLength)
+{
+ m_Caches.reserve(a_CachesLength);
+ for (size_t i = 0; i < a_CachesLength; i++)
+ {
+ m_Caches.push_back(new cBioGenCache(a_BioGenToCache, a_CacheSize));
+ }
+}
+
+
+
+
+
+cBioGenMulticache::~cBioGenMulticache()
+{
+ for (cBiomeGens::iterator it = m_Caches.begin(); it != m_Caches.end(); it++)
+ {
+ delete *it;
+ }
+}
+
+
+
+
+
+void cBioGenMulticache::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap)
+{
+ const size_t coefficient = 3;
+ const size_t cacheIdx = ((size_t)a_ChunkX + coefficient * (size_t)a_ChunkZ) % m_CachesLength;
+
+ m_Caches[cacheIdx]->GenBiomes(a_ChunkX, a_ChunkZ, a_BiomeMap);
+}
+
+
+
+
+
+void cBioGenMulticache::InitializeBiomeGen(cIniFile & a_IniFile)
+{
+ for (cBiomeGens::iterator it = m_Caches.begin(); it != m_Caches.end(); it++)
+ {
+ cBiomeGen * tmp = *it;
+ tmp->InitializeBiomeGen(a_IniFile);
+ }
+}
+
+
+
+
////////////////////////////////////////////////////////////////////////////////
// cBiomeGenList:
diff --git a/src/Generating/BioGen.h b/src/Generating/BioGen.h
index 227ec97d7..20d199611 100644
--- a/src/Generating/BioGen.h
+++ b/src/Generating/BioGen.h
@@ -80,6 +80,36 @@ protected:
+class cBioGenMulticache :
+ public cBiomeGen
+{
+
+ typedef cBiomeGen super;
+
+public:
+ /*
+ a_CacheSize defines the size of each singular cache
+ a_CachesLength defines how many caches are used for the multicache
+ */
+ cBioGenMulticache(cBiomeGen * a_BioGenToCache, size_t a_CacheSize, size_t a_CachesLength); // Doesn't take ownership of a_BioGenToCache
+ ~cBioGenMulticache();
+
+protected:
+ typedef std::vector<cBiomeGen *> cBiomeGens;
+
+
+ size_t m_CachesLength;
+ cBiomeGens m_Caches;
+
+
+ virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override;
+ virtual void InitializeBiomeGen(cIniFile & a_IniFile) override;
+};
+
+
+
+
+
/// Base class for generators that use a list of available biomes. This class takes care of the list.
class cBiomeGenList :
public cBiomeGen
diff --git a/src/Generating/ChunkGenerator.cpp b/src/Generating/ChunkGenerator.cpp
index a1188f984..d615456c1 100644
--- a/src/Generating/ChunkGenerator.cpp
+++ b/src/Generating/ChunkGenerator.cpp
@@ -52,10 +52,21 @@ bool cChunkGenerator::Start(cPluginInterface & a_PluginInterface, cChunkSink & a
m_PluginInterface = &a_PluginInterface;
m_ChunkSink = &a_ChunkSink;
- MTRand rnd;
- m_Seed = a_IniFile.GetValueSetI("Seed", "Seed", (int)rnd.randInt());
+ // Get the seed; create a new one and log it if not found in the INI file:
+ if (a_IniFile.HasValue("Seed", "Seed"))
+ {
+ m_Seed = a_IniFile.GetValueI("Seed", "Seed");
+ }
+ else
+ {
+ MTRand rnd;
+ m_Seed = rnd.randInt();
+ LOGINFO("Chosen a new random seed for world: %d", m_Seed);
+ a_IniFile.SetValueI("Seed", "Seed", m_Seed);
+ }
+
+ // Get the generator engine based on the INI file settings:
AString GeneratorName = a_IniFile.GetValueSet("Generator", "Generator", "Composable");
-
if (NoCaseCompare(GeneratorName, "Noise3D") == 0)
{
m_Generator = new cNoise3DGenerator(*this);
@@ -99,15 +110,17 @@ void cChunkGenerator::Stop(void)
-void cChunkGenerator::QueueGenerateChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
+void cChunkGenerator::QueueGenerateChunk(int a_ChunkX, int a_ChunkZ, bool a_ForceGenerate)
{
+ ASSERT(m_ChunkSink->IsChunkQueued(a_ChunkX, a_ChunkZ));
+
{
cCSLock Lock(m_CS);
// Check if it is already in the queue:
- for (cChunkCoordsList::iterator itr = m_Queue.begin(); itr != m_Queue.end(); ++itr)
+ for (cChunkCoordsWithBoolList::iterator itr = m_Queue.begin(); itr != m_Queue.end(); ++itr)
{
- if ((itr->m_ChunkX == a_ChunkX) && (itr->m_ChunkY == a_ChunkY) && (itr->m_ChunkZ == a_ChunkZ))
+ if ((itr->m_ChunkX == a_ChunkX) && (itr->m_ChunkZ == a_ChunkZ))
{
// Already in the queue, bail out
return;
@@ -119,7 +132,7 @@ void cChunkGenerator::QueueGenerateChunk(int a_ChunkX, int a_ChunkY, int a_Chunk
{
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(cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ));
+ m_Queue.push_back(cChunkCoordsWithBool(a_ChunkX, a_ChunkZ, a_ForceGenerate));
}
m_Event.Set();
@@ -229,9 +242,9 @@ void cChunkGenerator::Execute(void)
continue;
}
- cChunkCoords coords = m_Queue.front(); // Get next coord from queue
- m_Queue.erase( m_Queue.begin()); // Remove coordinate from queue
+ cChunkCoordsWithBool coords = m_Queue.front(); // Get next coord from queue
bool SkipEnabled = (m_Queue.size() > QUEUE_SKIP_LIMIT);
+ m_Queue.erase(m_Queue.begin()); // Remove coordinate from queue
Lock.Unlock(); // Unlock ASAP
m_evtRemoved.Set();
@@ -245,8 +258,7 @@ void cChunkGenerator::Execute(void)
LastReportTick = clock();
}
- // Hack for regenerating chunks: if Y != 0, the chunk is considered invalid, even if it has its data set
- if ((coords.m_ChunkY == 0) && m_ChunkSink->IsChunkValid(coords.m_ChunkX, coords.m_ChunkZ))
+ if (!coords.m_ForceGenerate && m_ChunkSink->IsChunkValid(coords.m_ChunkX, coords.m_ChunkZ))
{
LOGD("Chunk [%d, %d] already generated, skipping generation", coords.m_ChunkX, coords.m_ChunkZ);
// Already generated, ignore request
@@ -259,8 +271,8 @@ void cChunkGenerator::Execute(void)
continue;
}
- LOGD("Generating chunk [%d, %d, %d]", coords.m_ChunkX, coords.m_ChunkY, coords.m_ChunkZ);
- DoGenerate(coords.m_ChunkX, coords.m_ChunkY, coords.m_ChunkZ);
+ LOGD("Generating chunk [%d, %d]", coords.m_ChunkX, coords.m_ChunkZ);
+ DoGenerate(coords.m_ChunkX, coords.m_ChunkZ);
NumChunksGenerated++;
} // while (!bStop)
@@ -269,11 +281,12 @@ void cChunkGenerator::Execute(void)
-void cChunkGenerator::DoGenerate(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
+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);
diff --git a/src/Generating/ChunkGenerator.h b/src/Generating/ChunkGenerator.h
index 88d71f3f9..190d9e616 100644
--- a/src/Generating/ChunkGenerator.h
+++ b/src/Generating/ChunkGenerator.h
@@ -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;
} ;
@@ -116,7 +120,7 @@ public:
void Stop(void);
/// Queues the chunk for generation; removes duplicate requests
- void QueueGenerateChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ);
+ void QueueGenerateChunk(int a_ChunkX, int a_ChunkZ, bool a_ForceGenerate);
/// Generates the biomes for the specified chunk (directly, not in a separate thread). Used by the world loader if biomes failed loading.
void GenerateBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap);
@@ -137,10 +141,10 @@ private:
int m_Seed;
- cCriticalSection m_CS;
- cChunkCoordsList m_Queue;
- cEvent m_Event; ///< Set when an item is added to the queue or the thread should terminate
- cEvent m_evtRemoved; ///< Set when an item is removed from the queue
+ cCriticalSection m_CS;
+ cChunkCoordsWithBoolList m_Queue;
+ cEvent m_Event; ///< Set when an item is added to the queue or the thread should terminate
+ cEvent m_evtRemoved; ///< Set when an item is removed from the queue
cGenerator * m_Generator; ///< The actual generator engine used to generate chunks
@@ -154,7 +158,7 @@ private:
// cIsThread override:
virtual void Execute(void) override;
- void DoGenerate(int a_ChunkX, int a_ChunkY, int a_ChunkZ);
+ void DoGenerate(int a_ChunkX, int a_ChunkZ);
};
diff --git a/src/Generating/ComposableGenerator.cpp b/src/Generating/ComposableGenerator.cpp
index 6f4007d24..69068d231 100644
--- a/src/Generating/ComposableGenerator.cpp
+++ b/src/Generating/ComposableGenerator.cpp
@@ -230,17 +230,29 @@ void cComposableGenerator::InitBiomeGen(cIniFile & a_IniFile)
// Add a cache, if requested:
int CacheSize = a_IniFile.GetValueSetI("Generator", "BiomeGenCacheSize", CacheOffByDefault ? 0 : 64);
- if (CacheSize > 0)
+
+ if (CacheSize <= 0)
+ {
+ return;
+ }
+
+ int MultiCacheLength = a_IniFile.GetValueSetI("Generator", "BiomeGenMultiCacheLength", 4);
+ if (CacheSize < 4)
+ {
+ LOGWARNING("Biomegen cache size set too low, would hurt performance instead of helping. Increasing from %d to %d",
+ CacheSize, 4
+ );
+ CacheSize = 4;
+ }
+ LOGD("Using a cache for biomegen of size %d.", CacheSize);
+ m_UnderlyingBiomeGen = m_BiomeGen;
+ if (MultiCacheLength > 0)
+ {
+ LOGD("Enabling multicache for biomegen of length %d.", MultiCacheLength);
+ m_BiomeGen = new cBioGenMulticache(m_UnderlyingBiomeGen, CacheSize, MultiCacheLength);
+ }
+ else
{
- if (CacheSize < 4)
- {
- LOGWARNING("Biomegen cache size set too low, would hurt performance instead of helping. Increasing from %d to %d",
- CacheSize, 4
- );
- CacheSize = 4;
- }
- LOGD("Using a cache for biomegen of size %d.", CacheSize);
- m_UnderlyingBiomeGen = m_BiomeGen;
m_BiomeGen = new cBioGenCache(m_UnderlyingBiomeGen, CacheSize);
}
}