[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:
ApoC 2009-10-16 20:11:00 +02:00
parent 40b0612dfc
commit 45c9c136ba
18 changed files with 272 additions and 116 deletions

View file

@ -60,23 +60,26 @@ GameObject::GameObject() : WorldObject()
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()
{
///- Remove the gameobject from the accessor
if(IsInWorld())
{
// Possible crash at access to deleted GO in Unit::m_gameobj
// Remove GO from owner
if(uint64 owner_guid = GetOwnerGUID())
{
Unit* owner = NULL;
if(IS_PLAYER_GUID(owner_guid))
owner = ObjectAccessor::GetObjectInWorld(owner_guid, (Player*)NULL);
else
owner = ObjectAccessor::GetUnit(*this,owner_guid);
if(owner)
if (Unit* owner = IS_PLAYER_GUID(owner_guid) ? ObjectAccessor::FindPlayer(owner_guid) : GetMap()->GetCreatureOrPet(owner_guid))
owner->RemoveGameObject(this,false);
else
{
@ -90,20 +93,10 @@ void GameObject::CleanupsBeforeDelete()
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();
}