rendered paste bodyIndex: game/GridStates.cpp
===================================================================
--- game/GridStates.cpp (revision 4064)
+++ 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 4064)
+++ game/Map.cpp (working copy)
@@ -89,7 +89,6 @@
return true;
}
-//=========================================
void Map::loadVMap(int x,int y)
{
@@ -107,28 +106,35 @@
break;
}
}
-//=========================================
-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]);
@@ -151,12 +157,13 @@
if(!buf) //unexpected error
{
fclose(pf);
- return NULL;
+ return;
}
fread(buf,1,sizeof(GridMap),pf);
fclose(pf);
+
loadVMap(x, y);
- return buf;
+ GridMaps[x][y] = buf;
}
void Map::InitStateMachine()
@@ -177,7 +184,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;
@@ -187,8 +193,6 @@
//z code
GridMaps[idx][j] =NULL;
- //z code
-
i_grids[idx][j] = NULL;
i_info[idx][j] = NULL;
}
@@ -377,14 +381,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);
}
}
@@ -419,6 +424,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 )
@@ -1002,8 +1008,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
@@ -1203,16 +1212,17 @@
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;
}
VMAP::VMapFactory::createOrGetVMapManager()->unloadMap(GetId(), gy, gx); // x and y are swaped
- //z coordinate
DEBUG_LOG("Unloading grid[%u,%u] for map %u finished", x,y, i_id);
return true;
}
@@ -1226,7 +1236,6 @@
{
if( i_gridMask[i] & mask )
UnloadGrid(i, j);
-
mask <<= 1;
}
}
@@ -1258,8 +1267,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
VMAP::IVMapManager* vmgr = VMAP::VMapFactory::createOrGetVMapManager();
if(vmgr->isHeightCalcEnabled())
@@ -1323,8 +1331,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)];
@@ -1358,8 +1365,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)];
@@ -1393,8 +1399,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 4064)
+++ 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 4064)
+++ game/MapInstanced.cpp (working copy)
@@ -26,10 +26,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())
@@ -85,10 +91,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 4064)
+++ 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