Area-based MapEditEvent ignore and that put to use for on_generate too

This commit is contained in:
Perttu Ahola 2012-03-29 01:22:08 +03:00
parent 02c035c548
commit a6ca7eb29d
3 changed files with 82 additions and 8 deletions

@ -98,6 +98,38 @@ struct MapEditEvent
}
return event;
}
VoxelArea getArea()
{
switch(type){
case MEET_ADDNODE:
return VoxelArea(p);
case MEET_REMOVENODE:
return VoxelArea(p);
case MEET_BLOCK_NODE_METADATA_CHANGED:
{
v3s16 np1 = p*MAP_BLOCKSIZE;
v3s16 np2 = np1 + v3s16(1,1,1)*MAP_BLOCKSIZE - v3s16(1,1,1);
return VoxelArea(np1, np2);
}
case MEET_OTHER:
{
VoxelArea a;
for(core::map<v3s16, bool>::Iterator
i = modified_blocks.getIterator();
i.atEnd()==false; i++)
{
v3s16 p = i.getNode()->getKey();
v3s16 np1 = p*MAP_BLOCKSIZE;
v3s16 np2 = np1 + v3s16(1,1,1)*MAP_BLOCKSIZE - v3s16(1,1,1);
a.addPoint(np1);
a.addPoint(np2);
}
return a;
}
}
return VoxelArea();
}
};
class MapEventReceiver

@ -82,6 +82,31 @@ private:
bool *m_flag;
};
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;
};
void * ServerThread::Thread()
{
ThreadStarted();
@ -279,24 +304,32 @@ void * EmergeThread::Thread()
/*
Do some post-generate stuff
*/
v3s16 minp = data.blockpos_min*MAP_BLOCKSIZE;
v3s16 maxp = data.blockpos_max*MAP_BLOCKSIZE +
v3s16(1,1,1)*(MAP_BLOCKSIZE-1);
scriptapi_environment_on_generated(m_server->m_lua,
minp, maxp, mapgen::get_blockseed(data.seed, minp));
if(enable_mapgen_debug_info)
infostream<<"EmergeThread: ended up with: "
<<analyze_block(block)<<std::endl;
/*
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);
//MapEditEventIgnorer ign(&m_server->m_ignore_map_edit_events);
MapEditEventAreaIgnorer ign(
&m_server->m_ignore_map_edit_events_area,
VoxelArea(minp, maxp));
{
TimeTaker timer("on_generated");
scriptapi_environment_on_generated(m_server->m_lua,
minp, maxp, mapgen::get_blockseed(data.seed, minp));
int t = timer.stop(true);
dstream<<"on_generated took "<<t<<"ms"<<std::endl;
}
if(enable_mapgen_debug_info)
infostream<<"EmergeThread: ended up with: "
<<analyze_block(block)<<std::endl;
// Activate objects and stuff
m_server->m_env->activateBlock(block, 0);
}while(false);
@ -3169,6 +3202,8 @@ void Server::onMapEditEvent(MapEditEvent *event)
//infostream<<"Server::onMapEditEvent()"<<std::endl;
if(m_ignore_map_edit_events)
return;
if(m_ignore_map_edit_events_area.contains(event->getArea()))
return;
MapEditEvent *e = event->clone();
m_unsent_map_edit_queue.push_back(e);
}

@ -823,6 +823,13 @@ private:
This is behind m_env_mutex
*/
bool m_ignore_map_edit_events;
/*
If a non-empty area, map edit events contained within are left
unsent. Done at map generation time to speed up editing of the
generated area, as it will be sent anyway.
This is behind m_env_mutex
*/
VoxelArea m_ignore_map_edit_events_area;
/*
If set to !=0, the incoming MapEditEvents are modified to have
this peed id as the disabled recipient