*Move object update from objectaccessor to map

*Move activeobject list from objectaccessor to map
*Open grid for all active creatures (previously only for possessed ones)

--HG--
branch : trunk
This commit is contained in:
megamage
2008-11-21 15:41:18 -06:00
parent 71707df1de
commit e9d6f1b23a
8 changed files with 111 additions and 103 deletions
+4 -4
View File
@@ -10,12 +10,12 @@
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#include "GridStates.h" #include "GridStates.h"
@@ -36,7 +36,7 @@ ActiveState::Update(Map &m, NGridType &grid, GridInfo & info, const uint32 &x, c
info.UpdateTimeTracker(t_diff); info.UpdateTimeTracker(t_diff);
if( info.getTimeTracker().Passed() ) if( info.getTimeTracker().Passed() )
{ {
if( grid.ActiveObjectsInGrid() == 0 && !ObjectAccessor::Instance().ActiveObjectsNearGrid(x, y, m.GetId(), m.GetInstanceId()) ) if( grid.ActiveObjectsInGrid() == 0 && !m.ActiveObjectsNearGrid(x, y) )
{ {
ObjectGridStoper stoper(grid); ObjectGridStoper stoper(grid);
stoper.StopN(); stoper.StopN();
@@ -50,7 +50,7 @@ ActiveState::Update(Map &m, NGridType &grid, GridInfo & info, const uint32 &x, c
} }
void void
IdleState::Update(Map &m, NGridType &grid, GridInfo &info, const uint32 &x, const uint32 &y, const uint32 &) const IdleState::Update(Map &m, NGridType &grid, GridInfo &, const uint32 &x, const uint32 &y, const uint32 &) const
{ {
m.ResetGridExpiry(grid); m.ResetGridExpiry(grid);
grid.SetGridState(GRID_STATE_REMOVAL); grid.SetGridState(GRID_STATE_REMOVAL);
+87 -40
View File
@@ -594,57 +594,69 @@ bool Map::loaded(const GridPair &p) const
return ( getNGrid(p.x_coord, p.y_coord) && isGridObjectDataLoaded(p.x_coord, p.y_coord) ); return ( getNGrid(p.x_coord, p.y_coord) && isGridObjectDataLoaded(p.x_coord, p.y_coord) );
} }
void Map::Update(const uint32 &t_diff) void Map::UpdateActiveCells(const float &x, const float &y, const uint32 &t_diff)
{ {
// TODO: need have an active object list for every map CellPair standing_cell(Trinity::ComputeCellPair(x, y));
/*resetMarkedCells(); // Check for correctness of standing_cell, it also avoids problems with update_cell
if (standing_cell.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || standing_cell.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP)
return;
// will this reduce the speed?
Trinity::ObjectUpdater updater(t_diff); Trinity::ObjectUpdater updater(t_diff);
// for creature // for creature
TypeContainerVisitor<Trinity::ObjectUpdater, GridTypeMapContainer > grid_object_update(updater); TypeContainerVisitor<Trinity::ObjectUpdater, GridTypeMapContainer > grid_object_update(updater);
// for pets // for pets
TypeContainerVisitor<Trinity::ObjectUpdater, WorldTypeMapContainer > world_object_update(updater); TypeContainerVisitor<Trinity::ObjectUpdater, WorldTypeMapContainer > world_object_update(updater);
// the overloaded operators handle range checking
// so ther's no need for range checking inside the loop
CellPair begin_cell(standing_cell), end_cell(standing_cell);
begin_cell << 1; begin_cell -= 1; // upper left
end_cell >> 1; end_cell += 1; // lower right
for(uint32 x = begin_cell.x_coord; x <= end_cell.x_coord; ++x)
{
for(uint32 y = begin_cell.y_coord; y <= end_cell.y_coord; ++y)
{
// marked cells are those that have been visited
// don't visit the same cell twice
uint32 cell_id = (y * TOTAL_NUMBER_OF_CELLS_PER_MAP) + x;
if(!isCellMarked(cell_id))
{
markCell(cell_id);
CellPair pair(x,y);
Cell cell(pair);
cell.data.Part.reserved = CENTER_DISTRICT;
cell.SetNoCreate();
CellLock<NullGuard> cell_lock(cell, pair);
cell_lock->Visit(cell_lock, grid_object_update, *this);
cell_lock->Visit(cell_lock, world_object_update, *this);
}
}
}
}
void Map::Update(const uint32 &t_diff)
{
resetMarkedCells();
// update cells around players
for(MapRefManager::iterator iter = m_mapRefManager.begin(); iter != m_mapRefManager.end(); ++iter) for(MapRefManager::iterator iter = m_mapRefManager.begin(); iter != m_mapRefManager.end(); ++iter)
{ {
Player* plr = iter->getSource(); Player* plr = iter->getSource();
if(!plr->IsInWorld()) if(plr->IsInWorld())
continue; UpdateActiveCells(plr->GetPositionX(), plr->GetPositionY(), t_diff);
}
CellPair standing_cell(Trinity::ComputeCellPair(plr->GetPositionX(), plr->GetPositionY())); // update cells around active objects
// clone the active object list, because update might remove from it
// Check for correctness of standing_cell, it also avoids problems with update_cell std::set<WorldObject *> activeObjects(i_activeObjects);
if (standing_cell.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || standing_cell.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP) for(std::set<WorldObject *>::iterator iter = activeObjects.begin(); iter != activeObjects.end(); ++iter)
continue; {
if((*iter)->IsInWorld())
// the overloaded operators handle range checking UpdateActiveCells((*iter)->GetPositionX(), (*iter)->GetPositionY(), t_diff);
// so ther's no need for range checking inside the loop }
CellPair begin_cell(standing_cell), end_cell(standing_cell);
begin_cell << 1; begin_cell -= 1; // upper left
end_cell >> 1; end_cell += 1; // lower right
for(uint32 x = begin_cell.x_coord; x <= end_cell.x_coord; ++x)
{
for(uint32 y = begin_cell.y_coord; y <= end_cell.y_coord; ++y)
{
// marked cells are those that have been visited
// don't visit the same cell twice
uint32 cell_id = (y * TOTAL_NUMBER_OF_CELLS_PER_MAP) + x;
if(!isCellMarked(cell_id))
{
markCell(cell_id);
CellPair pair(x,y);
Cell cell(pair);
cell.data.Part.reserved = CENTER_DISTRICT;
cell.SetNoCreate();
CellLock<NullGuard> cell_lock(cell, pair);
cell_lock->Visit(cell_lock, grid_object_update, *this);
cell_lock->Visit(cell_lock, world_object_update, *this);
}
}
}
}*/
// Don't unload grids if it's battleground, since we may have manually added GOs,creatures, those doesn't load from DB at grid re-load ! // Don't unload grids if it's battleground, since we may have manually added GOs,creatures, those doesn't load from DB at grid re-load !
// This isn't really bother us, since as soon as we have instanced BG-s, the whole map unloads as the BG gets ended // This isn't really bother us, since as soon as we have instanced BG-s, the whole map unloads as the BG gets ended
@@ -813,8 +825,13 @@ Map::CreatureRelocation(Creature *creature, float x, float y, float z, float ang
#endif #endif
AddCreatureToMoveList(creature,x,y,z,ang); AddCreatureToMoveList(creature,x,y,z,ang);
// in diffcell/diffgrid case notifiers called at finishing move creature in Map::MoveAllCreaturesInMoveList // in diffcell/diffgrid case notifiers called at finishing move creature in Map::MoveAllCreaturesInMoveList
if(creature->isPossessedByPlayer()) if(creature->isActive())
EnsureGridLoadedForPlayer(new_cell, (Player*)creature->GetCharmer(), false); {
if(creature->isPossessedByPlayer())
EnsureGridLoadedForPlayer(new_cell, (Player*)creature->GetCharmer(), false);
else
EnsureGridLoadedForPlayer(new_cell, NULL, false);
}
} }
else else
{ {
@@ -1509,6 +1526,36 @@ bool Map::PlayersNearGrid(uint32 x, uint32 y) const
return false; return false;
} }
bool Map::ActiveObjectsNearGrid(uint32 x, uint32 y) const
{
CellPair cell_min(x*MAX_NUMBER_OF_CELLS, y*MAX_NUMBER_OF_CELLS);
CellPair cell_max(cell_min.x_coord + MAX_NUMBER_OF_CELLS, cell_min.y_coord+MAX_NUMBER_OF_CELLS);
cell_min << 2;
cell_min -= 2;
cell_max >> 2;
cell_max += 2;
for(MapRefManager::const_iterator iter = m_mapRefManager.begin(); iter != m_mapRefManager.end(); ++iter)
{
Player* plr = iter->getSource();
CellPair p = Trinity::ComputeCellPair(plr->GetPositionX(), plr->GetPositionY());
if( (cell_min.x_coord <= p.x_coord && p.x_coord <= cell_max.x_coord) &&
(cell_min.y_coord <= p.y_coord && p.y_coord <= cell_max.y_coord) )
return true;
}
for(std::set<WorldObject*>::const_iterator itr = i_activeObjects.begin(); itr != i_activeObjects.end(); ++itr)
{
CellPair p = Trinity::ComputeCellPair((*itr)->GetPositionX(), (*itr)->GetPositionY());
if( (cell_min.x_coord <= p.x_coord && p.x_coord <= cell_max.x_coord) &&
(cell_min.y_coord <= p.y_coord && p.y_coord <= cell_max.y_coord) )
return true;
}
return false;
}
template void Map::Add(Corpse *); template void Map::Add(Corpse *);
template void Map::Add(Creature *); template void Map::Add(Creature *);
template void Map::Add(GameObject *); template void Map::Add(GameObject *);
+6
View File
@@ -242,6 +242,10 @@ class TRINITY_DLL_SPEC Map : public GridRefManager<NGridType>, public Trinity::O
bool HavePlayers() const { return !m_mapRefManager.isEmpty(); } bool HavePlayers() const { return !m_mapRefManager.isEmpty(); }
uint32 GetPlayersCountExceptGMs() const; uint32 GetPlayersCountExceptGMs() const;
bool PlayersNearGrid(uint32 x,uint32 y) const; bool PlayersNearGrid(uint32 x,uint32 y) const;
bool ActiveObjectsNearGrid(uint32 x, uint32 y) const;
void AddActiveObject(WorldObject* obj) { i_activeObjects.insert(obj); }
void RemoveActiveObject(WorldObject* obj) { i_activeObjects.erase(obj); }
void SendToPlayers(WorldPacket const* data) const; void SendToPlayers(WorldPacket const* data) const;
@@ -287,6 +291,7 @@ class TRINITY_DLL_SPEC Map : public GridRefManager<NGridType>, public Trinity::O
inline void setNGrid(NGridType* grid, uint32 x, uint32 y); inline void setNGrid(NGridType* grid, uint32 x, uint32 y);
void UpdateActiveCells(const float &x, const float &y, const uint32 &t_diff);
protected: protected:
typedef Trinity::ObjectLevelLockable<Map, ZThread::Mutex>::Lock Guard; typedef Trinity::ObjectLevelLockable<Map, ZThread::Mutex>::Lock Guard;
@@ -307,6 +312,7 @@ class TRINITY_DLL_SPEC Map : public GridRefManager<NGridType>, public Trinity::O
time_t i_gridExpiry; time_t i_gridExpiry;
std::set<WorldObject *> i_activeObjects;
std::set<WorldObject *> i_objectsToRemove; std::set<WorldObject *> i_objectsToRemove;
// Type specific code for add/remove to/from grid // Type specific code for add/remove to/from grid
+10 -9
View File
@@ -990,36 +990,37 @@ WorldObject::WorldObject()
WorldObject::~WorldObject() WorldObject::~WorldObject()
{ {
if(m_isActive && IsInWorld()) if(m_isActive && !isType(TYPEMASK_PLAYER) && IsInWorld())
ObjectAccessor::Instance().RemoveActiveObject(this); GetMap()->RemoveActiveObject(this);
} }
void WorldObject::setActive(bool isActive) void WorldObject::setActive(bool isActive)
{ {
// if already in the same activity state as we try to set, do nothing // if already in the same activity state as we try to set, do nothing
if(isActive == m_isActive) if(isActive == m_isActive || isType(TYPEMASK_PLAYER))
return; return;
m_isActive = isActive; m_isActive = isActive;
if(IsInWorld()) if(IsInWorld())
{ {
if(isActive) if(isActive)
ObjectAccessor::Instance().AddActiveObject(this); GetMap()->AddActiveObject(this);
else else
ObjectAccessor::Instance().RemoveActiveObject(this); GetMap()->RemoveActiveObject(this);
} }
} }
void WorldObject::AddToWorld() void WorldObject::AddToWorld()
{ {
Object::AddToWorld(); Object::AddToWorld();
if(m_isActive) if(m_isActive && !isType(TYPEMASK_PLAYER))
ObjectAccessor::Instance().AddActiveObject(this); GetMap()->AddActiveObject(this);
} }
void WorldObject::RemoveFromWorld() void WorldObject::RemoveFromWorld()
{ {
if(m_isActive) if(m_isActive && !isType(TYPEMASK_PLAYER))
ObjectAccessor::Instance().RemoveActiveObject(this); GetMap()->RemoveActiveObject(this);
Object::RemoveFromWorld(); Object::RemoveFromWorld();
} }
+1 -1
View File
@@ -455,7 +455,7 @@ class TRINITY_DLL_SPEC WorldObject : public Object
Creature* SummonCreature(uint32 id, float x, float y, float z, float ang,TempSummonType spwtype,uint32 despwtime); Creature* SummonCreature(uint32 id, float x, float y, float z, float ang,TempSummonType spwtype,uint32 despwtime);
GameObject* SummonGameObject(uint32 entry, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 respawnTime); GameObject* SummonGameObject(uint32 entry, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 respawnTime);
bool isActive() const { return m_isActive; } bool isActive() const { return m_isActive; }
virtual void setActive(bool isActive); void setActive(bool isActive);
protected: protected:
explicit WorldObject(); explicit WorldObject();
std::string m_name; std::string m_name;
+3 -41
View File
@@ -486,25 +486,11 @@ ObjectAccessor::ConvertCorpseForPlayer(uint64 player_guid)
return bones; return bones;
} }
void
ObjectAccessor::AddActiveObject( WorldObject * obj )
{
i_activeobjects.insert(obj);
}
void
ObjectAccessor::RemoveActiveObject( WorldObject * obj )
{
i_activeobjects.erase(obj);
}
void void
ObjectAccessor::Update(uint32 diff) ObjectAccessor::Update(uint32 diff)
{ {
/* {
{
//Player update now in MapManager -> UpdatePlayers //Player update now in MapManager -> UpdatePlayers
/*
// player update might remove the player from grid, and that causes crashes. We HAVE to update players first, and then the active objects. // player update might remove the player from grid, and that causes crashes. We HAVE to update players first, and then the active objects.
HashMapHolder<Player>::MapType& playerMap = HashMapHolder<Player>::GetContainer(); HashMapHolder<Player>::MapType& playerMap = HashMapHolder<Player>::GetContainer();
for(HashMapHolder<Player>::MapType::iterator iter = playerMap.begin(); iter != playerMap.end(); ++iter) for(HashMapHolder<Player>::MapType::iterator iter = playerMap.begin(); iter != playerMap.end(); ++iter)
@@ -513,7 +499,7 @@ ObjectAccessor::Update(uint32 diff)
{ {
iter->second->Update(diff); iter->second->Update(diff);
} }
}*/ }
// TODO: move this to Map::Update // TODO: move this to Map::Update
// clone the active object list, because update might remove from it // clone the active object list, because update might remove from it
@@ -574,7 +560,7 @@ ObjectAccessor::Update(uint32 diff)
} }
} }
} }
} }*/
UpdateDataMapType update_players; UpdateDataMapType update_players;
{ {
@@ -608,30 +594,6 @@ ObjectAccessor::UpdatePlayers(uint32 diff)
iter->second->Update(diff); iter->second->Update(diff);
} }
bool
ObjectAccessor::ActiveObjectsNearGrid(uint32 x, uint32 y, uint32 m_id, uint32 i_id) const
{
CellPair cell_min(x*MAX_NUMBER_OF_CELLS, y*MAX_NUMBER_OF_CELLS);
CellPair cell_max(cell_min.x_coord + MAX_NUMBER_OF_CELLS, cell_min.y_coord+MAX_NUMBER_OF_CELLS);
cell_min << 2;
cell_min -= 2;
cell_max >> 2;
cell_max += 2;
for(std::set<WorldObject*>::const_iterator itr = i_activeobjects.begin(); itr != i_activeobjects.end(); ++itr)
{
if( m_id != (*itr)->GetMapId() || i_id != (*itr)->GetInstanceId() )
continue;
CellPair p = Trinity::ComputeCellPair((*itr)->GetPositionX(), (*itr)->GetPositionY());
if( (cell_min.x_coord <= p.x_coord && p.x_coord <= cell_max.x_coord) &&
(cell_min.y_coord <= p.y_coord && p.y_coord <= cell_max.y_coord) )
return true;
}
return false;
}
void void
ObjectAccessor::WorldObjectChangeAccumulator::Visit(PlayerMapType &m) ObjectAccessor::WorldObjectChangeAccumulator::Visit(PlayerMapType &m)
{ {
-6
View File
@@ -194,16 +194,11 @@ class TRINITY_DLL_DECL ObjectAccessor : public Trinity::Singleton<ObjectAccessor
void AddCorpsesToGrid(GridPair const& gridpair,GridType& grid,Map* map); void AddCorpsesToGrid(GridPair const& gridpair,GridType& grid,Map* map);
Corpse* ConvertCorpseForPlayer(uint64 player_guid); Corpse* ConvertCorpseForPlayer(uint64 player_guid);
bool ActiveObjectsNearGrid(uint32 x,uint32 y,uint32 m_id,uint32 i_id) const;
static void UpdateObject(Object* obj, Player* exceptPlayer); static void UpdateObject(Object* obj, Player* exceptPlayer);
static void _buildUpdateObject(Object* obj, UpdateDataMapType &); static void _buildUpdateObject(Object* obj, UpdateDataMapType &);
static void UpdateObjectVisibility(WorldObject* obj); static void UpdateObjectVisibility(WorldObject* obj);
static void UpdateVisibilityForPlayer(Player* player); static void UpdateVisibilityForPlayer(Player* player);
void AddActiveObject(WorldObject*);
void RemoveActiveObject(WorldObject*);
private: private:
struct WorldObjectChangeAccumulator struct WorldObjectChangeAccumulator
{ {
@@ -228,7 +223,6 @@ class TRINITY_DLL_DECL ObjectAccessor : public Trinity::Singleton<ObjectAccessor
static void _buildPacket(Player *, Object *, UpdateDataMapType &); static void _buildPacket(Player *, Object *, UpdateDataMapType &);
void _update(void); void _update(void);
std::set<Object *> i_objects; std::set<Object *> i_objects;
std::set<WorldObject *> i_activeobjects;
LockType i_playerGuard; LockType i_playerGuard;
LockType i_updateGuard; LockType i_updateGuard;
LockType i_corpseGuard; LockType i_corpseGuard;
-2
View File
@@ -897,8 +897,6 @@ class TRINITY_DLL_SPEC Player : public Unit
void AddToWorld(); void AddToWorld();
void RemoveFromWorld(); void RemoveFromWorld();
// always active
void setActive(bool) {}
void SetViewport(uint64 guid, bool movable); void SetViewport(uint64 guid, bool movable);
void Possess(Unit *target); void Possess(Unit *target);