All pastes #612718 Raw Edit

Anonymous

public text v1 · immutable
·published 2007-07-10 16:00 UTC
rendered paste body
Index: game/GridStates.cpp
===================================================================
--- game/GridStates.cpp	(revision 4014)
+++ game/GridStates.cpp	(working copy)
@@ -30,11 +30,19 @@
 void
 ActiveState::Update(Map &m, NGridType &grid, GridInfo & info, const uint32 &x, const uint32 &y, const uint32 &t_diff) const
 {
-    if( grid.ActiveObjectsInGrid() == 0 && !ObjectAccessor::Instance().PlayersNearGrid(x, y, m.GetId(), m.GetInstanceId()) )
+    // Only check grid activity every (grid_expiry/10) ms, because it's really useless to do it every cycle
+    info.i_timer.Update(t_diff);
+    if (info.i_timer.Passed())
     {
-        ObjectGridStoper stoper(grid);
-        stoper.StopN();
-        grid.SetGridState(GRID_STATE_IDLE);
+        if( grid.ActiveObjectsInGrid() == 0 && !ObjectAccessor::Instance().PlayersNearGrid(x, y, m.GetId(), m.GetInstanceId()) )
+        {
+            ObjectGridStoper stoper(grid);
+            stoper.StopN();
+            grid.SetGridState(GRID_STATE_IDLE);
+        } else
+        {
+            m.ResetGridExpiry(info, 0.1f);
+        }
     }
 }
 
Index: game/Map.cpp
===================================================================
--- game/Map.cpp	(revision 4014)
+++ game/Map.cpp	(working copy)
@@ -73,27 +73,34 @@
     return true;
 }
 
-GridMap * Map::LoadMAP(uint32 mapid, uint32 instanceid, int x,int y)
+void Map::LoadMAP(uint32 mapid, uint32 instanceid, int x,int y)
 {
     //check map file existance (but not output error)
-    if(!Map::ExistMAP(mapid,x,y,false))
-        return NULL;
+    if (!Map::ExistMAP(mapid,x,y,false))
+        return;
 
     if (instanceid != 0)
     {
-        // load from base map
-        if (GridMaps[x][y]) GridMaps[x][y]=NULL;
+        if (GridMaps[x][y])
+            return;
 
-        if (!MapManager::Instance().GetBaseMap(mapid)->GridMaps[x][y])
-        {
-            // load grids for base map
-            MapManager::Instance().GetBaseMap(mapid)->GridMaps[x][y] = Map::LoadMAP(mapid, 0, x, y);
-        }
+        Map* baseMap = MapManager::Instance().GetBaseMap(mapid);
 
-        return(MapManager::Instance().GetBaseMap(mapid)->GridMaps[x][y]);
+        // load gridmap for base map
+        if (!baseMap->GridMaps[x][y])
+            baseMap->EnsureGridCreated(GridPair(63-x,63-y));
+
+        if (!baseMap->GridMaps[x][y])
+            return;
+
+        ((MapInstanced*)(baseMap))->AddGridMapReference(GridPair(x,y));
+        baseMap->SetUnloadFlag(GridPair(63-x,63-y), false);
+        GridMaps[x][y] = baseMap->GridMaps[x][y];
+        return;
     }
 
-    if(GridMaps[x][y])                                      //map already load, delete it before reloading
+    //map already load, delete it before reloading (Is it neccessary? Do we really need the abilty the reload maps during runtime?)
+    if(GridMaps[x][y])
     {
         sLog.outDetail("Unloading already loaded map %u before reloading.",mapid);
         delete (GridMaps[x][y]);
@@ -117,11 +124,12 @@
     if(!buf)                                                //unexpected error
     {
         fclose(pf);
-        return NULL;
+        return;
     }
     fread(buf,1,sizeof(GridMap),pf);
     fclose(pf);
-    return buf;
+
+    GridMaps[x][y] = buf;
 }
 
 void Map::InitStateMachine()
@@ -142,7 +150,6 @@
 
 Map::Map(uint32 id, time_t expiry, uint32 ainstanceId) : i_id(id), i_gridExpiry(expiry), i_mapEntry (sMapStore.LookupEntry(id)), i_resetTime(0), i_InstanceId(ainstanceId)
 {
-    //    char tmp[32];
     for(unsigned int idx=0; idx < MAX_NUMBER_OF_GRIDS; ++idx)
     {
         i_gridMask[idx] = 0;
@@ -152,8 +159,6 @@
             //z code
             GridMaps[idx][j] =NULL;
 
-            //z code
-
             i_grids[idx][j] = NULL;
             i_info[idx][j] = NULL;
         }
@@ -342,14 +347,15 @@
             i_grids[p.x_coord][p.y_coord] = new NGridType(p.x_coord*MAX_NUMBER_OF_GRIDS + p.y_coord);
             i_info[p.x_coord][p.y_coord] = new GridInfo(i_gridExpiry,sWorld.getConfig(CONFIG_GRID_UNLOAD));
             i_gridMask[p.x_coord] |= mask;
+            
+            i_grids[p.x_coord][p.y_coord]->SetGridState(GRID_STATE_IDLE);
+            
             //z coord
-
             int gx=63-p.x_coord;
             int gy=63-p.y_coord;
 
             if(!GridMaps[gx][gy])
-                GridMaps[gx][gy]=Map::LoadMAP(i_id,i_InstanceId,gx,gy);
-
+                Map::LoadMAP(i_id,i_InstanceId,gx,gy);
         }
     }
 
