changed server to do object management at longer intervals (0.5s)
authorPerttu Ahola <celeron55@gmail.com>
Sun, 10 Apr 2011 20:14:41 +0000 (23:14 +0300)
committerPerttu Ahola <celeron55@gmail.com>
Sun, 10 Apr 2011 20:14:41 +0000 (23:14 +0300)
src/environment.cpp
src/environment.h

index efcdbbd156c6287469d6f18d5ea997cee8db5e43..bed47fd40d61642b84df273e4e62acabcee59f86 100644 (file)
@@ -449,227 +449,231 @@ void ServerEnvironment::step(float dtime)
                obj->step(dtime, m_active_object_messages, send_recommended);
        }
 
-       /*
-               Remove objects that satisfy (m_removed && m_known_by_count==0)
-       */
+       if(m_object_management_interval.step(dtime, 0.5))
        {
-               core::list<u16> objects_to_remove;
-               for(core::map<u16, ServerActiveObject*>::Iterator
-                               i = m_active_objects.getIterator();
-                               i.atEnd()==false; i++)
+               /*
+                       Remove objects that satisfy (m_removed && m_known_by_count==0)
+               */
                {
-                       u16 id = i.getNode()->getKey();
-                       ServerActiveObject* obj = i.getNode()->getValue();
-                       // This shouldn't happen but check it
-                       if(obj == NULL)
+                       core::list<u16> objects_to_remove;
+                       for(core::map<u16, ServerActiveObject*>::Iterator
+                                       i = m_active_objects.getIterator();
+                                       i.atEnd()==false; i++)
                        {
-                               dstream<<"WARNING: NULL object found in ServerEnvironment"
-                                               <<" while finding removed objects. id="<<id<<std::endl;
+                               u16 id = i.getNode()->getKey();
+                               ServerActiveObject* obj = i.getNode()->getValue();
+                               // This shouldn't happen but check it
+                               if(obj == NULL)
+                               {
+                                       dstream<<"WARNING: NULL object found in ServerEnvironment"
+                                                       <<" while finding removed objects. id="<<id<<std::endl;
+                                       // Id to be removed from m_active_objects
+                                       objects_to_remove.push_back(id);
+                                       continue;
+                               }
+                               // If not m_removed, don't remove.
+                               if(obj->m_removed == false)
+                                       continue;
+                               // Delete static data from block
+                               if(obj->m_static_exists)
+                               {
+                                       MapBlock *block = m_map->getBlockNoCreateNoEx(obj->m_static_block);
+                                       if(block)
+                                       {
+                                               block->m_static_objects.remove(id);
+                                               block->setChangedFlag();
+                                       }
+                               }
+                               // If m_known_by_count > 0, don't actually remove.
+                               if(obj->m_known_by_count > 0)
+                                       continue;
+                               // Delete
+                               delete obj;
                                // Id to be removed from m_active_objects
                                objects_to_remove.push_back(id);
-                               continue;
                        }
-                       // If not m_removed, don't remove.
-                       if(obj->m_removed == false)
-                               continue;
-                       // Delete static data from block
-                       if(obj->m_static_exists)
+                       // Remove references from m_active_objects
+                       for(core::list<u16>::Iterator i = objects_to_remove.begin();
+                                       i != objects_to_remove.end(); i++)
                        {
-                               MapBlock *block = m_map->getBlockNoCreateNoEx(obj->m_static_block);
-                               if(block)
-                               {
-                                       block->m_static_objects.remove(id);
-                                       block->setChangedFlag();
-                               }
+                               m_active_objects.remove(*i);
                        }
-                       // If m_known_by_count > 0, don't actually remove.
-                       if(obj->m_known_by_count > 0)
-                               continue;
-                       // Delete
-                       delete obj;
-                       // Id to be removed from m_active_objects
-                       objects_to_remove.push_back(id);
-               }
-               // Remove references from m_active_objects
-               for(core::list<u16>::Iterator i = objects_to_remove.begin();
-                               i != objects_to_remove.end(); i++)
-               {
-                       m_active_objects.remove(*i);
                }
-       }
-       
-
-       const s16 to_active_max_blocks = 3;
-       const f32 to_static_max_f = (to_active_max_blocks+1)*MAP_BLOCKSIZE*BS;
-
-       /*
-               Convert stored objects from blocks near the players to active.
-       */
-       for(core::list<Player*>::Iterator i = m_players.begin();
-                       i != m_players.end(); i++)
-       {
-               Player *player = *i;
                
-               // Ignore disconnected players
-               if(player->peer_id == 0)
-                       continue;
 
-               v3f playerpos = player->getPosition();
-               
-               v3s16 blockpos0 = getNodeBlockPos(floatToInt(playerpos, BS));
-               v3s16 bpmin = blockpos0 - v3s16(1,1,1)*to_active_max_blocks;
-               v3s16 bpmax = blockpos0 + v3s16(1,1,1)*to_active_max_blocks;
-               // Loop through all nearby blocks
-               for(s16 x=bpmin.X; x<=bpmax.X; x++)
-               for(s16 y=bpmin.Y; y<=bpmax.Y; y++)
-               for(s16 z=bpmin.Z; z<=bpmax.Z; z++)
+               const s16 to_active_max_blocks = 3;
+               const f32 to_static_max_f = (to_active_max_blocks+1)*MAP_BLOCKSIZE*BS;
+
+               /*
+                       Convert stored objects from blocks near the players to active.
+               */
+               for(core::list<Player*>::Iterator i = m_players.begin();
+                               i != m_players.end(); i++)
                {
-                       v3s16 blockpos(x,y,z);
-                       MapBlock *block = m_map->getBlockNoCreateNoEx(blockpos);
-                       if(block==NULL)
-                               continue;
-                       // Ignore if no stored objects (to not set changed flag)
-                       if(block->m_static_objects.m_stored.size() == 0)
+                       Player *player = *i;
+                       
+                       // Ignore disconnected players
+                       if(player->peer_id == 0)
                                continue;
-                       // This will contain the leftovers of the stored list
-                       core::list<StaticObject> new_stored;
-                       // Loop through stored static objects
-                       for(core::list<StaticObject>::Iterator
-                                       i = block->m_static_objects.m_stored.begin();
-                                       i != block->m_static_objects.m_stored.end(); i++)
+
+                       v3f playerpos = player->getPosition();
+                       
+                       v3s16 blockpos0 = getNodeBlockPos(floatToInt(playerpos, BS));
+                       v3s16 bpmin = blockpos0 - v3s16(1,1,1)*to_active_max_blocks;
+                       v3s16 bpmax = blockpos0 + v3s16(1,1,1)*to_active_max_blocks;
+                       // Loop through all nearby blocks
+                       for(s16 x=bpmin.X; x<=bpmax.X; x++)
+                       for(s16 y=bpmin.Y; y<=bpmax.Y; y++)
+                       for(s16 z=bpmin.Z; z<=bpmax.Z; z++)
                        {
-                               /*dstream<<"INFO: Server: Creating an active object from "
-                                               <<"static data"<<std::endl;*/
-                               StaticObject &s_obj = *i;
-                               // Create an active object from the data
-                               ServerActiveObject *obj = ServerActiveObject::create
-                                               (s_obj.type, this, 0, s_obj.pos, s_obj.data);
-                               if(obj==NULL)
-                               {
-                                       // This is necessary to preserve stuff during bugs
-                                       // and errors
-                                       new_stored.push_back(s_obj);
+                               v3s16 blockpos(x,y,z);
+                               MapBlock *block = m_map->getBlockNoCreateNoEx(blockpos);
+                               if(block==NULL)
                                        continue;
+                               // Ignore if no stored objects (to not set changed flag)
+                               if(block->m_static_objects.m_stored.size() == 0)
+                                       continue;
+                               // This will contain the leftovers of the stored list
+                               core::list<StaticObject> new_stored;
+                               // Loop through stored static objects
+                               for(core::list<StaticObject>::Iterator
+                                               i = block->m_static_objects.m_stored.begin();
+                                               i != block->m_static_objects.m_stored.end(); i++)
+                               {
+                                       /*dstream<<"INFO: Server: Creating an active object from "
+                                                       <<"static data"<<std::endl;*/
+                                       StaticObject &s_obj = *i;
+                                       // Create an active object from the data
+                                       ServerActiveObject *obj = ServerActiveObject::create
+                                                       (s_obj.type, this, 0, s_obj.pos, s_obj.data);
+                                       if(obj==NULL)
+                                       {
+                                               // This is necessary to preserve stuff during bugs
+                                               // and errors
+                                               new_stored.push_back(s_obj);
+                                               continue;
+                                       }
+                                       // This will also add the object to the active static list
+                                       addActiveObject(obj);
+                                       //u16 id = addActiveObject(obj);
                                }
-                               // This will also add the object to the active static list
-                               addActiveObject(obj);
-                               //u16 id = addActiveObject(obj);
-                       }
-                       // Clear stored list
-                       block->m_static_objects.m_stored.clear();
-                       // Add leftover stuff to stored list
-                       for(core::list<StaticObject>::Iterator
-                                       i = new_stored.begin();
-                                       i != new_stored.end(); i++)
-                       {
-                               StaticObject &s_obj = *i;
-                               block->m_static_objects.m_stored.push_back(s_obj);
+                               // Clear stored list
+                               block->m_static_objects.m_stored.clear();
+                               // Add leftover stuff to stored list
+                               for(core::list<StaticObject>::Iterator
+                                               i = new_stored.begin();
+                                               i != new_stored.end(); i++)
+                               {
+                                       StaticObject &s_obj = *i;
+                                       block->m_static_objects.m_stored.push_back(s_obj);
+                               }
+                               block->setChangedFlag();
                        }
-                       block->setChangedFlag();
                }
-       }
 
-       /*
-               Convert objects that are far away from all the players to static.
-       */
-       {
-               core::list<u16> objects_to_remove;
-               for(core::map<u16, ServerActiveObject*>::Iterator
-                               i = m_active_objects.getIterator();
-                               i.atEnd()==false; i++)
+               /*
+                       Convert objects that are far away from all the players to static.
+               */
                {
-                       ServerActiveObject* obj = i.getNode()->getValue();
-                       u16 id = i.getNode()->getKey();
-                       v3f objectpos = obj->getBasePosition();
-
-                       // This shouldn't happen but check it
-                       if(obj == NULL)
+                       core::list<u16> objects_to_remove;
+                       for(core::map<u16, ServerActiveObject*>::Iterator
+                                       i = m_active_objects.getIterator();
+                                       i.atEnd()==false; i++)
                        {
-                               dstream<<"WARNING: NULL object found in ServerEnvironment"
-                                               <<std::endl;
-                               continue;
-                       }
-                       // If known by some client, don't convert to static.
-                       if(obj->m_known_by_count > 0)
-                               continue;
+                               ServerActiveObject* obj = i.getNode()->getValue();
+                               u16 id = i.getNode()->getKey();
+                               v3f objectpos = obj->getBasePosition();
 
-                       // If close to some player, don't convert to static.
-                       bool close_to_player = false;
-                       for(core::list<Player*>::Iterator i = m_players.begin();
-                                       i != m_players.end(); i++)
-                       {
-                               Player *player = *i;
-                               
-                               // Ignore disconnected players
-                               if(player->peer_id == 0)
+                               // This shouldn't happen but check it
+                               if(obj == NULL)
+                               {
+                                       dstream<<"WARNING: NULL object found in ServerEnvironment"
+                                                       <<std::endl;
+                                       continue;
+                               }
+                               // If known by some client, don't convert to static.
+                               if(obj->m_known_by_count > 0)
                                        continue;
 
-                               v3f playerpos = player->getPosition();
-                               f32 d = playerpos.getDistanceFrom(objectpos);
-                               if(d < to_static_max_f)
+                               // If close to some player, don't convert to static.
+                               bool close_to_player = false;
+                               for(core::list<Player*>::Iterator i = m_players.begin();
+                                               i != m_players.end(); i++)
                                {
-                                       close_to_player = true;
-                                       break;
+                                       Player *player = *i;
+                                       
+                                       // Ignore disconnected players
+                                       if(player->peer_id == 0)
+                                               continue;
+
+                                       v3f playerpos = player->getPosition();
+                                       f32 d = playerpos.getDistanceFrom(objectpos);
+                                       if(d < to_static_max_f)
+                                       {
+                                               close_to_player = true;
+                                               break;
+                                       }
                                }
-                       }
 
-                       if(close_to_player)
-                               continue;
+                               if(close_to_player)
+                                       continue;
 
-                       /*
-                               Update the static data and remove the active object.
-                       */
+                               /*
+                                       Update the static data and remove the active object.
+                               */
 
-                       // Delete old static object
-                       MapBlock *oldblock = NULL;
-                       if(obj->m_static_exists)
-                       {
-                               MapBlock *block = m_map->getBlockNoCreateNoEx(obj->m_static_block);
+                               // Delete old static object
+                               MapBlock *oldblock = NULL;
+                               if(obj->m_static_exists)
+                               {
+                                       MapBlock *block = m_map->getBlockNoCreateNoEx
+                                                       (obj->m_static_block);
+                                       if(block)
+                                       {
+                                               block->m_static_objects.remove(id);
+                                               oldblock = block;
+                                       }
+                               }
+                               // Add new static object
+                               std::string staticdata = obj->getStaticData();
+                               StaticObject s_obj(obj->getType(), objectpos, staticdata);
+                               // Add to the block where the object is located in
+                               v3s16 blockpos = getNodeBlockPos(floatToInt(objectpos, BS));
+                               MapBlock *block = m_map->getBlockNoCreateNoEx(blockpos);
                                if(block)
                                {
-                                       block->m_static_objects.remove(id);
-                                       oldblock = block;
+                                       block->m_static_objects.insert(0, s_obj);
+                                       block->setChangedFlag();
+                                       obj->m_static_exists = true;
+                                       obj->m_static_block = block->getPos();
                                }
+                               // If not possible, add back to previous block
+                               else if(oldblock)
+                               {
+                                       oldblock->m_static_objects.insert(0, s_obj);
+                                       oldblock->setChangedFlag();
+                                       obj->m_static_exists = true;
+                                       obj->m_static_block = oldblock->getPos();
+                               }
+                               else{
+                                       dstream<<"WARNING: Server: Could not find a block for "
+                                                       <<"storing static object"<<std::endl;
+                                       obj->m_static_exists = false;
+                                       continue;
+                               }
+                               /*dstream<<"INFO: Server: Stored static data. Deleting object."
+                                               <<std::endl;*/
+                               // Delete active object
+                               delete obj;
+                               // Id to be removed from m_active_objects
+                               objects_to_remove.push_back(id);
                        }
-                       // Add new static object
-                       std::string staticdata = obj->getStaticData();
-                       StaticObject s_obj(obj->getType(), objectpos, staticdata);
-                       // Add to the block where the object is located in
-                       v3s16 blockpos = getNodeBlockPos(floatToInt(objectpos, BS));
-                       MapBlock *block = m_map->getBlockNoCreateNoEx(blockpos);
-                       if(block)
-                       {
-                               block->m_static_objects.insert(0, s_obj);
-                               block->setChangedFlag();
-                               obj->m_static_exists = true;
-                               obj->m_static_block = block->getPos();
-                       }
-                       // If not possible, add back to previous block
-                       else if(oldblock)
+                       // Remove references from m_active_objects
+                       for(core::list<u16>::Iterator i = objects_to_remove.begin();
+                                       i != objects_to_remove.end(); i++)
                        {
-                               oldblock->m_static_objects.insert(0, s_obj);
-                               oldblock->setChangedFlag();
-                               obj->m_static_exists = true;
-                               obj->m_static_block = oldblock->getPos();
-                       }
-                       else{
-                               dstream<<"WARNING: Server: Could not find a block for "
-                                               <<"storing static object"<<std::endl;
-                               obj->m_static_exists = false;
-                               continue;
+                               m_active_objects.remove(*i);
                        }
-                       /*dstream<<"INFO: Server: Stored static data. Deleting object."
-                                       <<std::endl;*/
-                       // Delete active object
-                       delete obj;
-                       // Id to be removed from m_active_objects
-                       objects_to_remove.push_back(id);
-               }
-               // Remove references from m_active_objects
-               for(core::list<u16>::Iterator i = objects_to_remove.begin();
-                               i != objects_to_remove.end(); i++)
-               {
-                       m_active_objects.remove(*i);
                }
        }
 
index 85d2f668f444fc2aa197dbc250aed9c029592c28..e82cea6ae275ab9fe2330b543397b8bfa4431a60 100644 (file)
@@ -35,6 +35,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "player.h"
 #include "map.h"
 #include <ostream>
+#include "utility.h"
 
 class Environment
 {
@@ -154,6 +155,7 @@ private:
        Queue<ActiveObjectMessage> m_active_object_messages;
        float m_random_spawn_timer;
        float m_send_recommended_timer;
+       IntervalLimiter m_object_management_interval;
 };
 
 #ifndef SERVER