forked from Mirrorlandia_minetest/minetest
Make map generator as much threaded as possible (not much benefit with current generator because of small generator chunk size (a single MapBlock))
This commit is contained in:
parent
769cc9879f
commit
b2ccbdffc1
@ -1331,7 +1331,7 @@ minetest.register_on_respawnplayer(function(player)
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
minetest.register_on_generated(function(minp, maxp)
|
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}
|
--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"})
|
--minetest.env:add_node(cp, {name="sand"})
|
||||||
end)
|
end)
|
||||||
|
10
src/map.cpp
10
src/map.cpp
@ -2163,6 +2163,16 @@ MapBlock* ServerMap::finishBlockMake(mapgen::BlockMakeData *data,
|
|||||||
/*infostream<<"Resulting vmanip:"<<std::endl;
|
/*infostream<<"Resulting vmanip:"<<std::endl;
|
||||||
data->vmanip.print(infostream);*/
|
data->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
|
Blit generated stuff to map
|
||||||
NOTE: blitBackAll adds nearly everything to changed_blocks
|
NOTE: blitBackAll adds nearly everything to changed_blocks
|
||||||
|
169
src/server.cpp
169
src/server.cpp
@ -44,6 +44,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "nodedef.h"
|
#include "nodedef.h"
|
||||||
#include "tooldef.h"
|
#include "tooldef.h"
|
||||||
#include "craftdef.h"
|
#include "craftdef.h"
|
||||||
|
#include "mapgen.h"
|
||||||
|
|
||||||
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
|
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
|
||||||
|
|
||||||
@ -143,12 +144,7 @@ void * EmergeThread::Thread()
|
|||||||
/*
|
/*
|
||||||
Do not generate over-limit
|
Do not generate over-limit
|
||||||
*/
|
*/
|
||||||
if(p.X < -MAP_GENERATION_LIMIT / MAP_BLOCKSIZE
|
if(blockpos_over_limit(p))
|
||||||
|| 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)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
//infostream<<"EmergeThread::Thread(): running"<<std::endl;
|
//infostream<<"EmergeThread::Thread(): running"<<std::endl;
|
||||||
@ -192,128 +188,105 @@ void * EmergeThread::Thread()
|
|||||||
|
|
||||||
ServerMap &map = ((ServerMap&)m_server->m_env->getMap());
|
ServerMap &map = ((ServerMap&)m_server->m_env->getMap());
|
||||||
|
|
||||||
//core::map<v3s16, MapBlock*> changed_blocks;
|
|
||||||
//core::map<v3s16, MapBlock*> lighting_invalidated_blocks;
|
|
||||||
|
|
||||||
MapBlock *block = NULL;
|
MapBlock *block = NULL;
|
||||||
bool got_block = true;
|
bool got_block = true;
|
||||||
core::map<v3s16, MapBlock*> modified_blocks;
|
core::map<v3s16, MapBlock*> 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);
|
JMutexAutoLock envlock(m_server->m_env_mutex);
|
||||||
|
|
||||||
// Load sector if it isn't loaded
|
// Load sector if it isn't loaded
|
||||||
if(map.getSectorNoGenerateNoEx(p2d) == NULL)
|
if(map.getSectorNoGenerateNoEx(p2d) == NULL)
|
||||||
//map.loadSectorFull(p2d);
|
|
||||||
map.loadSectorMeta(p2d);
|
map.loadSectorMeta(p2d);
|
||||||
|
|
||||||
|
// Attempt to load block
|
||||||
block = map.getBlockNoCreateNoEx(p);
|
block = map.getBlockNoCreateNoEx(p);
|
||||||
if(!block || block->isDummy() || !block->isGenerated())
|
if(!block || block->isDummy() || !block->isGenerated())
|
||||||
{
|
{
|
||||||
if(enable_mapgen_debug_info)
|
if(enable_mapgen_debug_info)
|
||||||
infostream<<"EmergeThread: not in memory, loading"<<std::endl;
|
infostream<<"EmergeThread: not in memory, "
|
||||||
|
<<"attempting to load from disk"<<std::endl;
|
||||||
// Get, load or create sector
|
|
||||||
/*ServerMapSector *sector =
|
|
||||||
(ServerMapSector*)map.createSector(p2d);*/
|
|
||||||
|
|
||||||
// Load/generate block
|
|
||||||
|
|
||||||
/*block = map.emergeBlock(p, sector, changed_blocks,
|
|
||||||
lighting_invalidated_blocks);*/
|
|
||||||
|
|
||||||
block = map.loadBlock(p);
|
block = map.loadBlock(p);
|
||||||
|
}
|
||||||
|
|
||||||
if(only_from_disk == false)
|
// If could not load and allowed to generate, start generation
|
||||||
{
|
// inside this same envlock
|
||||||
if(block == NULL || block->isGenerated() == false)
|
if(only_from_disk == false &&
|
||||||
{
|
(block == NULL || block->isGenerated() == false)){
|
||||||
if(enable_mapgen_debug_info)
|
if(enable_mapgen_debug_info)
|
||||||
infostream<<"EmergeThread: generating"<<std::endl;
|
infostream<<"EmergeThread: generating"<<std::endl;
|
||||||
block = map.generateBlock(p, modified_blocks);
|
started_generate = true;
|
||||||
|
|
||||||
v3s16 minp = block->getPos()*MAP_BLOCKSIZE;
|
map.initBlockMake(&data, p);
|
||||||
v3s16 maxp = minp + v3s16(1,1,1)*(MAP_BLOCKSIZE-1);
|
}
|
||||||
scriptapi_environment_on_generated(m_server->m_lua,
|
}
|
||||||
minp, maxp);
|
|
||||||
}
|
/*
|
||||||
}
|
If generator was initialized, generate now when envlock is free.
|
||||||
|
*/
|
||||||
|
if(started_generate)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
ScopeProfiler sp(g_profiler, "EmergeThread: mapgen::make_block",
|
||||||
|
SPT_AVG);
|
||||||
|
TimeTaker t("mapgen::make_block()");
|
||||||
|
|
||||||
|
mapgen::make_block(&data);
|
||||||
|
|
||||||
|
if(enable_mapgen_debug_info == false)
|
||||||
|
t.stop(true); // Hide output
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Lock environment again to access the map
|
||||||
|
JMutexAutoLock envlock(m_server->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)
|
if(enable_mapgen_debug_info)
|
||||||
infostream<<"EmergeThread: ended up with: "
|
infostream<<"EmergeThread: ended up with: "
|
||||||
<<analyze_block(block)<<std::endl;
|
<<analyze_block(block)<<std::endl;
|
||||||
|
|
||||||
if(block == NULL)
|
/*
|
||||||
{
|
Ignore map edit events, they will not need to be
|
||||||
got_block = false;
|
sent to anybody because the block hasn't been sent
|
||||||
}
|
to anybody
|
||||||
else
|
*/
|
||||||
{
|
MapEditEventIgnorer ign(&m_server->m_ignore_map_edit_events);
|
||||||
/*
|
|
||||||
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
|
// Activate objects and stuff
|
||||||
m_server->m_env->activateBlock(block, 3600);
|
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
|
if(block == NULL)
|
||||||
JMutexAutoLock envlock(m_server->m_env_mutex);
|
got_block = false;
|
||||||
|
|
||||||
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 "<<lighting_invalidated_blocks.size()
|
|
||||||
<<" blocks"<<std::endl;*/
|
|
||||||
|
|
||||||
// 50-100ms for single block generation
|
|
||||||
//TimeTaker timer("** EmergeThread updateLighting");
|
|
||||||
|
|
||||||
// Update lighting without locking the environment mutex,
|
|
||||||
// add modified blocks to changed blocks
|
|
||||||
map.updateLighting(lighting_invalidated_blocks, modified_blocks);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add all from changed_blocks to modified_blocks
|
|
||||||
for(core::map<v3s16, MapBlock*>::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
|
Set sent status of modified blocks on clients
|
||||||
|
Loading…
Reference in New Issue
Block a user