@@ -384,6 +390,7 @@
             // Add resurrectable corpses to world object list in grid
             ObjectAccessor::Instance().AddCorpsesToGrid(GridPair(cell.GridX(),cell.GridY()),(*grid)(cell.CellX(), cell.CellY()), this);
 
+            ResetGridExpiry(*i_info[cell.GridX()][cell.GridY()], 0.1f);
             grid->SetGridState(GRID_STATE_ACTIVE);
 
             if( add_player && player != NULL )
@@ -966,8 +973,11 @@
     UpdateObjectsVisibilityFor(player,new_cell,new_val);
     PlayerRelocationNotify(player,new_cell,new_val);
 
-    if( !same_cell )
+    if( !same_cell && i_grids[new_cell.GridX()][new_cell.GridY()]->GetGridState()!=GRID_STATE_ACTIVE )
+    {
+        ResetGridExpiry(*i_info[new_cell.GridX()][new_cell.GridY()], 0.1f);
         i_grids[new_cell.GridX()][new_cell.GridY()]->SetGridState(GRID_STATE_ACTIVE);
+    }
 }
 
 void
@@ -1167,15 +1177,16 @@
     int gx=63-x;
     int gy=63-y;
 
-    // delete grid map, but don't delete grid map if it is from parent map
-    // FIXME: we must delete also in case single loaded instance or none loaded instances
-    if(GridMaps[gx][gy])
+    // delete grid map, but don't delete if it is from parent map (and thus only reference)
+    if (GridMaps[gx][gy])
     {
-        if (i_InstanceId == 0) delete (GridMaps[gx][gy]);
-        GridMaps[gx][gy]=NULL;
+        if (i_InstanceId == 0)
+            delete (GridMaps[gx][gy]);
+        else
+            ((MapInstanced*)(MapManager::Instance().GetBaseMap(i_id)))->RemoveGridMapReference(GridPair(gx, gy));
+        GridMaps[gx][gy] = NULL;
     }
 
-    //z coordinate
     DEBUG_LOG("Unloading grid[%u,%u] for map %u finished", x,y, i_id);
     return true;
 }
@@ -1189,7 +1200,6 @@
         {
             if( i_gridMask[i] & mask )
                 UnloadGrid(i, j);
-
             mask <<= 1;
         }
     }
@@ -1221,8 +1231,7 @@
     ly=MAP_RESOLUTION*(32 -y/SIZE_OF_GRIDS - gy);
     //DEBUG_LOG("my %d %d si %d %d",gx,gy,p.x_coord,p.y_coord);
 
-    if(!GridMaps[gx][gy])                                   //this map is not loaded
-        GridMaps[gx][gy]=Map::LoadMAP(i_id,i_InstanceId,gx,gy);
+    EnsureGridCreated(GridPair(63-gx,63-gy));               // ensure GridMap is loaded
 
     if(GridMaps[gx][gy])
         return GridMaps[gx][gy]->Z[(int)(lx)][(int)(ly)];
@@ -1256,8 +1265,7 @@
     ly=16*(32 -y/SIZE_OF_GRIDS - gy);
     //DEBUG_LOG("my %d %d si %d %d",gx,gy,p.x_coord,p.y_coord);
 
-    if(!GridMaps[gx][gy])                                   //this map is not loaded
-        GridMaps[gx][gy]=Map::LoadMAP(i_id,i_InstanceId,gx,gy);
+    EnsureGridCreated(GridPair(63-gx,63-gy));               // ensure GridMap is loaded
 
     if(GridMaps[gx][gy])
         return GridMaps[gx][gy]->area_flag[(int)(lx)][(int)(ly)];
@@ -1291,8 +1299,7 @@
     lx=16*(32 -x/SIZE_OF_GRIDS - gx);
     ly=16*(32 -y/SIZE_OF_GRIDS - gy);
 
-    if(!GridMaps[gx][gy])                                   //this map is not loaded
-        GridMaps[gx][gy]=Map::LoadMAP(i_id,i_InstanceId,gx,gy);
+    EnsureGridCreated(GridPair(63-gx,63-gy));               // ensure GridMap is loaded
 
     if(GridMaps[gx][gy])
         return GridMaps[gx][gy]->terrain_type[(int)(lx)][(int)(ly)];
