[8678] Move objects updates store and proccessing for send to client in per map way.

This commit is contained in:
VladimirMangos 2009-10-19 23:24:41 +04:00
parent abb77cfdbf
commit 8bf52f7c63
10 changed files with 80 additions and 61 deletions

View file

@ -996,6 +996,18 @@ bool Item::IsBindedNotWith( Player const* player ) const
}
}
void Item::AddToClientUpdateList()
{
if (Player* pl = GetOwner())
pl->GetMap()->AddUpdateObject(this);
}
void Item::RemoveFromClientUpdateList()
{
if (Player* pl = GetOwner())
pl->GetMap()->RemoveUpdateObject(this);
}
void Item::BuildUpdateData(UpdateDataMapType& update_players)
{
if (Player* pl = GetOwner())

View file

@ -313,6 +313,8 @@ class MANGOS_DLL_SPEC Item : public Object
bool IsPotion() const { return GetProto()->IsPotion(); }
bool IsConjuredConsumable() const { return GetProto()->IsConjuredConsumable(); }
void AddToClientUpdateList();
void RemoveFromClientUpdateList();
void BuildUpdateData(UpdateDataMapType& update_players);
private:
uint8 m_slot;

View file

@ -697,6 +697,9 @@ void Map::Update(const uint32 &t_diff)
}
}
// Send world objects and item update field changes
SendObjectUpdates();
// 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
if (!IsBattleGroundOrArena())
@ -3415,3 +3418,25 @@ DynamicObject* Map::GetDynamicObject(uint64 guid)
{
return m_objectsStore.find<DynamicObject>(guid, (DynamicObject*)NULL);
}
void Map::SendObjectUpdates()
{
UpdateDataMapType update_players;
while(!i_objectsToClientUpdate.empty())
{
Object* obj = *i_objectsToClientUpdate.begin();
i_objectsToClientUpdate.erase(i_objectsToClientUpdate.begin());
if (!obj)
continue;
obj->BuildUpdateData(update_players);
}
WorldPacket packet; // here we allocate a std::vector with a size of 0x10000
for(UpdateDataMapType::iterator iter = update_players.begin(); iter != update_players.end(); ++iter)
{
iter->second.BuildPacket(&packet);
iter->first->GetSession()->SendPacket(&packet);
packet.clear(); // clean the string
}
}

View file

@ -428,6 +428,16 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
DynamicObject* GetDynamicObject(uint64 guid);
TypeUnorderedMapContainer<AllMapStoredObjectTypes>& GetObjectsStore() { return m_objectsStore; }
void AddUpdateObject(Object *obj)
{
i_objectsToClientUpdate.insert(obj);
}
void RemoveUpdateObject(Object *obj)
{
i_objectsToClientUpdate.erase( obj );
}
private:
void LoadMapAndVMap(int gx, int gy);
void LoadVMap(int gx, int gy);
@ -472,6 +482,8 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
void setNGrid(NGridType* grid, uint32 x, uint32 y);
void ScriptsProcess();
void SendObjectUpdates();
std::set<Object *> i_objectsToClientUpdate;
protected:
void SetUnloadReferenceLock(const GridPair &p, bool on) { getNGrid(p.x_coord, p.y_coord)->setUnloadReferenceLock(on); }

View file

@ -268,7 +268,6 @@ MapManager::Update(uint32 diff)
iter->second->Update(i_timer.GetCurrent());
}
ObjectAccessor::Instance().Update(i_timer.GetCurrent());
for (TransportSet::iterator iter = m_Transports.begin(); iter != m_Transports.end(); ++iter)
(*iter)->Update(i_timer.GetCurrent());

View file

