diff options
Diffstat (limited to 'src/emerge.cpp')
-rw-r--r-- | src/emerge.cpp | 244 |
1 files changed, 141 insertions, 103 deletions
diff --git a/src/emerge.cpp b/src/emerge.cpp index e76383d09..0ac26a682 100644 --- a/src/emerge.cpp +++ b/src/emerge.cpp @@ -18,6 +18,7 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ + #include "emerge.h" #include <iostream> @@ -44,8 +45,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "settings.h" #include "voxel.h" -class EmergeThread : public Thread -{ +class EmergeThread : public Thread { public: bool enable_mapgen_debug_info; int id; @@ -61,8 +61,9 @@ public: void cancelPendingItems(); - static void runCompletionCallbacks(const v3s16 &pos, EmergeAction action, - const EmergeCallbackList &callbacks); + static void runCompletionCallbacks( + const v3s16 &pos, EmergeAction action, + const EmergeCallbackList &callbacks); private: Server *m_server; @@ -75,10 +76,10 @@ private: bool popBlockEmerge(v3s16 *pos, BlockEmergeData *bedata); - EmergeAction getBlockOrStartGen(const v3s16 &pos, bool allow_gen, - MapBlock **block, BlockMakeData *data); + EmergeAction getBlockOrStartGen( + const v3s16 &pos, bool allow_gen, MapBlock **block, BlockMakeData *data); MapBlock *finishGen(v3s16 pos, BlockMakeData *bmdata, - std::map<v3s16, MapBlock *> *modified_blocks); + std::map<v3s16, MapBlock *> *modified_blocks); friend class EmergeManager; }; @@ -86,10 +87,10 @@ private: class MapEditEventAreaIgnorer { public: - MapEditEventAreaIgnorer(VoxelArea *ignorevariable, const VoxelArea &a) : - m_ignorevariable(ignorevariable) + MapEditEventAreaIgnorer(VoxelArea *ignorevariable, const VoxelArea &a): + m_ignorevariable(ignorevariable) { - if (m_ignorevariable->getVolume() == 0) + if(m_ignorevariable->getVolume() == 0) *m_ignorevariable = a; else m_ignorevariable = NULL; @@ -97,7 +98,8 @@ public: ~MapEditEventAreaIgnorer() { - if (m_ignorevariable) { + if(m_ignorevariable) + { assert(m_ignorevariable->getVolume() != 0); *m_ignorevariable = VoxelArea(); } @@ -118,14 +120,14 @@ EmergeParams::~EmergeParams() } 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()) + 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()) { } @@ -135,11 +137,11 @@ EmergeParams::EmergeParams(EmergeManager *parent, const BiomeManager *biomemgr, EmergeManager::EmergeManager(Server *server) { - this->ndef = server->getNodeDefManager(); - this->biomemgr = new BiomeManager(server); - this->oremgr = new OreManager(server); - this->decomgr = new DecorationManager(server); - this->schemmgr = new SchematicManager(server); + 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 @@ -177,6 +179,7 @@ EmergeManager::EmergeManager(Server *server) infostream << "EmergeManager: using " << nthreads << " threads" << std::endl; } + EmergeManager::~EmergeManager() { for (u32 i = 0; i != m_threads.size(); i++) { @@ -201,34 +204,36 @@ EmergeManager::~EmergeManager() delete schemmgr; } + BiomeManager *EmergeManager::getWritableBiomeManager() { FATAL_ERROR_IF(!m_mapgens.empty(), - "Writable managers can only be returned before mapgen init"); + "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"); + "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"); + "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"); + "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."); @@ -237,13 +242,14 @@ void EmergeManager::initMapgens(MapgenParams *params) for (u32 i = 0; i != m_threads.size(); i++) { EmergeParams *p = new EmergeParams( - this, biomemgr, oremgr, decomgr, schemmgr); - infostream << "EmergeManager: Created params " << p << " for thread " << i - << std::endl; + 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)); } } + Mapgen *EmergeManager::getCurrentMapgen() { if (!m_threads_active) @@ -258,6 +264,7 @@ Mapgen *EmergeManager::getCurrentMapgen() return nullptr; } + void EmergeManager::startThreads() { if (m_threads_active) @@ -269,6 +276,7 @@ void EmergeManager::startThreads() m_threads_active = true; } + void EmergeManager::stopThreads() { if (!m_threads_active) @@ -287,13 +295,18 @@ void EmergeManager::stopThreads() m_threads_active = false; } + bool EmergeManager::isRunning() { return m_threads_active; } -bool EmergeManager::enqueueBlockEmerge(session_t peer_id, v3s16 blockpos, - bool allow_generate, bool ignore_queue_limits) + +bool EmergeManager::enqueueBlockEmerge( + session_t peer_id, + v3s16 blockpos, + bool allow_generate, + bool ignore_queue_limits) { u16 flags = 0; if (allow_generate) @@ -304,8 +317,13 @@ bool EmergeManager::enqueueBlockEmerge(session_t peer_id, v3s16 blockpos, return enqueueBlockEmergeEx(blockpos, peer_id, flags, NULL, NULL); } -bool EmergeManager::enqueueBlockEmergeEx(v3s16 blockpos, session_t peer_id, u16 flags, - EmergeCompletionCallback callback, void *callback_param) + +bool EmergeManager::enqueueBlockEmergeEx( + v3s16 blockpos, + session_t peer_id, + u16 flags, + EmergeCompletionCallback callback, + void *callback_param) { EmergeThread *thread = NULL; bool entry_already_exists = false; @@ -313,8 +331,8 @@ bool EmergeManager::enqueueBlockEmergeEx(v3s16 blockpos, session_t peer_id, u16 { MutexAutoLock queuelock(m_queue_mutex); - if (!pushBlockEmergeData(blockpos, peer_id, flags, callback, - callback_param, &entry_already_exists)) + if (!pushBlockEmergeData(blockpos, peer_id, flags, + callback, callback_param, &entry_already_exists)) return false; if (entry_already_exists) @@ -329,10 +347,12 @@ bool EmergeManager::enqueueBlockEmergeEx(v3s16 blockpos, session_t peer_id, u16 return true; } + // // Mapgen-related helper functions // + // TODO(hmmmm): Move this to ServerMap v3s16 EmergeManager::getContainingChunk(v3s16 blockpos) { @@ -345,28 +365,28 @@ v3s16 EmergeManager::getContainingChunk(v3s16 blockpos, s16 chunksize) s16 coff = -chunksize / 2; v3s16 chunk_offset(coff, coff, coff); - return getContainerPos(blockpos - chunk_offset, chunksize) * chunksize + - chunk_offset; + return getContainerPos(blockpos - chunk_offset, chunksize) + * chunksize + chunk_offset; } + int EmergeManager::getSpawnLevelAtPoint(v2s16 p) { if (m_mapgens.empty() || !m_mapgens[0]) { errorstream << "EmergeManager: getSpawnLevelAtPoint() called" - " before mapgen init" - << std::endl; + " before mapgen init" << std::endl; return 0; } return m_mapgens[0]->getSpawnLevelAtPoint(p); } + int EmergeManager::getGroundLevelAtPoint(v2s16 p) { if (m_mapgens.empty() || !m_mapgens[0]) { errorstream << "EmergeManager: getGroundLevelAtPoint() called" - " before mapgen init" - << std::endl; + " before mapgen init" << std::endl; return 0; } @@ -387,9 +407,13 @@ bool EmergeManager::isBlockUnderground(v3s16 blockpos) return blockpos.Y * (MAP_BLOCKSIZE + 1) <= mgparams->water_level; } -bool EmergeManager::pushBlockEmergeData(v3s16 pos, u16 peer_requested, u16 flags, - EmergeCompletionCallback callback, void *callback_param, - bool *entry_already_exists) +bool EmergeManager::pushBlockEmergeData( + v3s16 pos, + u16 peer_requested, + u16 flags, + EmergeCompletionCallback callback, + void *callback_param, + bool *entry_already_exists) { u16 &count_peer = m_peer_queue_count[peer_requested]; @@ -398,9 +422,8 @@ bool EmergeManager::pushBlockEmergeData(v3s16 pos, u16 peer_requested, u16 flags return false; if (peer_requested != PEER_ID_INEXISTENT) { - u16 qlimit_peer = (flags & BLOCK_EMERGE_ALLOW_GEN) - ? m_qlimit_generate - : m_qlimit_diskonly; + u16 qlimit_peer = (flags & BLOCK_EMERGE_ALLOW_GEN) ? + m_qlimit_generate : m_qlimit_diskonly; if (count_peer >= qlimit_peer) return false; } @@ -410,7 +433,7 @@ bool EmergeManager::pushBlockEmergeData(v3s16 pos, u16 peer_requested, u16 flags findres = m_blocks_enqueued.insert(std::make_pair(pos, BlockEmergeData())); BlockEmergeData &bedata = findres.first->second; - *entry_already_exists = !findres.second; + *entry_already_exists = !findres.second; if (callback) bedata.callbacks.emplace_back(callback, callback_param); @@ -427,6 +450,7 @@ bool EmergeManager::pushBlockEmergeData(v3s16 pos, u16 peer_requested, u16 flags return true; } + bool EmergeManager::popBlockEmergeData(v3s16 pos, BlockEmergeData *bedata) { std::map<v3s16, BlockEmergeData>::iterator it; @@ -451,6 +475,7 @@ bool EmergeManager::popBlockEmergeData(v3s16 pos, BlockEmergeData *bedata) return true; } + EmergeThread *EmergeManager::getOptimalThread() { size_t nthreads = m_threads.size(); @@ -471,28 +496,36 @@ EmergeThread *EmergeManager::getOptimalThread() return m_threads[index]; } + //// //// EmergeThread //// EmergeThread::EmergeThread(Server *server, int ethreadid) : - enable_mapgen_debug_info(false), id(ethreadid), m_server(server), - m_map(NULL), m_emerge(NULL), m_mapgen(NULL) + enable_mapgen_debug_info(false), + id(ethreadid), + m_server(server), + m_map(NULL), + m_emerge(NULL), + m_mapgen(NULL) { m_name = "Emerge-" + itos(ethreadid); } + void EmergeThread::signal() { m_queue_event.signal(); } + bool EmergeThread::pushBlock(const v3s16 &pos) { m_block_queue.push(pos); return true; } + void EmergeThread::cancelPendingItems() { MutexAutoLock queuelock(m_emerge->m_queue_mutex); @@ -510,20 +543,22 @@ void EmergeThread::cancelPendingItems() } } + void EmergeThread::runCompletionCallbacks(const v3s16 &pos, EmergeAction action, - const EmergeCallbackList &callbacks) + const EmergeCallbackList &callbacks) { for (size_t i = 0; i != callbacks.size(); i++) { EmergeCompletionCallback callback; void *param; callback = callbacks[i].first; - param = callbacks[i].second; + param = callbacks[i].second; callback(pos, action, param); } } + bool EmergeThread::popBlockEmerge(v3s16 *pos, BlockEmergeData *bedata) { MutexAutoLock queuelock(m_emerge->m_queue_mutex); @@ -539,8 +574,9 @@ bool EmergeThread::popBlockEmerge(v3s16 *pos, BlockEmergeData *bedata) return true; } + EmergeAction EmergeThread::getBlockOrStartGen( - const 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); @@ -564,11 +600,13 @@ EmergeAction EmergeThread::getBlockOrStartGen( return EMERGE_CANCELLED; } + MapBlock *EmergeThread::finishGen(v3s16 pos, BlockMakeData *bmdata, - std::map<v3s16, MapBlock *> *modified_blocks) + std::map<v3s16, MapBlock *> *modified_blocks) { MutexAutoLock envlock(m_server->m_env_mutex); - ScopeProfiler sp(g_profiler, "EmergeThread: after Mapgen::makeChunk", SPT_AVG); + ScopeProfiler sp(g_profiler, + "EmergeThread: after Mapgen::makeChunk", SPT_AVG); /* Perform post-processing on blocks (invalidate lighting, queue liquid @@ -579,26 +617,26 @@ MapBlock *EmergeThread::finishGen(v3s16 pos, BlockMakeData *bmdata, MapBlock *block = m_map->getBlockNoCreateNoEx(pos); if (!block) { errorstream << "EmergeThread::finishGen: Couldn't grab block we " - "just generated: " - << PP(pos) << std::endl; + "just generated: " << PP(pos) << std::endl; return NULL; } v3s16 minp = bmdata->blockpos_min * MAP_BLOCKSIZE; v3s16 maxp = bmdata->blockpos_max * MAP_BLOCKSIZE + - v3s16(1, 1, 1) * (MAP_BLOCKSIZE - 1); + v3s16(1,1,1) * (MAP_BLOCKSIZE - 1); // Ignore map edit events, they will not need to be sent // to anybody because the block hasn't been sent to anybody MapEditEventAreaIgnorer ign( - &m_server->m_ignore_map_edit_events_area, VoxelArea(minp, maxp)); + &m_server->m_ignore_map_edit_events_area, + VoxelArea(minp, maxp)); /* Run Lua on_generated callbacks */ try { m_server->getScriptIface()->environment_OnGenerated( - minp, maxp, m_mapgen->blockseed); + minp, maxp, m_mapgen->blockseed); } catch (LuaError &e) { m_server->setAsyncFatalError("Lua: finishGen" + std::string(e.what())); } @@ -618,74 +656,74 @@ MapBlock *EmergeThread::finishGen(v3s16 pos, BlockMakeData *bmdata, return block; } + void *EmergeThread::run() { BEGIN_DEBUG_EXCEPTION_HANDLER v3s16 pos; - m_map = (ServerMap *)&(m_server->m_env->getMap()); + m_map = (ServerMap *)&(m_server->m_env->getMap()); m_emerge = m_server->m_emerge; m_mapgen = m_emerge->m_mapgens[id]; enable_mapgen_debug_info = m_emerge->enable_mapgen_debug_info; try { - while (!stopRequested()) { - std::map<v3s16, MapBlock *> modified_blocks; - BlockEmergeData bedata; - BlockMakeData bmdata; - EmergeAction action; - MapBlock *block; - - if (!popBlockEmerge(&pos, &bedata)) { - m_queue_event.wait(); - continue; - } + while (!stopRequested()) { + std::map<v3s16, MapBlock *> modified_blocks; + BlockEmergeData bedata; + BlockMakeData bmdata; + EmergeAction action; + MapBlock *block; - if (blockpos_over_max_limit(pos)) - continue; + if (!popBlockEmerge(&pos, &bedata)) { + m_queue_event.wait(); + continue; + } - bool allow_gen = bedata.flags & BLOCK_EMERGE_ALLOW_GEN; - EMERGE_DBG_OUT("pos=" PP(pos) " allow_gen=" << allow_gen); + if (blockpos_over_max_limit(pos)) + continue; - action = getBlockOrStartGen(pos, allow_gen, &block, &bmdata); - if (action == EMERGE_GENERATED) { - { - ScopeProfiler sp(g_profiler, - "EmergeThread: Mapgen::makeChunk", - SPT_AVG); + bool allow_gen = bedata.flags & BLOCK_EMERGE_ALLOW_GEN; + EMERGE_DBG_OUT("pos=" PP(pos) " allow_gen=" << allow_gen); - m_mapgen->makeChunk(&bmdata); - } + action = getBlockOrStartGen(pos, allow_gen, &block, &bmdata); + if (action == EMERGE_GENERATED) { + { + ScopeProfiler sp(g_profiler, + "EmergeThread: Mapgen::makeChunk", SPT_AVG); - block = finishGen(pos, &bmdata, &modified_blocks); + m_mapgen->makeChunk(&bmdata); } - runCompletionCallbacks(pos, action, bedata.callbacks); + block = finishGen(pos, &bmdata, &modified_blocks); + } - if (block) - modified_blocks[pos] = block; + runCompletionCallbacks(pos, action, bedata.callbacks); - if (!modified_blocks.empty()) - m_server->SetBlocksNotSent(modified_blocks); - } + if (block) + modified_blocks[pos] = block; + + if (!modified_blocks.empty()) + m_server->SetBlocksNotSent(modified_blocks); + } } catch (VersionMismatchException &e) { std::ostringstream err; err << "World data version mismatch in MapBlock " << PP(pos) << std::endl - << "----" << std::endl - << "\"" << e.what() << "\"" << std::endl - << "See debug.txt." << std::endl - << "World probably saved by a newer version of " PROJECT_NAME_C "." - << std::endl; + << "----" << std::endl + << "\"" << e.what() << "\"" << std::endl + << "See debug.txt." << std::endl + << "World probably saved by a newer version of " PROJECT_NAME_C "." + << std::endl; m_server->setAsyncFatalError(err.str()); } catch (SerializationError &e) { std::ostringstream err; err << "Invalid data in MapBlock " << PP(pos) << std::endl - << "----" << std::endl - << "\"" << e.what() << "\"" << std::endl - << "See debug.txt." << std::endl - << "You can ignore this using [ignore_world_load_errors = true]." - << std::endl; + << "----" << std::endl + << "\"" << e.what() << "\"" << std::endl + << "See debug.txt." << std::endl + << "You can ignore this using [ignore_world_load_errors = true]." + << std::endl; m_server->setAsyncFatalError(err.str()); } |