mirror of
https://github.com/mangosfour/server.git
synced 2025-12-12 10:37:03 +00:00
[8653] Implemented per map guids store.
This patch implements storing guid->object pairs on per map level, this leads to less locking in ObjectAccessor in case of further multithreaded map update. For case of cross map guid looking (auras cases) all maps are linked into ObjectAccessor and can be traversed for this lookup. Signed-off-by: ApoC <apoc@nymfe.net>
This commit is contained in:
parent
40b0612dfc
commit
45c9c136ba
18 changed files with 272 additions and 116 deletions
|
|
@ -28,8 +28,114 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "Platform/Define.h"
|
#include "Platform/Define.h"
|
||||||
#include "Utilities/TypeList.h"
|
#include "Utilities/TypeList.h"
|
||||||
|
#include "Utilities/UnorderedMap.h"
|
||||||
#include "GameSystem/GridRefManager.h"
|
#include "GameSystem/GridRefManager.h"
|
||||||
|
|
||||||
|
template<class OBJECT, class KEY_TYPE> struct ContainerUnorderedMap
|
||||||
|
{
|
||||||
|
UNORDERED_MAP<KEY_TYPE, OBJECT*> _element;
|
||||||
|
};
|
||||||
|
template<class KEY_TYPE> struct ContainerUnorderedMap<TypeNull, KEY_TYPE>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
template<class H, class T, class KEY_TYPE> struct ContainerUnorderedMap< TypeList<H, T>, KEY_TYPE >
|
||||||
|
{
|
||||||
|
ContainerUnorderedMap<H, KEY_TYPE> _elements;
|
||||||
|
ContainerUnorderedMap<T, KEY_TYPE> _TailElements;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class OBJECT_TYPES, class KEY_TYPE = OBJECT_HANDLE>
|
||||||
|
class TypeUnorderedMapContainer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
template<class SPECIFIC_TYPE> bool insert(KEY_TYPE handle, SPECIFIC_TYPE* obj)
|
||||||
|
{
|
||||||
|
return TypeUnorderedMapContainer::insert(i_elements, handle, obj);
|
||||||
|
}
|
||||||
|
template<class SPECIFIC_TYPE> bool erase(KEY_TYPE handle, SPECIFIC_TYPE* /*obj*/)
|
||||||
|
{
|
||||||
|
return TypeUnorderedMapContainer::erase(i_elements, handle, (SPECIFIC_TYPE*)NULL);
|
||||||
|
}
|
||||||
|
template<class SPECIFIC_TYPE> SPECIFIC_TYPE* find(KEY_TYPE hdl, SPECIFIC_TYPE* /*obj*/)
|
||||||
|
{
|
||||||
|
return TypeUnorderedMapContainer::find(i_elements, hdl, (SPECIFIC_TYPE*)NULL);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
ContainerUnorderedMap<OBJECT_TYPES, KEY_TYPE> i_elements;
|
||||||
|
|
||||||
|
// Helpers
|
||||||
|
// Insert helpers
|
||||||
|
template<class SPECIFIC_TYPE> static bool insert(ContainerUnorderedMap<SPECIFIC_TYPE, KEY_TYPE>& elements, KEY_TYPE handle, SPECIFIC_TYPE* obj)
|
||||||
|
{
|
||||||
|
typename UNORDERED_MAP<OBJECT_HANDLE, SPECIFIC_TYPE*>::iterator i = elements._element.find(handle);
|
||||||
|
if (i == elements._element.end())
|
||||||
|
{
|
||||||
|
elements._element[handle] = obj;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert (i->second == obj && "Object with certain key already in but objects are different!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
template<class SPECIFIC_TYPE> static bool insert(ContainerUnorderedMap<TypeNull, KEY_TYPE>& /*elements*/, KEY_TYPE /*handle*/, SPECIFIC_TYPE* /*obj*/)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
template<class SPECIFIC_TYPE, class T> static bool insert(ContainerUnorderedMap<T, KEY_TYPE>& /*elements*/, KEY_TYPE /*handle*/, SPECIFIC_TYPE* /*obj*/)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
template<class SPECIFIC_TYPE, class H, class T> static bool insert(ContainerUnorderedMap< TypeList<H, T>, KEY_TYPE >& elements, KEY_TYPE handle, SPECIFIC_TYPE* obj)
|
||||||
|
{
|
||||||
|
bool ret = TypeUnorderedMapContainer::insert(elements._elements, handle, obj);
|
||||||
|
return ret ? ret : TypeUnorderedMapContainer::insert(elements._TailElements, handle, obj);
|
||||||
|
}
|
||||||
|
// Find helpers
|
||||||
|
template<class SPECIFIC_TYPE> static SPECIFIC_TYPE* find(ContainerUnorderedMap<SPECIFIC_TYPE, KEY_TYPE>& elements, KEY_TYPE hdl, SPECIFIC_TYPE* /*obj*/)
|
||||||
|
{
|
||||||
|
typename UNORDERED_MAP<OBJECT_HANDLE, SPECIFIC_TYPE*>::iterator i = elements._element.find(hdl);
|
||||||
|
if (i == elements._element.end())
|
||||||
|
return NULL;
|
||||||
|
else
|
||||||
|
return i->second;
|
||||||
|
}
|
||||||
|
template<class SPECIFIC_TYPE> static SPECIFIC_TYPE* find(ContainerUnorderedMap<TypeNull, KEY_TYPE>& /*elements*/, KEY_TYPE /*hdl*/, SPECIFIC_TYPE* /*obj*/)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
template<class SPECIFIC_TYPE, class T> static SPECIFIC_TYPE* find(ContainerUnorderedMap<T, KEY_TYPE>& /*elements*/, KEY_TYPE /*hdl*/, SPECIFIC_TYPE* /*obj*/)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
template<class SPECIFIC_TYPE, class H, class T> static SPECIFIC_TYPE* find(ContainerUnorderedMap< TypeList<H, T>, KEY_TYPE >& elements, KEY_TYPE hdl, SPECIFIC_TYPE* /*obj*/)
|
||||||
|
{
|
||||||
|
SPECIFIC_TYPE* ret = TypeUnorderedMapContainer::find(elements._elements, hdl, (SPECIFIC_TYPE*)NULL);
|
||||||
|
return ret ? ret : TypeUnorderedMapContainer::find(elements._TailElements, hdl, (SPECIFIC_TYPE*)NULL);
|
||||||
|
}
|
||||||
|
// Erase helpers
|
||||||
|
template<class SPECIFIC_TYPE> static bool erase(ContainerUnorderedMap<SPECIFIC_TYPE, KEY_TYPE>& elements, KEY_TYPE handle, SPECIFIC_TYPE* /*obj*/)
|
||||||
|
{
|
||||||
|
elements._element.erase(handle);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
template<class SPECIFIC_TYPE> static bool erase(ContainerUnorderedMap<TypeNull, KEY_TYPE>& /*elements*/, KEY_TYPE /*handle*/, SPECIFIC_TYPE* /*obj*/)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
template<class SPECIFIC_TYPE, class T> static bool erase(ContainerUnorderedMap<T, KEY_TYPE>& /*elements*/, KEY_TYPE /*handle*/, SPECIFIC_TYPE* /*obj*/)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
template<class SPECIFIC_TYPE, class H, class T> static bool erase(ContainerUnorderedMap< TypeList<H, T>, KEY_TYPE >& elements, KEY_TYPE handle, SPECIFIC_TYPE* /*obj*/)
|
||||||
|
{
|
||||||
|
bool ret = TypeUnorderedMapContainer::erase(elements._elements, handle, (SPECIFIC_TYPE*)NULL);
|
||||||
|
return ret ? ret : TypeUnorderedMapContainer::erase(elements._TailElements, handle, (SPECIFIC_TYPE*)NULL);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @class ContainerMapList is a mulit-type container for map elements
|
* @class ContainerMapList is a mulit-type container for map elements
|
||||||
* By itself its meaningless but collaborate along with TypeContainers,
|
* By itself its meaningless but collaborate along with TypeContainers,
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@
|
||||||
#include "Language.h"
|
#include "Language.h"
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
#include "WorldPacket.h"
|
#include "WorldPacket.h"
|
||||||
|
#include "MapManager.h"
|
||||||
|
|
||||||
BattleGroundAB::BattleGroundAB()
|
BattleGroundAB::BattleGroundAB()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@
|
||||||
#include "Language.h"
|
#include "Language.h"
|
||||||
#include "WorldPacket.h"
|
#include "WorldPacket.h"
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
|
#include "MapManager.h"
|
||||||
|
|
||||||
BattleGroundEY::BattleGroundEY()
|
BattleGroundEY::BattleGroundEY()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@
|
||||||
#include "BattleGroundMgr.h"
|
#include "BattleGroundMgr.h"
|
||||||
#include "WorldPacket.h"
|
#include "WorldPacket.h"
|
||||||
#include "Language.h"
|
#include "Language.h"
|
||||||
|
#include "MapManager.h"
|
||||||
|
|
||||||
BattleGroundWS::BattleGroundWS()
|
BattleGroundWS::BattleGroundWS()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -141,14 +141,18 @@ Creature::~Creature()
|
||||||
void Creature::AddToWorld()
|
void Creature::AddToWorld()
|
||||||
{
|
{
|
||||||
///- Register the creature for guid lookup
|
///- Register the creature for guid lookup
|
||||||
if(!IsInWorld()) ObjectAccessor::Instance().AddObject(this);
|
if(!IsInWorld())
|
||||||
|
GetMap()->GetObjectsStore().insert<Creature>(GetGUID(), (Creature*)this);
|
||||||
|
|
||||||
Unit::AddToWorld();
|
Unit::AddToWorld();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Creature::RemoveFromWorld()
|
void Creature::RemoveFromWorld()
|
||||||
{
|
{
|
||||||
///- Remove the creature from the accessor
|
///- Remove the creature from the accessor
|
||||||
if(IsInWorld()) ObjectAccessor::Instance().RemoveObject(this);
|
if(IsInWorld())
|
||||||
|
GetMap()->GetObjectsStore().erase<Creature>(GetGUID(), (Creature*)NULL);
|
||||||
|
|
||||||
Unit::RemoveFromWorld();
|
Unit::RemoveFromWorld();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ void DynamicObject::AddToWorld()
|
||||||
{
|
{
|
||||||
///- Register the dynamicObject for guid lookup
|
///- Register the dynamicObject for guid lookup
|
||||||
if(!IsInWorld())
|
if(!IsInWorld())
|
||||||
ObjectAccessor::Instance().AddObject(this);
|
GetMap()->GetObjectsStore().insert<DynamicObject>(GetGUID(), (DynamicObject*)this);
|
||||||
|
|
||||||
Object::AddToWorld();
|
Object::AddToWorld();
|
||||||
}
|
}
|
||||||
|
|
@ -50,7 +50,7 @@ void DynamicObject::RemoveFromWorld()
|
||||||
{
|
{
|
||||||
///- Remove the dynamicObject from the accessor
|
///- Remove the dynamicObject from the accessor
|
||||||
if(IsInWorld())
|
if(IsInWorld())
|
||||||
ObjectAccessor::Instance().RemoveObject(this);
|
GetMap()->GetObjectsStore().erase<DynamicObject>(GetGUID(), (DynamicObject*)NULL);
|
||||||
|
|
||||||
Object::RemoveFromWorld();
|
Object::RemoveFromWorld();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -60,23 +60,26 @@ GameObject::GameObject() : WorldObject()
|
||||||
|
|
||||||
GameObject::~GameObject()
|
GameObject::~GameObject()
|
||||||
{
|
{
|
||||||
CleanupsBeforeDelete();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameObject::CleanupsBeforeDelete()
|
void GameObject::AddToWorld()
|
||||||
{
|
{
|
||||||
if(m_uint32Values) // field array can be not exist if GameOBject not loaded
|
///- Register the gameobject for guid lookup
|
||||||
|
if(!IsInWorld())
|
||||||
|
GetMap()->GetObjectsStore().insert<GameObject>(GetGUID(), (GameObject*)this);
|
||||||
|
|
||||||
|
Object::AddToWorld();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameObject::RemoveFromWorld()
|
||||||
{
|
{
|
||||||
// Possible crash at access to deleted GO in Unit::m_gameobj
|
///- Remove the gameobject from the accessor
|
||||||
|
if(IsInWorld())
|
||||||
|
{
|
||||||
|
// Remove GO from owner
|
||||||
if(uint64 owner_guid = GetOwnerGUID())
|
if(uint64 owner_guid = GetOwnerGUID())
|
||||||
{
|
{
|
||||||
Unit* owner = NULL;
|
if (Unit* owner = IS_PLAYER_GUID(owner_guid) ? ObjectAccessor::FindPlayer(owner_guid) : GetMap()->GetCreatureOrPet(owner_guid))
|
||||||
if(IS_PLAYER_GUID(owner_guid))
|
|
||||||
owner = ObjectAccessor::GetObjectInWorld(owner_guid, (Player*)NULL);
|
|
||||||
else
|
|
||||||
owner = ObjectAccessor::GetUnit(*this,owner_guid);
|
|
||||||
|
|
||||||
if(owner)
|
|
||||||
owner->RemoveGameObject(this,false);
|
owner->RemoveGameObject(this,false);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -90,20 +93,10 @@ void GameObject::CleanupsBeforeDelete()
|
||||||
GetGUIDLow(), GetGOInfo()->id, m_spellId, GetGOInfo()->GetLinkedGameObjectEntry(), GUID_LOPART(owner_guid), ownerType);
|
GetGUIDLow(), GetGOInfo()->id, m_spellId, GetGOInfo()->GetLinkedGameObjectEntry(), GUID_LOPART(owner_guid), ownerType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
GetMap()->GetObjectsStore().erase<GameObject>(GetGUID(), (GameObject*)NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameObject::AddToWorld()
|
|
||||||
{
|
|
||||||
///- Register the gameobject for guid lookup
|
|
||||||
if(!IsInWorld()) ObjectAccessor::Instance().AddObject(this);
|
|
||||||
Object::AddToWorld();
|
|
||||||
}
|
|
||||||
|
|
||||||
void GameObject::RemoveFromWorld()
|
|
||||||
{
|
|
||||||
///- Remove the gameobject from the accessor
|
|
||||||
if(IsInWorld()) ObjectAccessor::Instance().RemoveObject(this);
|
|
||||||
Object::RemoveFromWorld();
|
Object::RemoveFromWorld();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -559,7 +559,6 @@ class MANGOS_DLL_SPEC GameObject : public WorldObject
|
||||||
|
|
||||||
void AddToWorld();
|
void AddToWorld();
|
||||||
void RemoveFromWorld();
|
void RemoveFromWorld();
|
||||||
void CleanupsBeforeDelete();
|
|
||||||
|
|
||||||
bool Create(uint32 guidlow, uint32 name_id, Map *map, uint32 phaseMask, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 animprogress, GOState go_state);
|
bool Create(uint32 guidlow, uint32 name_id, Map *map, uint32 phaseMask, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 animprogress, GOState go_state);
|
||||||
void Update(uint32 p_time);
|
void Update(uint32 p_time);
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@
|
||||||
// Forward class definitions
|
// Forward class definitions
|
||||||
class Corpse;
|
class Corpse;
|
||||||
class Creature;
|
class Creature;
|
||||||
|
class Vehicle;
|
||||||
class DynamicObject;
|
class DynamicObject;
|
||||||
class GameObject;
|
class GameObject;
|
||||||
class Pet;
|
class Pet;
|
||||||
|
|
@ -57,6 +58,7 @@ class Player;
|
||||||
// Creature used instead pet to simplify *::Visit templates (not required duplicate code for Creature->Pet case)
|
// Creature used instead pet to simplify *::Visit templates (not required duplicate code for Creature->Pet case)
|
||||||
typedef TYPELIST_3(Player, Creature/*pets*/, Corpse/*resurrectable*/) AllWorldObjectTypes;
|
typedef TYPELIST_3(Player, Creature/*pets*/, Corpse/*resurrectable*/) AllWorldObjectTypes;
|
||||||
typedef TYPELIST_4(GameObject, Creature/*except pets*/, DynamicObject, Corpse/*Bones*/) AllGridObjectTypes;
|
typedef TYPELIST_4(GameObject, Creature/*except pets*/, DynamicObject, Corpse/*Bones*/) AllGridObjectTypes;
|
||||||
|
typedef TYPELIST_5(Creature, Pet, Vehicle, GameObject, DynamicObject) AllMapStoredObjectTypes;
|
||||||
|
|
||||||
typedef GridRefManager<Corpse> CorpseMapType;
|
typedef GridRefManager<Corpse> CorpseMapType;
|
||||||
typedef GridRefManager<Creature> CreatureMapType;
|
typedef GridRefManager<Creature> CreatureMapType;
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,7 @@ struct ScriptAction
|
||||||
|
|
||||||
Map::~Map()
|
Map::~Map()
|
||||||
{
|
{
|
||||||
|
ObjectAccessor::DelinkMap(this);
|
||||||
UnloadAll(true);
|
UnloadAll(true);
|
||||||
|
|
||||||
if(!m_scriptSchedule.empty())
|
if(!m_scriptSchedule.empty())
|
||||||
|
|
@ -212,6 +213,7 @@ Map::Map(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode, Map* _par
|
||||||
setNGrid(NULL, idx, j);
|
setNGrid(NULL, idx, j);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ObjectAccessor::LinkMap(this);
|
||||||
|
|
||||||
//lets initialize visibility distance for map
|
//lets initialize visibility distance for map
|
||||||
Map::InitVisibilityDistance();
|
Map::InitVisibilityDistance();
|
||||||
|
|
@ -2761,19 +2763,19 @@ void Map::ScriptsProcess()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case HIGHGUID_UNIT:
|
case HIGHGUID_UNIT:
|
||||||
source = HashMapHolder<Creature>::Find(step.sourceGUID);
|
source = GetCreature(step.sourceGUID);
|
||||||
break;
|
break;
|
||||||
case HIGHGUID_PET:
|
case HIGHGUID_PET:
|
||||||
source = HashMapHolder<Pet>::Find(step.sourceGUID);
|
source = GetPet(step.sourceGUID);
|
||||||
break;
|
break;
|
||||||
case HIGHGUID_VEHICLE:
|
case HIGHGUID_VEHICLE:
|
||||||
source = HashMapHolder<Vehicle>::Find(step.sourceGUID);
|
source = GetVehicle(step.sourceGUID);
|
||||||
break;
|
break;
|
||||||
case HIGHGUID_PLAYER:
|
case HIGHGUID_PLAYER:
|
||||||
source = HashMapHolder<Player>::Find(step.sourceGUID);
|
source = HashMapHolder<Player>::Find(step.sourceGUID);
|
||||||
break;
|
break;
|
||||||
case HIGHGUID_GAMEOBJECT:
|
case HIGHGUID_GAMEOBJECT:
|
||||||
source = HashMapHolder<GameObject>::Find(step.sourceGUID);
|
source = GetGameObject(step.sourceGUID);
|
||||||
break;
|
break;
|
||||||
case HIGHGUID_CORPSE:
|
case HIGHGUID_CORPSE:
|
||||||
source = HashMapHolder<Corpse>::Find(step.sourceGUID);
|
source = HashMapHolder<Corpse>::Find(step.sourceGUID);
|
||||||
|
|
@ -2793,19 +2795,19 @@ void Map::ScriptsProcess()
|
||||||
switch(GUID_HIPART(step.targetGUID))
|
switch(GUID_HIPART(step.targetGUID))
|
||||||
{
|
{
|
||||||
case HIGHGUID_UNIT:
|
case HIGHGUID_UNIT:
|
||||||
target = HashMapHolder<Creature>::Find(step.targetGUID);
|
target = GetCreature(step.targetGUID);
|
||||||
break;
|
break;
|
||||||
case HIGHGUID_PET:
|
case HIGHGUID_PET:
|
||||||
target = HashMapHolder<Pet>::Find(step.targetGUID);
|
target = GetPet(step.targetGUID);
|
||||||
break;
|
break;
|
||||||
case HIGHGUID_VEHICLE:
|
case HIGHGUID_VEHICLE:
|
||||||
target = HashMapHolder<Vehicle>::Find(step.targetGUID);
|
target = GetVehicle(step.targetGUID);
|
||||||
break;
|
break;
|
||||||
case HIGHGUID_PLAYER: // empty GUID case also
|
case HIGHGUID_PLAYER: // empty GUID case also
|
||||||
target = HashMapHolder<Player>::Find(step.targetGUID);
|
target = HashMapHolder<Player>::Find(step.targetGUID);
|
||||||
break;
|
break;
|
||||||
case HIGHGUID_GAMEOBJECT:
|
case HIGHGUID_GAMEOBJECT:
|
||||||
target = HashMapHolder<GameObject>::Find(step.targetGUID);
|
target = GetGameObject(step.targetGUID);
|
||||||
break;
|
break;
|
||||||
case HIGHGUID_CORPSE:
|
case HIGHGUID_CORPSE:
|
||||||
target = HashMapHolder<Corpse>::Find(step.targetGUID);
|
target = HashMapHolder<Corpse>::Find(step.targetGUID);
|
||||||
|
|
@ -3381,44 +3383,35 @@ void Map::ScriptsProcess()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Creature*
|
Creature* Map::GetCreature(uint64 guid)
|
||||||
Map::GetCreature(uint64 guid)
|
|
||||||
{
|
{
|
||||||
Creature * ret = ObjectAccessor::GetObjectInWorld(guid, (Creature*)NULL);
|
return m_objectsStore.find<Creature>(guid, (Creature*)NULL);
|
||||||
if(!ret)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if(ret->GetMapId() != GetId())
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if(ret->GetInstanceId() != GetInstanceId())
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GameObject*
|
Vehicle* Map::GetVehicle(uint64 guid)
|
||||||
Map::GetGameObject(uint64 guid)
|
|
||||||
{
|
{
|
||||||
GameObject * ret = ObjectAccessor::GetObjectInWorld(guid, (GameObject*)NULL);
|
return m_objectsStore.find<Vehicle>(guid, (Vehicle*)NULL);
|
||||||
if(!ret)
|
|
||||||
return NULL;
|
|
||||||
if(ret->GetMapId() != GetId())
|
|
||||||
return NULL;
|
|
||||||
if(ret->GetInstanceId() != GetInstanceId())
|
|
||||||
return NULL;
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DynamicObject*
|
Pet* Map::GetPet(uint64 guid)
|
||||||
Map::GetDynamicObject(uint64 guid)
|
|
||||||
{
|
{
|
||||||
DynamicObject * ret = ObjectAccessor::GetObjectInWorld(guid, (DynamicObject*)NULL);
|
return m_objectsStore.find<Pet>(guid, (Pet*)NULL);
|
||||||
if(!ret)
|
}
|
||||||
return NULL;
|
|
||||||
if(ret->GetMapId() != GetId())
|
Unit* Map::GetCreatureOrPet(uint64 guid)
|
||||||
return NULL;
|
{
|
||||||
if(ret->GetInstanceId() != GetInstanceId())
|
if (Unit* ret = GetCreature(guid))
|
||||||
return NULL;
|
return ret;
|
||||||
return ret;
|
|
||||||
|
return GetPet(guid);
|
||||||
|
}
|
||||||
|
|
||||||
|
GameObject* Map::GetGameObject(uint64 guid)
|
||||||
|
{
|
||||||
|
return m_objectsStore.find<GameObject>(guid, (GameObject*)NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
DynamicObject* Map::GetDynamicObject(uint64 guid)
|
||||||
|
{
|
||||||
|
return m_objectsStore.find<DynamicObject>(guid, (DynamicObject*)NULL);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@
|
||||||
#include "SharedDefines.h"
|
#include "SharedDefines.h"
|
||||||
#include "GameSystem/GridRefManager.h"
|
#include "GameSystem/GridRefManager.h"
|
||||||
#include "MapRefManager.h"
|
#include "MapRefManager.h"
|
||||||
|
#include "Utilities/TypeList.h"
|
||||||
|
|
||||||
#include <bitset>
|
#include <bitset>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
@ -420,8 +421,13 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
|
||||||
void RemoveFromActive(Creature* obj);
|
void RemoveFromActive(Creature* obj);
|
||||||
|
|
||||||
Creature* GetCreature(uint64 guid);
|
Creature* GetCreature(uint64 guid);
|
||||||
|
Vehicle* GetVehicle(uint64 guid);
|
||||||
|
Pet* GetPet(uint64 guid);
|
||||||
|
Unit* GetCreatureOrPet(uint64 guid);
|
||||||
GameObject* GetGameObject(uint64 guid);
|
GameObject* GetGameObject(uint64 guid);
|
||||||
DynamicObject* GetDynamicObject(uint64 guid);
|
DynamicObject* GetDynamicObject(uint64 guid);
|
||||||
|
|
||||||
|
TypeUnorderedMapContainer<AllMapStoredObjectTypes>& GetObjectsStore() { return m_objectsStore; }
|
||||||
private:
|
private:
|
||||||
void LoadMapAndVMap(int gx, int gy);
|
void LoadMapAndVMap(int gx, int gy);
|
||||||
void LoadVMap(int gx, int gy);
|
void LoadVMap(int gx, int gy);
|
||||||
|
|
@ -484,6 +490,7 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
|
||||||
typedef std::set<WorldObject*> ActiveNonPlayers;
|
typedef std::set<WorldObject*> ActiveNonPlayers;
|
||||||
ActiveNonPlayers m_activeNonPlayers;
|
ActiveNonPlayers m_activeNonPlayers;
|
||||||
ActiveNonPlayers::iterator m_activeNonPlayersIter;
|
ActiveNonPlayers::iterator m_activeNonPlayersIter;
|
||||||
|
TypeUnorderedMapContainer<AllMapStoredObjectTypes> m_objectsStore;
|
||||||
private:
|
private:
|
||||||
time_t i_gridExpiry;
|
time_t i_gridExpiry;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -53,16 +53,16 @@ ObjectAccessor::~ObjectAccessor()
|
||||||
Creature*
|
Creature*
|
||||||
ObjectAccessor::GetCreatureOrPetOrVehicle(WorldObject const &u, uint64 guid)
|
ObjectAccessor::GetCreatureOrPetOrVehicle(WorldObject const &u, uint64 guid)
|
||||||
{
|
{
|
||||||
if(IS_PLAYER_GUID(guid))
|
if(IS_PLAYER_GUID(guid) || !u.IsInWorld())
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if(IS_PET_GUID(guid))
|
if(IS_PET_GUID(guid))
|
||||||
return GetPet(guid);
|
return u.GetMap()->GetPet(guid);
|
||||||
|
|
||||||
if(IS_VEHICLE_GUID(guid))
|
if(IS_VEHICLE_GUID(guid))
|
||||||
return GetVehicle(guid);
|
return u.GetMap()->GetVehicle(guid);
|
||||||
|
|
||||||
return u.IsInWorld() ? u.GetMap()->GetCreature(guid) : NULL;
|
return u.GetMap()->GetCreature(guid);
|
||||||
}
|
}
|
||||||
|
|
||||||
Unit*
|
Unit*
|
||||||
|
|
@ -97,8 +97,8 @@ WorldObject* ObjectAccessor::GetWorldObject(WorldObject const &p, uint64 guid)
|
||||||
case HIGHGUID_PLAYER: return FindPlayer(guid);
|
case HIGHGUID_PLAYER: return FindPlayer(guid);
|
||||||
case HIGHGUID_GAMEOBJECT: return p.GetMap()->GetGameObject(guid);
|
case HIGHGUID_GAMEOBJECT: return p.GetMap()->GetGameObject(guid);
|
||||||
case HIGHGUID_UNIT: return p.GetMap()->GetCreature(guid);
|
case HIGHGUID_UNIT: return p.GetMap()->GetCreature(guid);
|
||||||
case HIGHGUID_PET: return GetPet(guid);
|
case HIGHGUID_PET: return p.GetMap()->GetPet(guid);
|
||||||
case HIGHGUID_VEHICLE: return GetVehicle(guid);
|
case HIGHGUID_VEHICLE: return p.GetMap()->GetVehicle(guid);
|
||||||
case HIGHGUID_DYNAMICOBJECT:return p.GetMap()->GetDynamicObject(guid);
|
case HIGHGUID_DYNAMICOBJECT:return p.GetMap()->GetDynamicObject(guid);
|
||||||
case HIGHGUID_TRANSPORT: return NULL;
|
case HIGHGUID_TRANSPORT: return NULL;
|
||||||
case HIGHGUID_CORPSE: return GetCorpse(p,guid);
|
case HIGHGUID_CORPSE: return GetCorpse(p,guid);
|
||||||
|
|
@ -131,11 +131,11 @@ Object* ObjectAccessor::GetObjectByTypeMask(WorldObject const &p, uint64 guid, u
|
||||||
break;
|
break;
|
||||||
case HIGHGUID_PET:
|
case HIGHGUID_PET:
|
||||||
if(typemask & TYPEMASK_UNIT)
|
if(typemask & TYPEMASK_UNIT)
|
||||||
return GetPet(guid);
|
return p.GetMap()->GetPet(guid);
|
||||||
break;
|
break;
|
||||||
case HIGHGUID_VEHICLE:
|
case HIGHGUID_VEHICLE:
|
||||||
if(typemask & TYPEMASK_UNIT)
|
if(typemask & TYPEMASK_UNIT)
|
||||||
return GetVehicle(guid);
|
return p.GetMap()->GetVehicle(guid);
|
||||||
break;
|
break;
|
||||||
case HIGHGUID_DYNAMICOBJECT:
|
case HIGHGUID_DYNAMICOBJECT:
|
||||||
if(typemask & TYPEMASK_DYNAMICOBJECT)
|
if(typemask & TYPEMASK_DYNAMICOBJECT)
|
||||||
|
|
@ -416,13 +416,11 @@ template <class T> ACE_Thread_Mutex HashMapHolder<T>::i_lock;
|
||||||
/// Global definitions for the hashmap storage
|
/// Global definitions for the hashmap storage
|
||||||
|
|
||||||
template class HashMapHolder<Player>;
|
template class HashMapHolder<Player>;
|
||||||
template class HashMapHolder<Pet>;
|
|
||||||
template class HashMapHolder<Vehicle>;
|
|
||||||
template class HashMapHolder<GameObject>;
|
|
||||||
template class HashMapHolder<DynamicObject>;
|
|
||||||
template class HashMapHolder<Creature>;
|
|
||||||
template class HashMapHolder<Corpse>;
|
template class HashMapHolder<Corpse>;
|
||||||
|
|
||||||
|
/// Define the static member of ObjectAccessor
|
||||||
|
std::list<Map*> ObjectAccessor::i_mapList;
|
||||||
|
|
||||||
template Player* ObjectAccessor::GetObjectInWorld<Player>(uint32 mapid, float x, float y, uint64 guid, Player* /*fake*/);
|
template Player* ObjectAccessor::GetObjectInWorld<Player>(uint32 mapid, float x, float y, uint64 guid, Player* /*fake*/);
|
||||||
template Pet* ObjectAccessor::GetObjectInWorld<Pet>(uint32 mapid, float x, float y, uint64 guid, Pet* /*fake*/);
|
template Pet* ObjectAccessor::GetObjectInWorld<Pet>(uint32 mapid, float x, float y, uint64 guid, Pet* /*fake*/);
|
||||||
template Vehicle* ObjectAccessor::GetObjectInWorld<Vehicle>(uint32 mapid, float x, float y, uint64 guid, Vehicle* /*fake*/);
|
template Vehicle* ObjectAccessor::GetObjectInWorld<Vehicle>(uint32 mapid, float x, float y, uint64 guid, Vehicle* /*fake*/);
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@
|
||||||
#include "Player.h"
|
#include "Player.h"
|
||||||
|
|
||||||
#include <set>
|
#include <set>
|
||||||
|
#include <list>
|
||||||
|
|
||||||
class Creature;
|
class Creature;
|
||||||
class Corpse;
|
class Corpse;
|
||||||
|
|
@ -95,29 +96,9 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton<ObjectAccessor,
|
||||||
return HashMapHolder<T>::Find(guid);
|
return HashMapHolder<T>::Find(guid);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Unit* GetObjectInWorld(uint64 guid, Unit* /*fake*/)
|
|
||||||
{
|
|
||||||
if(!guid)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (IS_PLAYER_GUID(guid))
|
|
||||||
{
|
|
||||||
Unit * u = (Unit*)HashMapHolder<Player>::Find(guid);
|
|
||||||
if(!u || !u->IsInWorld())
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return u;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IS_PET_GUID(guid))
|
|
||||||
return (Unit*)HashMapHolder<Pet>::Find(guid);
|
|
||||||
|
|
||||||
return (Unit*)HashMapHolder<Creature>::Find(guid);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class T> static T* GetObjectInWorld(uint32 mapid, float x, float y, uint64 guid, T* /*fake*/)
|
template<class T> static T* GetObjectInWorld(uint32 mapid, float x, float y, uint64 guid, T* /*fake*/)
|
||||||
{
|
{
|
||||||
T* obj = HashMapHolder<T>::Find(guid);
|
T* obj = GetObjectInWorld(guid, (T*)NULL);
|
||||||
if(!obj || obj->GetMapId() != mapid) return NULL;
|
if(!obj || obj->GetMapId() != mapid) return NULL;
|
||||||
|
|
||||||
CellPair p = MaNGOS::ComputeCellPair(x,y);
|
CellPair p = MaNGOS::ComputeCellPair(x,y);
|
||||||
|
|
@ -201,6 +182,9 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton<ObjectAccessor,
|
||||||
|
|
||||||
static void _buildUpdateObject(Object* obj, UpdateDataMapType &);
|
static void _buildUpdateObject(Object* obj, UpdateDataMapType &);
|
||||||
|
|
||||||
|
// TODO: This methods will need lock in MT environment
|
||||||
|
static void LinkMap(Map* map) { i_mapList.push_back(map); }
|
||||||
|
static void DelinkMap(Map* map) { i_mapList.remove(map); }
|
||||||
private:
|
private:
|
||||||
struct WorldObjectChangeAccumulator
|
struct WorldObjectChangeAccumulator
|
||||||
{
|
{
|
||||||
|
|
@ -211,6 +195,24 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton<ObjectAccessor,
|
||||||
template<class SKIP> void Visit(GridRefManager<SKIP> &) {}
|
template<class SKIP> void Visit(GridRefManager<SKIP> &) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// TODO: This methods will need lock in MT environment
|
||||||
|
// Theoreticaly multiple threads can enter and search in this method but
|
||||||
|
// in that case linking/delinking other map should be guarded
|
||||||
|
template <class OBJECT> static OBJECT* FindHelper(uint64 guid)
|
||||||
|
{
|
||||||
|
OBJECT* ret = NULL;
|
||||||
|
std::list<Map*>::const_iterator i = i_mapList.begin();
|
||||||
|
while (i != i_mapList.end() && !ret)
|
||||||
|
{
|
||||||
|
ret = (*i)->GetObjectsStore().find<OBJECT>(guid, (OBJECT*)NULL);
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::list<Map*> i_mapList;
|
||||||
|
|
||||||
friend struct WorldObjectChangeAccumulator;
|
friend struct WorldObjectChangeAccumulator;
|
||||||
Player2CorpsesMapType i_player2corpse;
|
Player2CorpsesMapType i_player2corpse;
|
||||||
|
|
||||||
|
|
@ -223,6 +225,52 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton<ObjectAccessor,
|
||||||
LockType i_playerGuard;
|
LockType i_playerGuard;
|
||||||
LockType i_updateGuard;
|
LockType i_updateGuard;
|
||||||
LockType i_corpseGuard;
|
LockType i_corpseGuard;
|
||||||
LockType i_petGuard;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Out of class template specializations
|
||||||
|
template <> static inline Creature* ObjectAccessor::GetObjectInWorld(uint64 guid, Creature* /*fake*/)
|
||||||
|
{
|
||||||
|
return FindHelper<Creature>(guid);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <> static inline GameObject* ObjectAccessor::GetObjectInWorld(uint64 guid, GameObject* /*fake*/)
|
||||||
|
{
|
||||||
|
return FindHelper<GameObject>(guid);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <> static inline DynamicObject* ObjectAccessor::GetObjectInWorld(uint64 guid, DynamicObject* /*fake*/)
|
||||||
|
{
|
||||||
|
return FindHelper<DynamicObject>(guid);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <> static inline Pet* ObjectAccessor::GetObjectInWorld(uint64 guid, Pet* /*fake*/)
|
||||||
|
{
|
||||||
|
return FindHelper<Pet>(guid);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <> static inline Vehicle* ObjectAccessor::GetObjectInWorld(uint64 guid, Vehicle* /*fake*/)
|
||||||
|
{
|
||||||
|
return FindHelper<Vehicle>(guid);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <> static inline Unit* ObjectAccessor::GetObjectInWorld(uint64 guid, Unit* /*fake*/)
|
||||||
|
{
|
||||||
|
if(!guid)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (IS_PLAYER_GUID(guid))
|
||||||
|
{
|
||||||
|
Unit * u = (Unit*)HashMapHolder<Player>::Find(guid);
|
||||||
|
if(!u || !u->IsInWorld())
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return u;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IS_PET_GUID(guid))
|
||||||
|
return (Unit*)GetObjectInWorld<Pet>(guid, (Pet*)NULL);
|
||||||
|
|
||||||
|
return (Unit*)GetObjectInWorld<Creature>(guid, (Creature*)NULL);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -57,23 +57,24 @@ m_declinedname(NULL)
|
||||||
|
|
||||||
Pet::~Pet()
|
Pet::~Pet()
|
||||||
{
|
{
|
||||||
if(m_uint32Values) // only for fully created Object
|
|
||||||
ObjectAccessor::Instance().RemoveObject(this);
|
|
||||||
|
|
||||||
delete m_declinedname;
|
delete m_declinedname;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pet::AddToWorld()
|
void Pet::AddToWorld()
|
||||||
{
|
{
|
||||||
///- Register the pet for guid lookup
|
///- Register the pet for guid lookup
|
||||||
if(!IsInWorld()) ObjectAccessor::Instance().AddObject(this);
|
if(!IsInWorld())
|
||||||
|
GetMap()->GetObjectsStore().insert<Pet>(GetGUID(), (Pet*)this);
|
||||||
|
|
||||||
Unit::AddToWorld();
|
Unit::AddToWorld();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pet::RemoveFromWorld()
|
void Pet::RemoveFromWorld()
|
||||||
{
|
{
|
||||||
///- Remove the pet from the accessor
|
///- Remove the pet from the accessor
|
||||||
if(IsInWorld()) ObjectAccessor::Instance().RemoveObject(this);
|
if(IsInWorld())
|
||||||
|
GetMap()->GetObjectsStore().erase<Pet>(GetGUID(), (Pet*)NULL);
|
||||||
|
|
||||||
///- Don't call the function for Creature, normal mobs + totems go in a different storage
|
///- Don't call the function for Creature, normal mobs + totems go in a different storage
|
||||||
Unit::RemoveFromWorld();
|
Unit::RemoveFromWorld();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18821,7 +18821,7 @@ void Player::UpdateForQuestWorldObjects()
|
||||||
{
|
{
|
||||||
if(IS_GAMEOBJECT_GUID(*itr))
|
if(IS_GAMEOBJECT_GUID(*itr))
|
||||||
{
|
{
|
||||||
GameObject *obj = HashMapHolder<GameObject>::Find(*itr);
|
GameObject *obj = GetMap()->GetGameObject(*itr);
|
||||||
if(obj)
|
if(obj)
|
||||||
obj->BuildValuesUpdateBlockForPlayer(&udata,this);
|
obj->BuildValuesUpdateBlockForPlayer(&udata,this);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11736,7 +11736,7 @@ void Unit::SetFeared(bool apply, uint64 const& casterGUID, uint32 spellID, uint3
|
||||||
GetMotionMaster()->Initialize();
|
GetMotionMaster()->Initialize();
|
||||||
|
|
||||||
// attack caster if can
|
// attack caster if can
|
||||||
Unit* caster = ObjectAccessor::GetObjectInWorld(casterGUID, (Unit*)NULL);
|
Unit* caster = Unit::GetUnit(*this, casterGUID);
|
||||||
if(caster && ((Creature*)this)->AI())
|
if(caster && ((Creature*)this)->AI())
|
||||||
((Creature*)this)->AI()->AttackedBy(caster);
|
((Creature*)this)->AI()->AttackedBy(caster);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,21 +31,23 @@ Vehicle::Vehicle() : Creature(), m_vehicleId(0)
|
||||||
|
|
||||||
Vehicle::~Vehicle()
|
Vehicle::~Vehicle()
|
||||||
{
|
{
|
||||||
if(m_uint32Values) // only for fully created Object
|
|
||||||
ObjectAccessor::Instance().RemoveObject(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Vehicle::AddToWorld()
|
void Vehicle::AddToWorld()
|
||||||
{
|
{
|
||||||
///- Register the vehicle for guid lookup
|
///- Register the vehicle for guid lookup
|
||||||
if(!IsInWorld()) ObjectAccessor::Instance().AddObject(this);
|
if(!IsInWorld())
|
||||||
|
GetMap()->GetObjectsStore().insert<Vehicle>(GetGUID(), (Vehicle*)this);
|
||||||
|
|
||||||
Unit::AddToWorld();
|
Unit::AddToWorld();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Vehicle::RemoveFromWorld()
|
void Vehicle::RemoveFromWorld()
|
||||||
{
|
{
|
||||||
///- Remove the vehicle from the accessor
|
///- Remove the vehicle from the accessor
|
||||||
if(IsInWorld()) ObjectAccessor::Instance().RemoveObject(this);
|
if(IsInWorld())
|
||||||
|
GetMap()->GetObjectsStore().erase<Vehicle>(GetGUID(), (Vehicle*)NULL);
|
||||||
|
|
||||||
///- Don't call the function for Creature, normal mobs + totems go in a different storage
|
///- Don't call the function for Creature, normal mobs + totems go in a different storage
|
||||||
Unit::RemoveFromWorld();
|
Unit::RemoveFromWorld();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#ifndef __REVISION_NR_H__
|
#ifndef __REVISION_NR_H__
|
||||||
#define __REVISION_NR_H__
|
#define __REVISION_NR_H__
|
||||||
#define REVISION_NR "8652"
|
#define REVISION_NR "8653"
|
||||||
#endif // __REVISION_NR_H__
|
#endif // __REVISION_NR_H__
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue