Area-based MapEditEvent ignore and that put to use for on_generate too
authorPerttu Ahola <celeron55@gmail.com>
Wed, 28 Mar 2012 22:22:08 +0000 (01:22 +0300)
committerPerttu Ahola <celeron55@gmail.com>
Wed, 28 Mar 2012 22:22:08 +0000 (01:22 +0300)
src/map.h
src/server.cpp
src/server.h

index b84e123e4d8fc478da7c40e20083c069de3e843b..0940b8413fd66c04f56d76dec234eec1eb87b42d 100644 (file)
--- a/src/map.h
+++ b/src/map.h
@@ -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
index 3aa0bd04bf33acc5f6ab7af91c9cf19bad9f9e77..a8267b1f103752efc1eee817e290e30cd3f4998f 100644 (file)
@@ -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);
 }
index b827c5e27d0abbe81ec73dbd4c9cc3c563c8ad46..1b0cff7831725835944254705d3d47cedb4ed911 100644 (file)
@@ -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