@ -80,9 +80,6 @@ Object::Object( ) : m_PackGUID(sizeof(uint64)+1)
Object::~Object( )
{
if(m_objectUpdated)
ObjectAccessor::Instance().RemoveUpdateObject(this);
if(m_uint32Values)
{
if(IsInWorld())
@ -744,10 +741,11 @@ void Object::ClearUpdateMask(bool remove)
if(m_uint32Values_mirror[index]!= m_uint32Values[index])
m_uint32Values_mirror[index] = m_uint32Values[index];
}
if(m_objectUpdated)
{
if(remove)
ObjectAccessor::Instance().RemoveUpdateObject(this);
RemoveFromClientUpdateList();
m_objectUpdated = false;
}
}
@ -801,7 +799,7 @@ void Object::SetInt32Value( uint16 index, int32 value )
{
if(!m_objectUpdated)
{
ObjectAccessor::Instance().AddUpdateObject(this);
AddToClientUpdateList();
m_objectUpdated = true;
}
}
@ -820,7 +818,7 @@ void Object::SetUInt32Value( uint16 index, uint32 value )
{
if(!m_objectUpdated)
{
ObjectAccessor::Instance().AddUpdateObject(this);
AddToClientUpdateList();
m_objectUpdated = true;
}
}
@ -839,7 +837,7 @@ void Object::SetUInt64Value( uint16 index, const uint64 &value )
{
if(!m_objectUpdated)
{
ObjectAccessor::Instance().AddUpdateObject(this);
AddToClientUpdateList();
m_objectUpdated = true;
}
}
@ -858,7 +856,7 @@ void Object::SetFloatValue( uint16 index, float value )
{
if(!m_objectUpdated)
{
ObjectAccessor::Instance().AddUpdateObject(this);
AddToClientUpdateList();
m_objectUpdated = true;
}
}
@ -884,7 +882,7 @@ void Object::SetByteValue( uint16 index, uint8 offset, uint8 value )
{
if(!m_objectUpdated)
{
ObjectAccessor::Instance().AddUpdateObject(this);
AddToClientUpdateList();
m_objectUpdated = true;
}
}
@ -910,7 +908,7 @@ void Object::SetUInt16Value( uint16 index, uint8 offset, uint16 value )
{
if(!m_objectUpdated)
{
ObjectAccessor::Instance().AddUpdateObject(this);
AddToClientUpdateList();
m_objectUpdated = true;
}
}
@ -979,7 +977,7 @@ void Object::SetFlag( uint16 index, uint32 newFlag )
{
if(!m_objectUpdated)
{
ObjectAccessor::Instance().AddUpdateObject(this);
AddToClientUpdateList();
m_objectUpdated = true;
}
}
@ -1000,7 +998,7 @@ void Object::RemoveFlag( uint16 index, uint32 oldFlag )
{
if(!m_objectUpdated)
{
ObjectAccessor::Instance().AddUpdateObject(this);
AddToClientUpdateList();
m_objectUpdated = true;
}
}
@ -1025,7 +1023,7 @@ void Object::SetByteFlag( uint16 index, uint8 offset, uint8 newFlag )
{
if(!m_objectUpdated)
{
ObjectAccessor::Instance().AddUpdateObject(this);
AddToClientUpdateList();
m_objectUpdated = true;
}
}
@ -1050,7 +1048,7 @@ void Object::RemoveByteFlag( uint16 index, uint8 offset, uint8 oldFlag )
{
if(!m_objectUpdated)
{
ObjectAccessor::Instance().AddUpdateObject(this);
AddToClientUpdateList();
m_objectUpdated = true;
}
}
@ -1871,6 +1869,16 @@ void WorldObject::UpdateObjectVisibility()
GetMap()->UpdateObjectVisibility(this, cell, p);
}
void WorldObject::AddToClientUpdateList()
{
GetMap()->AddUpdateObject(this);
}
void WorldObject::RemoveFromClientUpdateList()
{
GetMap()->RemoveUpdateObject(this);
}
struct WorldObjectChangeAccumulator
{
UpdateDataMapType &i_updateDatas;

View file

@ -124,7 +124,7 @@ class MANGOS_DLL_SPEC Object
m_inWorld = true;
// synchronize values mirror with values array (changes will send in updatecreate opcode any way
ClearUpdateMask(true);
ClearUpdateMask(false); // false - we can't have update dat in update queue before adding to world
}
virtual void RemoveFromWorld()
{
@ -148,6 +148,8 @@ class MANGOS_DLL_SPEC Object
virtual void BuildCreateUpdateBlockForPlayer( UpdateData *data, Player *target ) const;
void SendCreateUpdateToPlayer(Player* player);
virtual void AddToClientUpdateList() =0;
virtual void RemoveFromClientUpdateList() =0;
virtual void BuildUpdateData(UpdateDataMapType& update_players) =0;
void BuildValuesUpdateBlockForPlayer( UpdateData *data, Player *target ) const;
void BuildOutOfRangeUpdateBlock( UpdateData *data ) const;
@ -308,6 +310,7 @@ class MANGOS_DLL_SPEC Object
virtual void _SetUpdateBits(UpdateMask *updateMask, Player *target) const;
virtual void _SetCreateBits(UpdateMask *updateMask, Player *target) const;
void BuildMovementUpdate(ByteBuffer * data, uint16 flags, uint32 flags2 ) const;
void BuildValuesUpdate(uint8 updatetype, ByteBuffer *data, UpdateMask *updateMask, Player *target ) const;
void BuildUpdateDataForPlayer(Player* pl, UpdateDataMapType& update_players);
@ -494,6 +497,8 @@ class MANGOS_DLL_SPEC WorldObject : public Object
//this function should be removed in nearest time...
Map const* GetBaseMap() const;
void AddToClientUpdateList();
void RemoveFromClientUpdateList();
void BuildUpdateData(UpdateDataMapType &);
Creature* SummonCreature(uint32 id, float x, float y, float z, float ang,TempSummonType spwtype,uint32 despwtime);

View file

@ -331,31 +331,6 @@ ObjectAccessor::ConvertCorpseForPlayer(uint64 player_guid, bool insignia)
return bones;
}
void
ObjectAccessor::Update(uint32 diff)
{
UpdateDataMapType update_players;
{
Guard guard(i_updateGuard);
while(!i_objects.empty())
{
Object* obj = *i_objects.begin();
i_objects.erase(i_objects.begin());
if (!obj)
continue;
obj->BuildUpdateData(update_players);
}
}
WorldPacket packet; // here we allocate a std::vector with a size of 0x10000
for(UpdateDataMapType::iterator iter = update_players.begin(); iter != update_players.end(); ++iter)
{
iter->second.BuildPacket(&packet);
iter->first->GetSession()->SendPacket(&packet);
packet.clear(); // clean the string
}
}
/// Define the static member of HashMapHolder
template <class T> UNORDERED_MAP< uint64, T* > HashMapHolder<T>::m_objectMap;

View file

@ -152,27 +152,10 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton<ObjectAccessor,
void RemoveObject(Player *pl)
{
HashMapHolder<Player>::Remove(pl);
Guard guard(i_updateGuard);
i_objects.erase((Object *)pl);
}
void SaveAllPlayers();
void AddUpdateObject(Object *obj)
{
Guard guard(i_updateGuard);
i_objects.insert(obj);
}
void RemoveUpdateObject(Object *obj)
{
Guard guard(i_updateGuard);
i_objects.erase( obj );
}
void Update(uint32 diff);
Corpse* GetCorpseForPlayerGUID(uint64 guid);
void RemoveCorpse(Corpse *corpse);
void AddCorpse(Corpse* corpse);
@ -206,9 +189,7 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton<ObjectAccessor,
typedef ACE_Thread_Mutex LockType;
typedef MaNGOS::GeneralLock<LockType > Guard;
std::set<Object *> i_objects;
LockType i_playerGuard;
LockType i_updateGuard;
LockType i_corpseGuard;
};

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "8677"
#define REVISION_NR "8678"
#endif // __REVISION_NR_H__