From b2ccbdffc1d85e320ef55c8994fae022dcef96f8 Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Sat, 26 Nov 2011 15:53:52 +0200 Subject: [PATCH] Make map generator as much threaded as possible (not much benefit with current generator because of small generator chunk size (a single MapBlock)) --- data/mods/default/init.lua | 2 +- src/map.cpp | 12 ++- src/server.cpp | 179 ++++++++++++++++--------------------- 3 files changed, 88 insertions(+), 105 deletions(-) diff --git a/data/mods/default/init.lua b/data/mods/default/init.lua index 6ea15b4ee..520fbddf1 100644 --- a/data/mods/default/init.lua +++ b/data/mods/default/init.lua @@ -1331,7 +1331,7 @@ minetest.register_on_respawnplayer(function(player) end) minetest.register_on_generated(function(minp, maxp) - --print("on_generated: minp="..dump(minp).." maxp="..dump(maxp)) + print("on_generated: minp="..dump(minp).." maxp="..dump(maxp)) --cp = {x=(minp.x+maxp.x)/2, y=(minp.y+maxp.y)/2, z=(minp.z+maxp.z)/2} --minetest.env:add_node(cp, {name="sand"}) end) diff --git a/src/map.cpp b/src/map.cpp index fd0f1e313..ab394769b 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -2162,7 +2162,17 @@ MapBlock* ServerMap::finishBlockMake(mapgen::BlockMakeData *data, /*infostream<<"Resulting vmanip:"<vmanip.print(infostream);*/ - + + // Make sure affected blocks are loaded + for(s16 x=-1; x<=1; x++) + for(s16 z=-1; z<=1; z++) + for(s16 y=-1; y<=1; y++) + { + v3s16 p(blockpos.X+x, blockpos.Y+y, blockpos.Z+z); + // Load from disk if not already in memory + emergeBlock(p, false); + } + /* Blit generated stuff to map NOTE: blitBackAll adds nearly everything to changed_blocks diff --git a/src/server.cpp b/src/server.cpp index 49fdabd67..7581f7a2b 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -44,6 +44,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "nodedef.h" #include "tooldef.h" #include "craftdef.h" +#include "mapgen.h" #define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")" @@ -143,12 +144,7 @@ void * EmergeThread::Thread() /* Do not generate over-limit */ - if(p.X < -MAP_GENERATION_LIMIT / MAP_BLOCKSIZE - || p.X > MAP_GENERATION_LIMIT / MAP_BLOCKSIZE - || p.Y < -MAP_GENERATION_LIMIT / MAP_BLOCKSIZE - || p.Y > MAP_GENERATION_LIMIT / MAP_BLOCKSIZE - || p.Z < -MAP_GENERATION_LIMIT / MAP_BLOCKSIZE - || p.Z > MAP_GENERATION_LIMIT / MAP_BLOCKSIZE) + if(blockpos_over_limit(p)) continue; //infostream<<"EmergeThread::Thread(): running"<m_env->getMap()); - //core::map changed_blocks; - //core::map lighting_invalidated_blocks; - MapBlock *block = NULL; bool got_block = true; core::map modified_blocks; - + /* - Fetch block from map or generate a single block + Try to fetch block from memory or disk. + If not found and asked to generate, initialize generator. */ + + bool started_generate = false; + mapgen::BlockMakeData data; + { JMutexAutoLock envlock(m_server->m_env_mutex); // Load sector if it isn't loaded if(map.getSectorNoGenerateNoEx(p2d) == NULL) - //map.loadSectorFull(p2d); map.loadSectorMeta(p2d); - + + // Attempt to load block block = map.getBlockNoCreateNoEx(p); if(!block || block->isDummy() || !block->isGenerated()) { if(enable_mapgen_debug_info) - infostream<<"EmergeThread: not in memory, loading"<isGenerated() == false) - { - if(enable_mapgen_debug_info) - infostream<<"EmergeThread: generating"<getPos()*MAP_BLOCKSIZE; - v3s16 maxp = minp + v3s16(1,1,1)*(MAP_BLOCKSIZE-1); - scriptapi_environment_on_generated(m_server->m_lua, - minp, maxp); - } - } + } + + // If could not load and allowed to generate, start generation + // inside this same envlock + if(only_from_disk == false && + (block == NULL || block->isGenerated() == false)){ + if(enable_mapgen_debug_info) + infostream<<"EmergeThread: generating"<m_env_mutex); + + ScopeProfiler sp(g_profiler, "EmergeThread: after " + "mapgen::make_block (envlock)", SPT_AVG); + + // Blit data back on map, update lighting, add mobs and + // whatever this does + map.finishBlockMake(&data, modified_blocks); + + // Get central block + block = map.getBlockNoCreateNoEx(p); + + /* + Do some post-generate stuff + */ + + v3s16 minp = block->getPos()*MAP_BLOCKSIZE; + v3s16 maxp = minp + v3s16(1,1,1)*(MAP_BLOCKSIZE-1); + scriptapi_environment_on_generated(m_server->m_lua, + minp, maxp); + if(enable_mapgen_debug_info) infostream<<"EmergeThread: ended up with: " <m_ignore_map_edit_events); - - // Activate objects and stuff - m_server->m_env->activateBlock(block, 3600); - } + /* + Ignore map edit events, they will not need to be + sent to anybody because the block hasn't been sent + to anybody + */ + MapEditEventIgnorer ign(&m_server->m_ignore_map_edit_events); + + // Activate objects and stuff + m_server->m_env->activateBlock(block, 3600); } - else - { - /*if(block->getLightingExpired()){ - lighting_invalidated_blocks[block->getPos()] = block; - }*/ - } - - // TODO: Some additional checking and lighting updating, - // see emergeBlock } - {//envlock - JMutexAutoLock envlock(m_server->m_env_mutex); - - if(got_block) - { - /* - Collect a list of blocks that have been modified in - addition to the fetched one. - */ - -#if 0 - if(lighting_invalidated_blocks.size() > 0) - { - /*infostream<<"lighting "<::Iterator i = changed_blocks.getIterator(); - i.atEnd() == false; i++) - { - MapBlock *block = i.getNode()->getValue(); - modified_blocks.insert(block->getPos(), block); - } -#endif - } - // If we got no block, there should be no invalidated blocks - else - { - //assert(lighting_invalidated_blocks.size() == 0); - } - - }//envlock - /* Set sent status of modified blocks on clients */