@@ -1326,8 +1333,7 @@
     lx=128*(32 -x/SIZE_OF_GRIDS - gx);
     ly=128*(32 -y/SIZE_OF_GRIDS - gy);
 
-    if(!GridMaps[gx][gy])                                   //this map is not loaded
-        GridMaps[gx][gy]=Map::LoadMAP(i_id,i_InstanceId,gx,gy);
+    EnsureGridCreated(GridPair(63-gx,63-gy));               // ensure GridMap is loaded
 
     if(GridMaps[gx][gy])
         return GridMaps[gx][gy]->liquid_level[(int)(lx)][(int)(ly)];
Index: game/Map.h
===================================================================
--- game/Map.h	(revision 4014)
+++ game/Map.h	(working copy)
@@ -92,6 +92,7 @@
     public:
 
         Map(uint32 id, time_t, uint32 aInstanceId);
+        virtual ~Map() {};    // Important! Else memleak at MapInstanced class destruction
 
         void Add(Player *);
         bool AddInstanced(Player *);
@@ -148,16 +149,16 @@
         bool UnloadGrid(const uint32 &x, const uint32 &y);
         virtual void UnloadAll();
 
-        void ResetGridExpiry(GridInfo &info) const
+        void ResetGridExpiry(GridInfo &info, float factor = 1) const
         {
-            info.i_timer.Reset(i_gridExpiry);
+            info.i_timer.Reset((time_t)((float)i_gridExpiry*factor));
         }
 
         time_t GetGridExpiry(void) const { return i_gridExpiry; }
         uint32 GetId(void) const { return i_id; }
 
         static bool ExistMAP(uint32 mapid, int x, int y, bool output = true);
-        GridMap * LoadMAP(uint32 mapid, uint32 instanceid, int x, int y);
+        void LoadMAP(uint32 mapid, uint32 instanceid, int x, int y);
 
         static void InitStateMachine();
         static void DeleteStateMachine();
Index: game/MapInstanced.cpp
===================================================================
--- game/MapInstanced.cpp	(revision 4014)
+++ game/MapInstanced.cpp	(working copy)
@@ -25,10 +25,16 @@
 {
     // initialize instanced maps list
     InstancedMaps.clear();
+    // fill with zero
+    memset(&GridMapReference, 0, MAX_NUMBER_OF_GRIDS*MAX_NUMBER_OF_GRIDS*sizeof(uint16));
 }
 
 void MapInstanced::Update(const uint32& t)
 {
+    // take care of loaded GridMaps (when unused, unload it!)
+    Map::Update(t);
+
+    // update the instanced maps
     HM_NAMESPACE::hash_map< uint32, Map* >::iterator i = InstancedMaps.begin();
 
     while (i != InstancedMaps.end())
@@ -83,10 +89,16 @@
 
 void MapInstanced::UnloadAll()
 {
+    // Unload instanced maps
     for (HM_NAMESPACE::hash_map< uint32, Map* >::iterator i = InstancedMaps.begin(); i != InstancedMaps.end(); i++)
     {
         i->second->UnloadAll();
+        delete i->second;
     }
+    InstancedMaps.clear();
+
+    // Unload own grids (just dummy(placeholder) grids, neccesary to unload GridMaps!)
+    Map::UnloadAll();
 }
 
 Map* MapInstanced::GetInstance(const WorldObject* obj)
Index: game/MapInstanced.h
===================================================================
--- game/MapInstanced.h	(revision 4014)
+++ game/MapInstanced.h	(working copy)
@@ -26,6 +26,7 @@
     public:
 
         MapInstanced(uint32 id, time_t, uint32 aInstanceId);
+        ~MapInstanced() {}    // Important! Else memleak at class destruction
 
         virtual void Update(const uint32&);
         virtual void MoveAllCreaturesInMoveList();
@@ -35,6 +36,13 @@
         Map* GetInstance(const WorldObject* obj);
         bool IsValidInstance(uint32 InstanceId);
 
+        void AddGridMapReference(const GridPair &p) { GridMapReference[p.x_coord][p.y_coord]++; }
+        void RemoveGridMapReference(const GridPair &p)
+        {
+            GridMapReference[p.x_coord][p.y_coord]--;
+            if (!GridMapReference[p.x_coord][p.y_coord]) { SetUnloadFlag(GridPair(63-p.x_coord,63-p.y_coord), true); }
+        }
+
     private:
 
         void CreateInstance(uint32 InstanceId, Map* &map);
@@ -47,6 +55,8 @@
 
             return(i == InstancedMaps.end() ? NULL : i->second);
         }
+
+        uint16 GridMapReference[MAX_NUMBER_OF_GRIDS][MAX_NUMBER_OF_GRIDS];
 };
 
 #endif