X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Femerge.cpp;h=ffe387f636c6d42b37e0e301a3929b129548056f;hb=f4fedfed070ffd85c3446bc5d38d2fbd577640d6;hp=157be2e64405b1bb5485a94bc7cb01f2a7bfbd09;hpb=3e0ea3c6eda27a7b6535570c2c208213be046494;p=dragonfireclient.git diff --git a/src/emerge.cpp b/src/emerge.cpp index 157be2e64..ffe387f63 100644 --- a/src/emerge.cpp +++ b/src/emerge.cpp @@ -34,49 +34,36 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "log.h" #include "map.h" #include "mapblock.h" -#include "mapgen_flat.h" -#include "mapgen_fractal.h" -#include "mapgen_v5.h" -#include "mapgen_v6.h" -#include "mapgen_v7.h" -#include "mapgen_singlenode.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 "scripting_game.h" +#include "scripting_server.h" #include "server.h" #include "serverobject.h" #include "settings.h" #include "voxel.h" - -struct MapgenDesc { - const char *name; - MapgenFactory *factory; - bool is_user_visible; -}; - class EmergeThread : public Thread { public: bool enable_mapgen_debug_info; 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: @@ -91,43 +78,53 @@ 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; }; -//// -//// Built-in mapgens -//// +class MapEditEventAreaIgnorer +{ +public: + MapEditEventAreaIgnorer(VoxelArea *ignorevariable, const VoxelArea &a): + m_ignorevariable(ignorevariable) + { + if(m_ignorevariable->getVolume() == 0) + *m_ignorevariable = a; + else + m_ignorevariable = NULL; + } -MapgenDesc g_reg_mapgens[] = { - {"v5", new MapgenFactoryV5, true}, - {"v6", new MapgenFactoryV6, true}, - {"v7", new MapgenFactoryV7, true}, - {"flat", new MapgenFactoryFlat, true}, - {"fractal", new MapgenFactoryFractal, true}, - {"singlenode", new MapgenFactorySinglenode, false}, + ~MapEditEventAreaIgnorer() + { + if(m_ignorevariable) + { + assert(m_ignorevariable->getVolume() != 0); + *m_ignorevariable = VoxelArea(); + } + } + +private: + VoxelArea *m_ignorevariable; }; //// //// EmergeManager //// -EmergeManager::EmergeManager(IGameDef *gamedef) +EmergeManager::EmergeManager(Server *server) { - this->ndef = gamedef->getNodeDefManager(); - this->biomemgr = new BiomeManager(gamedef); - this->oremgr = new OreManager(gamedef); - this->decomgr = new DecorationManager(gamedef); - this->schemmgr = new SchematicManager(gamedef); - this->gen_notify_on = 0; + this->ndef = server->getNodeDefManager(); + this->biomemgr = new BiomeManager(server); + this->oremgr = new OreManager(server); + this->decomgr = new DecorationManager(server); + this->schemmgr = new SchematicManager(server); // 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"); @@ -154,7 +151,7 @@ EmergeManager::EmergeManager(IGameDef *gamedef) m_qlimit_generate = 1; for (s16 i = 0; i < nthreads; i++) - m_threads.push_back(new EmergeThread((Server *)gamedef, i)); + m_threads.push_back(new EmergeThread(server, i)); infostream << "EmergeManager: using " << nthreads << " threads" << std::endl; } @@ -179,47 +176,30 @@ EmergeManager::~EmergeManager() delete oremgr; delete decomgr; delete schemmgr; - - delete params.sparams; } -void EmergeManager::loadMapgenParams() +bool EmergeManager::initMapgens(MapgenParams *params) { - params.load(*g_settings); -} - - -void EmergeManager::initMapgens() -{ - if (m_mapgens.size()) - return; - - MapgenFactory *mgfactory = getMapgenFactory(params.mg_name); - if (!mgfactory) { - errorstream << "EmergeManager: mapgen " << params.mg_name << - " not registered; falling back to " << DEFAULT_MAPGEN << std::endl; - - params.mg_name = DEFAULT_MAPGEN; - - mgfactory = getMapgenFactory(params.mg_name); - FATAL_ERROR_IF(mgfactory == NULL, "Couldn't use any mapgen!"); - } + if (!m_mapgens.empty()) + return false; - if (!params.sparams) { - params.sparams = mgfactory->createMapgenParams(); - params.sparams->readParams(g_settings); - } + this->mgparams = params; for (u32 i = 0; i != m_threads.size(); i++) { - Mapgen *mg = mgfactory->createMapgen(i, ¶ms, this); + Mapgen *mg = Mapgen::createMapgen(params->mgtype, i, params, this); m_mapgens.push_back(mg); } + + return true; } Mapgen *EmergeManager::getCurrentMapgen() { + if (!m_threads_active) + return NULL; + for (u32 i = 0; i != m_threads.size(); i++) { if (m_threads[i]->isCurrentThread()) return m_threads[i]->m_mapgen; @@ -267,7 +247,7 @@ bool EmergeManager::isRunning() bool EmergeManager::enqueueBlockEmerge( - u16 peer_id, + session_t peer_id, v3s16 blockpos, bool allow_generate, bool ignore_queue_limits) @@ -284,20 +264,24 @@ bool EmergeManager::enqueueBlockEmerge( bool EmergeManager::enqueueBlockEmergeEx( v3s16 blockpos, - u16 peer_id, + session_t peer_id, u16 flags, EmergeCompletionCallback callback, void *callback_param) { EmergeThread *thread = NULL; + bool entry_already_exists = false; { MutexAutoLock queuelock(m_queue_mutex); if (!pushBlockEmergeData(blockpos, peer_id, flags, - callback, callback_param)) + callback, callback_param, &entry_already_exists)) return false; + if (entry_already_exists) + return true; + thread = getOptimalThread(); thread->pushBlock(blockpos); } @@ -312,12 +296,14 @@ bool EmergeManager::enqueueBlockEmergeEx( // Mapgen-related helper functions // + +// TODO(hmmmm): Move this to ServerMap v3s16 EmergeManager::getContainingChunk(v3s16 blockpos) { - return getContainingChunk(blockpos, params.chunksize); + return getContainingChunk(blockpos, mgparams->chunksize); } - +// TODO(hmmmm): Move this to ServerMap v3s16 EmergeManager::getContainingChunk(v3s16 blockpos, s16 chunksize) { s16 coff = -chunksize / 2; @@ -328,9 +314,21 @@ v3s16 EmergeManager::getContainingChunk(v3s16 blockpos, s16 chunksize) } +int EmergeManager::getSpawnLevelAtPoint(v2s16 p) +{ + if (m_mapgens.empty() || !m_mapgens[0]) { + errorstream << "EmergeManager: getSpawnLevelAtPoint() called" + " before mapgen init" << std::endl; + return 0; + } + + return m_mapgens[0]->getSpawnLevelAtPoint(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; @@ -339,7 +337,7 @@ int EmergeManager::getGroundLevelAtPoint(v2s16 p) return m_mapgens[0]->getGroundLevelAtPoint(p); } - +// TODO(hmmmm): Move this to ServerMap bool EmergeManager::isBlockUnderground(v3s16 blockpos) { #if 0 @@ -350,37 +348,16 @@ bool EmergeManager::isBlockUnderground(v3s16 blockpos) #endif // Use a simple heuristic; the above method is wildly inaccurate anyway. - return blockpos.Y * (MAP_BLOCKSIZE + 1) <= params.water_level; -} - - -void EmergeManager::getMapgenNames( - std::vector *mgnames, bool include_hidden) -{ - for (u32 i = 0; i != ARRLEN(g_reg_mapgens); i++) { - if (include_hidden || g_reg_mapgens[i].is_user_visible) - mgnames->push_back(g_reg_mapgens[i].name); - } + return blockpos.Y * (MAP_BLOCKSIZE + 1) <= mgparams->water_level; } - -MapgenFactory *EmergeManager::getMapgenFactory(const std::string &mgname) -{ - for (u32 i = 0; i != ARRLEN(g_reg_mapgens); i++) { - if (mgname == g_reg_mapgens[i].name) - return g_reg_mapgens[i].factory; - } - - return NULL; -} - - bool EmergeManager::pushBlockEmergeData( v3s16 pos, u16 peer_requested, u16 flags, EmergeCompletionCallback callback, - void *callback_param) + void *callback_param, + bool *entry_already_exists) { u16 &count_peer = m_peer_queue_count[peer_requested]; @@ -400,12 +377,12 @@ bool EmergeManager::pushBlockEmergeData( findres = m_blocks_enqueued.insert(std::make_pair(pos, BlockEmergeData())); BlockEmergeData &bedata = findres.first->second; - bool update_existing = !findres.second; + *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 (update_existing) { + if (*entry_already_exists) { bedata.flags |= flags; } else { bedata.flags = flags; @@ -418,12 +395,10 @@ bool EmergeManager::pushBlockEmergeData( } -bool EmergeManager::popBlockEmergeData( - v3s16 pos, - BlockEmergeData *bedata) +bool EmergeManager::popBlockEmergeData(v3s16 pos, BlockEmergeData *bedata) { std::map::iterator it; - std::map::iterator it2; + std::unordered_map::iterator it2; it = m_blocks_enqueued.find(pos); if (it == m_blocks_enqueued.end()) @@ -482,19 +457,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; @@ -519,9 +488,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++) { @@ -553,19 +520,21 @@ 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); // 1). Attempt to fetch block from memory *block = m_map->getBlockNoCreateNoEx(pos); - if (*block && !(*block)->isDummy() && (*block)->isGenerated()) - return EMERGE_FROM_MEMORY; - - // 2). Attempt to load block from disk - *block = m_map->loadBlock(pos); - if (*block && (*block)->isGenerated()) - return EMERGE_FROM_DISK; + if (*block && !(*block)->isDummy()) { + if ((*block)->isGenerated()) + return EMERGE_FROM_MEMORY; + } else { + // 2). Attempt to load block from disk if it was not in the memory + *block = m_map->loadBlock(pos); + if (*block && (*block)->isGenerated()) + return EMERGE_FROM_DISK; + } // 3). Attempt to start generation if (allow_gen && m_map->initBlockMake(pos, bmdata)) @@ -613,7 +582,7 @@ MapBlock *EmergeThread::finishGen(v3s16 pos, BlockMakeData *bmdata, m_server->getScriptIface()->environment_OnGenerated( minp, maxp, m_mapgen->blockseed); } catch (LuaError &e) { - m_server->setAsyncFatalError("Lua: " + std::string(e.what())); + m_server->setAsyncFatalError("Lua: finishGen" + std::string(e.what())); } EMERGE_DBG_OUT("ended up with: " << analyze_block(block)); @@ -629,7 +598,6 @@ MapBlock *EmergeThread::finishGen(v3s16 pos, BlockMakeData *bmdata, void *EmergeThread::run() { - DSTACK(FUNCTION_NAME); BEGIN_DEBUG_EXCEPTION_HANDLER v3s16 pos; @@ -652,7 +620,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; @@ -667,7 +635,7 @@ void *EmergeThread::run() m_mapgen->makeChunk(&bmdata); - if (enable_mapgen_debug_info == false) + if (!enable_mapgen_debug_info) t.stop(true); // Hide output } @@ -679,7 +647,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) {