From 1d3dff32c16e61815beda5f612488b448f5a47c4 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Mon, 19 Oct 2009 15:04:10 +0400 Subject: [PATCH] Move most client update data functions to object itself from ObjectAccessor. Also use virtual function BuildUpdateData (old ObjectAccessor::_buildUpdateObject) that different for world objects and items. (backported from commit a94d615) Signed-off-by: VladimirMangos --- src/game/Item.cpp | 8 ++++++ src/game/Item.h | 1 + src/game/Object.cpp | 57 +++++++++++++++++++++++++++++++++---- src/game/Object.h | 16 ++++++++--- src/game/ObjectAccessor.cpp | 54 +---------------------------------- src/game/ObjectAccessor.h | 15 ---------- 6 files changed, 73 insertions(+), 78 deletions(-) diff --git a/src/game/Item.cpp b/src/game/Item.cpp index 5f680ca5496..1171e17a2da 100644 --- a/src/game/Item.cpp +++ b/src/game/Item.cpp @@ -955,6 +955,14 @@ bool Item::IsBindedNotWith( Player const* player ) const return true; } +void Item::BuildUpdateData(UpdateDataMapType& update_players) +{ + if (Player* pl = GetOwner()) + BuildUpdateDataForPlayer(pl, update_players); + + ClearUpdateMask(false); +} + bool ItemRequiredTarget::IsFitToRequirements( Unit* pUnitTarget ) const { if(pUnitTarget->GetTypeId() != TYPEID_UNIT) diff --git a/src/game/Item.h b/src/game/Item.h index e42a08b4855..9f8fb31268a 100644 --- a/src/game/Item.h +++ b/src/game/Item.h @@ -307,6 +307,7 @@ class MANGOS_DLL_SPEC Item : public Object bool IsPotion() const { return GetProto()->IsPotion(); } bool IsConjuredConsumable() const { return GetProto()->IsConjuredConsumable(); } + void BuildUpdateData(UpdateDataMapType& update_players); private: uint8 m_slot; Bag *m_container; diff --git a/src/game/Object.cpp b/src/game/Object.cpp index ab403701800..f94f33a1fac 100644 --- a/src/game/Object.cpp +++ b/src/game/Object.cpp @@ -127,7 +127,7 @@ void Object::BuildMovementUpdateBlock(UpdateData * data, uint32 flags ) const buf << uint8( UPDATETYPE_MOVEMENT ); buf << GetGUID(); - _BuildMovementUpdate(&buf, flags, 0x00000000); + BuildMovementUpdate(&buf, flags, 0x00000000); data->AddUpdateBlock(buf); } @@ -183,12 +183,12 @@ void Object::BuildCreateUpdateBlockForPlayer(UpdateData *data, Player *target) c buf << (uint8)0xFF << GetGUID(); buf << (uint8)m_objectTypeId; - _BuildMovementUpdate(&buf, flags, flags2); + BuildMovementUpdate(&buf, flags, flags2); UpdateMask updateMask; updateMask.SetCount( m_valuesCount ); _SetCreateBits( &updateMask, target ); - _BuildValuesUpdate(updatetype, &buf, &updateMask, target); + BuildValuesUpdate(updatetype, &buf, &updateMask, target); data->AddUpdateBlock(buf); } @@ -216,7 +216,7 @@ void Object::BuildValuesUpdateBlockForPlayer(UpdateData *data, Player *target) c updateMask.SetCount( m_valuesCount ); _SetUpdateBits( &updateMask, target ); - _BuildValuesUpdate(UPDATETYPE_VALUES, &buf, &updateMask, target); + BuildValuesUpdate(UPDATETYPE_VALUES, &buf, &updateMask, target); data->AddUpdateBlock(buf); } @@ -235,7 +235,7 @@ void Object::DestroyForPlayer( Player *target ) const target->GetSession()->SendPacket( &data ); } -void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2) const +void Object::BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2) const { *data << (uint8)flags; // update flags @@ -506,7 +506,7 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2) } } -void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask *updateMask, Player *target) const +void Object::BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask *updateMask, Player *target) const { if(!target) return; @@ -989,6 +989,20 @@ bool Object::PrintIndexError(uint32 index, bool set) const return false; } +void Object::BuildUpdateDataForPlayer(Player* pl, UpdateDataMapType& update_players) +{ + UpdateDataMapType::iterator iter = update_players.find(pl); + + if (iter == update_players.end()) + { + std::pair p = update_players.insert( UpdateDataMapType::value_type(pl, UpdateData()) ); + assert(p.second); + iter = p.first; + } + + BuildValuesUpdateBlockForPlayer(&iter->second, iter->first); +} + WorldObject::WorldObject() : m_mapId(0), m_InstanceId(0), m_positionX(0.0f), m_positionY(0.0f), m_positionZ(0.0f), m_orientation(0.0f) @@ -1773,3 +1787,34 @@ void WorldObject::UpdateObjectVisibility() GetMap()->UpdateObjectVisibility(this, cell, p); } + +struct WorldObjectChangeAccumulator +{ + UpdateDataMapType &i_updateDatas; + WorldObject &i_object; + WorldObjectChangeAccumulator(WorldObject &obj, UpdateDataMapType &d) : i_updateDatas(d), i_object(obj) {} + void Visit(PlayerMapType &m) + { + for(PlayerMapType::iterator iter = m.begin(); iter != m.end(); ++iter) + if(iter->getSource()->HaveAtClient(&i_object)) + i_object.BuildUpdateDataForPlayer(iter->getSource(), i_updateDatas); + } + + template void Visit(GridRefManager &) {} +}; + +void WorldObject::BuildUpdateData( UpdateDataMapType & update_players) +{ + CellPair p = MaNGOS::ComputeCellPair(GetPositionX(), GetPositionY()); + Cell cell(p); + cell.data.Part.reserved = ALL_DISTRICT; + cell.SetNoCreate(); + WorldObjectChangeAccumulator notifier(*this, update_players); + TypeContainerVisitor player_notifier(notifier); + CellLock cell_lock(cell, p); + Map* aMap = GetMap(); + //we must build packets for all visible players + cell_lock->Visit(cell_lock, player_notifier, *aMap, *this, aMap->GetVisibilityDistance()); + + ClearUpdateMask(false); +} diff --git a/src/game/Object.h b/src/game/Object.h index 36d6ec1e5ae..dc538e45cc9 100644 --- a/src/game/Object.h +++ b/src/game/Object.h @@ -142,6 +142,7 @@ class MANGOS_DLL_SPEC Object virtual void BuildCreateUpdateBlockForPlayer( UpdateData *data, Player *target ) const; void SendCreateUpdateToPlayer(Player* player); + virtual void BuildUpdateData(UpdateDataMapType& update_players) =0; void BuildValuesUpdateBlockForPlayer( UpdateData *data, Player *target ) const; void BuildOutOfRangeUpdateBlock( UpdateData *data ) const; void BuildMovementUpdateBlock( UpdateData * data, uint32 flags = 0 ) const; @@ -301,8 +302,9 @@ 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, uint8 flags, uint32 flags2 ) const; - void _BuildValuesUpdate(uint8 updatetype, ByteBuffer *data, UpdateMask *updateMask, Player *target ) const; + void BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2 ) const; + void BuildValuesUpdate(uint8 updatetype, ByteBuffer *data, UpdateMask *updateMask, Player *target ) const; + void BuildUpdateDataForPlayer(Player* pl, UpdateDataMapType& update_players); uint16 m_objectType; @@ -333,8 +335,12 @@ class MANGOS_DLL_SPEC Object Object& operator=(Object const&); // prevent generation assigment operator }; +struct WorldObjectChangeAccumulator; + class MANGOS_DLL_SPEC WorldObject : public Object { + friend struct WorldObjectChangeAccumulator; + public: virtual ~WorldObject ( ) {} @@ -477,12 +483,14 @@ class MANGOS_DLL_SPEC WorldObject : public Object Map * GetMap() const; Map const* GetBaseMap() const; - Creature* SummonCreature(uint32 id, float x, float y, float z, float ang,TempSummonType spwtype,uint32 despwtime); + void BuildUpdateData(UpdateDataMapType &); + + Creature* SummonCreature(uint32 id, float x, float y, float z, float ang,TempSummonType spwtype,uint32 despwtime); protected: explicit WorldObject(); - std::string m_name; + std::string m_name; private: uint32 m_mapId; // object at map with map_id uint32 m_InstanceId; // in map copy with instance id diff --git a/src/game/ObjectAccessor.cpp b/src/game/ObjectAccessor.cpp index 3bd8c7457c2..6217c012aae 100644 --- a/src/game/ObjectAccessor.cpp +++ b/src/game/ObjectAccessor.cpp @@ -169,49 +169,6 @@ ObjectAccessor::SaveAllPlayers() itr->second->SaveToDB(); } -void -ObjectAccessor::_buildUpdateObject(Object *obj, UpdateDataMapType &update_players) -{ - if(obj->isType(TYPEMASK_ITEM)) - { - Item *item = static_cast(obj); - if (Player* pl = item->GetOwner()) - _buildPacket(pl, obj, update_players); - } - else - _buildChangeObjectForPlayer(static_cast(obj), update_players); -} - -void -ObjectAccessor::_buildPacket(Player *pl, Object *obj, UpdateDataMapType &update_players) -{ - UpdateDataMapType::iterator iter = update_players.find(pl); - - if( iter == update_players.end() ) - { - std::pair p = update_players.insert( UpdateDataValueType(pl, UpdateData()) ); - assert(p.second); - iter = p.first; - } - - obj->BuildValuesUpdateBlockForPlayer(&iter->second, iter->first); -} - -void -ObjectAccessor::_buildChangeObjectForPlayer(WorldObject *obj, UpdateDataMapType &update_players) -{ - CellPair p = MaNGOS::ComputeCellPair(obj->GetPositionX(), obj->GetPositionY()); - Cell cell(p); - cell.data.Part.reserved = ALL_DISTRICT; - cell.SetNoCreate(); - WorldObjectChangeAccumulator notifier(*obj, update_players); - TypeContainerVisitor player_notifier(notifier); - CellLock cell_lock(cell, p); - Map& map = *obj->GetMap(); - //we must build packets for all visible players - cell_lock->Visit(cell_lock, player_notifier, map, *obj, map.GetVisibilityDistance()); -} - Pet* ObjectAccessor::GetPet(uint64 guid) { @@ -367,8 +324,7 @@ ObjectAccessor::Update(uint32 diff) i_objects.erase(i_objects.begin()); if (!obj) continue; - _buildUpdateObject(obj, update_players); - obj->ClearUpdateMask(false); + obj->BuildUpdateData(update_players); } } @@ -381,14 +337,6 @@ ObjectAccessor::Update(uint32 diff) } } -void -ObjectAccessor::WorldObjectChangeAccumulator::Visit(PlayerMapType &m) -{ - for(PlayerMapType::iterator iter = m.begin(); iter != m.end(); ++iter) - if(iter->getSource()->HaveAtClient(&i_object)) - ObjectAccessor::_buildPacket(iter->getSource(), &i_object, i_updateDatas); -} - /// Define the static member of HashMapHolder template UNORDERED_MAP< uint64, T* > HashMapHolder::m_objectMap; diff --git a/src/game/ObjectAccessor.h b/src/game/ObjectAccessor.h index 307f96666e4..8a6b0570456 100644 --- a/src/game/ObjectAccessor.h +++ b/src/game/ObjectAccessor.h @@ -87,7 +87,6 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton Player2CorpsesMapType; - typedef UNORDERED_MAP::value_type UpdateDataValueType; template static T* GetObjectInWorld(uint64 guid, T* /*fake*/) { @@ -191,26 +190,12 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton void Visit(GridRefManager &) {} - }; - - friend struct WorldObjectChangeAccumulator; Player2CorpsesMapType i_player2corpse; typedef ACE_Thread_Mutex LockType; typedef MaNGOS::GeneralLock Guard; - static void _buildChangeObjectForPlayer(WorldObject *, UpdateDataMapType &); - static void _buildPacket(Player *, Object *, UpdateDataMapType &); std::set i_objects; LockType i_playerGuard; LockType i_updateGuard;