X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;ds=sidebyside;f=src%2Femerge.cpp;h=0ac26a68232b35bb81e1e464fe18d03401d6fbbd;hb=1c38027c3a72402d752a8150701a44753e22990e;hp=a3efb09e78fd4190a98ace1cd8ad683b9591b7ac;hpb=ba0a8dabeff92ecd87d28b4b5b4010e958be5851;p=minetest.git diff --git a/src/emerge.cpp b/src/emerge.cpp index a3efb09e7..0ac26a682 100644 --- a/src/emerge.cpp +++ b/src/emerge.cpp @@ -34,15 +34,14 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "log.h" #include "map.h" #include "mapblock.h" -#include "mg_biome.h" -#include "mg_ore.h" -#include "mg_decoration.h" -#include "mg_schematic.h" +#include "mapgen/mg_biome.h" +#include "mapgen/mg_ore.h" +#include "mapgen/mg_decoration.h" +#include "mapgen/mg_schematic.h" #include "nodedef.h" #include "profiler.h" -#include "serverscripting.h" +#include "scripting_server.h" #include "server.h" -#include "serverobject.h" #include "settings.h" #include "voxel.h" @@ -52,18 +51,18 @@ class EmergeThread : public Thread { int id; EmergeThread(Server *server, int ethreadid); - ~EmergeThread(); + ~EmergeThread() = default; void *run(); void signal(); // Requires queue mutex held - bool pushBlock(v3s16 pos); + bool pushBlock(const v3s16 &pos); void cancelPendingItems(); static void runCompletionCallbacks( - v3s16 pos, EmergeAction action, + const v3s16 &pos, EmergeAction action, const EmergeCallbackList &callbacks); private: @@ -78,13 +77,60 @@ class EmergeThread : public Thread { bool popBlockEmerge(v3s16 *pos, BlockEmergeData *bedata); EmergeAction getBlockOrStartGen( - v3s16 pos, bool allow_gen, MapBlock **block, BlockMakeData *data); + const v3s16 &pos, bool allow_gen, MapBlock **block, BlockMakeData *data); MapBlock *finishGen(v3s16 pos, BlockMakeData *bmdata, std::map *modified_blocks); friend class EmergeManager; }; +class MapEditEventAreaIgnorer +{ +public: + MapEditEventAreaIgnorer(VoxelArea *ignorevariable, const VoxelArea &a): + m_ignorevariable(ignorevariable) + { + if(m_ignorevariable->getVolume() == 0) + *m_ignorevariable = a; + else + m_ignorevariable = NULL; + } + + ~MapEditEventAreaIgnorer() + { + if(m_ignorevariable) + { + assert(m_ignorevariable->getVolume() != 0); + *m_ignorevariable = VoxelArea(); + } + } + +private: + VoxelArea *m_ignorevariable; +}; + +EmergeParams::~EmergeParams() +{ + infostream << "EmergeParams: destroying " << this << std::endl; + // Delete everything that was cloned on creation of EmergeParams + delete biomemgr; + delete oremgr; + delete decomgr; + delete schemmgr; +} + +EmergeParams::EmergeParams(EmergeManager *parent, 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()) +{ +} + //// //// EmergeManager //// @@ -96,24 +142,24 @@ EmergeManager::EmergeManager(Server *server) this->oremgr = new OreManager(server); this->decomgr = new DecorationManager(server); this->schemmgr = new SchematicManager(server); - this->gen_notify_on = 0; // Note that accesses to this variable are not synchronized. // This is because the *only* thread ever starting or stopping // EmergeThreads should be the ServerThread. - this->m_threads_active = false; enable_mapgen_debug_info = g_settings->getBool("enable_mapgen_debug_info"); - // If unspecified, leave a proc for the main thread and one for + s16 nthreads = 1; + g_settings->getS16NoEx("num_emerge_threads", nthreads); + // If automatic, leave a proc for the main thread and one for // some other misc thread - s16 nthreads = 0; - if (!g_settings->getS16NoEx("num_emerge_threads", nthreads)) + if (nthreads == 0) nthreads = Thread::getNumberOfProcessors() - 2; if (nthreads < 1) nthreads = 1; 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)) @@ -146,7 +192,10 @@ EmergeManager::~EmergeManager() } delete thread; - delete m_mapgens[i]; + + // Mapgen init might not be finished if there is an error during startup. + if (m_mapgens.size() > i) + delete m_mapgens[i]; } delete biomemgr; @@ -156,33 +205,63 @@ EmergeManager::~EmergeManager() } -bool EmergeManager::initMapgens(MapgenParams *params) +BiomeManager *EmergeManager::getWritableBiomeManager() { - if (m_mapgens.size()) - return false; + FATAL_ERROR_IF(!m_mapgens.empty(), + "Writable managers can only be returned before mapgen init"); + return biomemgr; +} - this->mgparams = params; +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 initialised."); + + mgparams = params; for (u32 i = 0; i != m_threads.size(); i++) { - Mapgen *mg = Mapgen::createMapgen(params->mgtype, i, params, this); - m_mapgens.push_back(mg); + EmergeParams *p = new EmergeParams( + this, 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 true; } Mapgen *EmergeManager::getCurrentMapgen() { if (!m_threads_active) - return NULL; + 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 NULL; + return nullptr; } @@ -224,7 +303,7 @@ bool EmergeManager::isRunning() bool EmergeManager::enqueueBlockEmerge( - u16 peer_id, + session_t peer_id, v3s16 blockpos, bool allow_generate, bool ignore_queue_limits) @@ -241,7 +320,7 @@ bool EmergeManager::enqueueBlockEmerge( bool EmergeManager::enqueueBlockEmergeEx( v3s16 blockpos, - u16 peer_id, + session_t peer_id, u16 flags, EmergeCompletionCallback callback, void *callback_param) @@ -293,7 +372,7 @@ v3s16 EmergeManager::getContainingChunk(v3s16 blockpos, s16 chunksize) int EmergeManager::getSpawnLevelAtPoint(v2s16 p) { - if (m_mapgens.size() == 0 || !m_mapgens[0]) { + if (m_mapgens.empty() || !m_mapgens[0]) { errorstream << "EmergeManager: getSpawnLevelAtPoint() called" " before mapgen init" << std::endl; return 0; @@ -305,7 +384,7 @@ int EmergeManager::getSpawnLevelAtPoint(v2s16 p) int EmergeManager::getGroundLevelAtPoint(v2s16 p) { - if (m_mapgens.size() == 0 || !m_mapgens[0]) { + if (m_mapgens.empty() || !m_mapgens[0]) { errorstream << "EmergeManager: getGroundLevelAtPoint() called" " before mapgen init" << std::endl; return 0; @@ -357,7 +436,7 @@ bool EmergeManager::pushBlockEmergeData( *entry_already_exists = !findres.second; if (callback) - bedata.callbacks.push_back(std::make_pair(callback, callback_param)); + bedata.callbacks.emplace_back(callback, callback_param); if (*entry_already_exists) { bedata.flags |= flags; @@ -375,7 +454,7 @@ bool EmergeManager::pushBlockEmergeData( bool EmergeManager::popBlockEmergeData(v3s16 pos, BlockEmergeData *bedata) { std::map::iterator it; - UNORDERED_MAP::iterator it2; + std::unordered_map::iterator it2; it = m_blocks_enqueued.find(pos); if (it == m_blocks_enqueued.end()) @@ -434,19 +513,13 @@ EmergeThread::EmergeThread(Server *server, int ethreadid) : } -EmergeThread::~EmergeThread() -{ - //cancelPendingItems(); -} - - void EmergeThread::signal() { m_queue_event.signal(); } -bool EmergeThread::pushBlock(v3s16 pos) +bool EmergeThread::pushBlock(const v3s16 &pos) { m_block_queue.push(pos); return true; @@ -471,9 +544,7 @@ void EmergeThread::cancelPendingItems() } -void EmergeThread::runCompletionCallbacks( - v3s16 pos, - EmergeAction action, +void EmergeThread::runCompletionCallbacks(const v3s16 &pos, EmergeAction action, const EmergeCallbackList &callbacks) { for (size_t i = 0; i != callbacks.size(); i++) { @@ -505,7 +576,7 @@ bool EmergeThread::popBlockEmerge(v3s16 *pos, BlockEmergeData *bedata) EmergeAction EmergeThread::getBlockOrStartGen( - v3s16 pos, bool allow_gen, MapBlock **block, BlockMakeData *bmdata) + const v3s16 &pos, bool allow_gen, MapBlock **block, BlockMakeData *bmdata) { MutexAutoLock envlock(m_server->m_env_mutex); @@ -570,6 +641,11 @@ MapBlock *EmergeThread::finishGen(v3s16 pos, BlockMakeData *bmdata, m_server->setAsyncFatalError("Lua: finishGen" + std::string(e.what())); } + /* + Clear generate notifier events + */ + m_mapgen->gennotify.clearEvents(); + EMERGE_DBG_OUT("ended up with: " << analyze_block(block)); /* @@ -583,7 +659,6 @@ MapBlock *EmergeThread::finishGen(v3s16 pos, BlockMakeData *bmdata, void *EmergeThread::run() { - DSTACK(FUNCTION_NAME); BEGIN_DEBUG_EXCEPTION_HANDLER v3s16 pos; @@ -606,7 +681,7 @@ void *EmergeThread::run() continue; } - if (blockpos_over_limit(pos)) + if (blockpos_over_max_limit(pos)) continue; bool allow_gen = bedata.flags & BLOCK_EMERGE_ALLOW_GEN; @@ -617,12 +692,8 @@ void *EmergeThread::run() { ScopeProfiler sp(g_profiler, "EmergeThread: Mapgen::makeChunk", SPT_AVG); - TimeTaker t("mapgen::make_block()"); m_mapgen->makeChunk(&bmdata); - - if (enable_mapgen_debug_info == false) - t.stop(true); // Hide output } block = finishGen(pos, &bmdata, &modified_blocks); @@ -633,7 +704,7 @@ void *EmergeThread::run() if (block) modified_blocks[pos] = block; - if (modified_blocks.size() > 0) + if (!modified_blocks.empty()) m_server->SetBlocksNotSent(modified_blocks); } } catch (VersionMismatchException &e) {