#include "profiler.h"
#include "scripting_server.h"
#include "server.h"
-#include "serverobject.h"
#include "settings.h"
#include "voxel.h"
VoxelArea *m_ignorevariable;
};
+EmergeParams::~EmergeParams()
+{
+ infostream << "EmergeParams: destroying " << this << std::endl;
+ // Delete everything that was cloned on creation of EmergeParams
+ delete biomegen;
+ delete biomemgr;
+ delete oremgr;
+ delete decomgr;
+ delete schemmgr;
+}
+
+EmergeParams::EmergeParams(EmergeManager *parent, const BiomeGen *biomegen,
+ const BiomeManager *biomemgr,
+ const OreManager *oremgr, const DecorationManager *decomgr,
+ const SchematicManager *schemmgr) :
+ ndef(parent->ndef),
+ enable_mapgen_debug_info(parent->enable_mapgen_debug_info),
+ gen_notify_on(parent->gen_notify_on),
+ gen_notify_on_deco_ids(&parent->gen_notify_on_deco_ids),
+ biomemgr(biomemgr->clone()), oremgr(oremgr->clone()),
+ decomgr(decomgr->clone()), schemmgr(schemmgr->clone())
+{
+ this->biomegen = biomegen->clone(this->biomemgr);
+}
+
////
//// EmergeManager
////
this->decomgr = new DecorationManager(server);
this->schemmgr = new SchematicManager(server);
+ // initialized later
+ this->mgparams = nullptr;
+ this->biomegen = nullptr;
+
// Note that accesses to this variable are not synchronized.
// This is because the *only* thread ever starting or stopping
// EmergeThreads should be the ServerThread.
nthreads = Thread::getNumberOfProcessors() - 2;
if (nthreads < 1)
nthreads = 1;
- verbosestream << "Using " << nthreads << " emerge threads." << std::endl;
m_qlimit_total = g_settings->getU16("emergequeue_limit_total");
+ // FIXME: these fallback values are probably not good
if (!g_settings->getU16NoEx("emergequeue_limit_diskonly", m_qlimit_diskonly))
m_qlimit_diskonly = nthreads * 5 + 1;
if (!g_settings->getU16NoEx("emergequeue_limit_generate", m_qlimit_generate))
}
+BiomeManager *EmergeManager::getWritableBiomeManager()
+{
+ FATAL_ERROR_IF(!m_mapgens.empty(),
+ "Writable managers can only be returned before mapgen init");
+ return biomemgr;
+}
+
+OreManager *EmergeManager::getWritableOreManager()
+{
+ FATAL_ERROR_IF(!m_mapgens.empty(),
+ "Writable managers can only be returned before mapgen init");
+ return oremgr;
+}
+
+DecorationManager *EmergeManager::getWritableDecorationManager()
+{
+ FATAL_ERROR_IF(!m_mapgens.empty(),
+ "Writable managers can only be returned before mapgen init");
+ return decomgr;
+}
+
+SchematicManager *EmergeManager::getWritableSchematicManager()
+{
+ FATAL_ERROR_IF(!m_mapgens.empty(),
+ "Writable managers can only be returned before mapgen init");
+ return schemmgr;
+}
+
+
void EmergeManager::initMapgens(MapgenParams *params)
{
- FATAL_ERROR_IF(!m_mapgens.empty(), "mapgen already inited.");
+ FATAL_ERROR_IF(!m_mapgens.empty(), "Mapgen already initialised.");
mgparams = params;
- for (u32 i = 0; i != m_threads.size(); i++)
- m_mapgens.push_back(Mapgen::createMapgen(params->mgtype, i, params, this));
+ v3s16 csize = v3s16(1, 1, 1) * (params->chunksize * MAP_BLOCKSIZE);
+ biomegen = biomemgr->createBiomeGen(BIOMEGEN_ORIGINAL, params->bparams, csize);
+
+ for (u32 i = 0; i != m_threads.size(); i++) {
+ EmergeParams *p = new EmergeParams(this, biomegen,
+ biomemgr, oremgr, decomgr, schemmgr);
+ infostream << "EmergeManager: Created params " << p
+ << " for thread " << i << std::endl;
+ m_mapgens.push_back(Mapgen::createMapgen(params->mgtype, params, p));
+ }
}
return nullptr;
for (u32 i = 0; i != m_threads.size(); i++) {
- if (m_threads[i]->isCurrentThread())
- return m_threads[i]->m_mapgen;
+ EmergeThread *t = m_threads[i];
+ if (t->isRunning() && t->isCurrentThread())
+ return t->m_mapgen;
}
return nullptr;
}
+bool EmergeManager::isBlockInQueue(v3s16 pos)
+{
+ MutexAutoLock queuelock(m_queue_mutex);
+ return m_blocks_enqueued.find(pos) != m_blocks_enqueued.end();
+}
+
+
//
// Mapgen-related helper functions
//
// TODO(hmmmm): Move this to ServerMap
bool EmergeManager::isBlockUnderground(v3s16 blockpos)
{
-#if 0
- v2s16 p = v2s16((blockpos.X * MAP_BLOCKSIZE) + MAP_BLOCKSIZE / 2,
- (blockpos.Y * MAP_BLOCKSIZE) + MAP_BLOCKSIZE / 2);
- int ground_level = getGroundLevelAtPoint(p);
- return blockpos.Y * (MAP_BLOCKSIZE + 1) <= min(water_level, ground_level);
-#endif
-
- // Use a simple heuristic; the above method is wildly inaccurate anyway.
+ // Use a simple heuristic
return blockpos.Y * (MAP_BLOCKSIZE + 1) <= mgparams->water_level;
}
m_qlimit_generate : m_qlimit_diskonly;
if (count_peer >= qlimit_peer)
return false;
+ } else {
+ // limit block enqueue requests for active blocks to 1/2 of total
+ if (count_peer * 2 >= m_qlimit_total)
+ return false;
}
}
/*
Clear generate notifier events
*/
- Mapgen *mg = m_emerge->getCurrentMapgen();
- mg->gennotify.clearEvents();
+ m_mapgen->gennotify.clearEvents();
EMERGE_DBG_OUT("ended up with: " << analyze_block(block));
{
ScopeProfiler sp(g_profiler,
"EmergeThread: Mapgen::makeChunk", SPT_AVG);
- TimeTaker t("mapgen::make_block()");
m_mapgen->makeChunk(&bmdata);
-
- if (!enable_mapgen_debug_info)
- t.stop(true); // Hide output
}
block = finishGen(pos, &bmdata, &modified_blocks);