Core/Grids: Modernize TypeContainer with variadic template

This commit is contained in:
Shauren
2025-01-05 20:22:34 +01:00
parent 0443391042
commit 401502ea3c
20 changed files with 186 additions and 528 deletions

View File

@@ -70,7 +70,7 @@ void AreaTrigger::AddToWorld()
if (m_zoneScript)
m_zoneScript->OnAreaTriggerCreate(this);
GetMap()->GetObjectsStore().Insert<AreaTrigger>(GetGUID(), this);
GetMap()->GetObjectsStore().Insert<AreaTrigger>(this);
if (_spawnId)
GetMap()->GetAreaTriggerBySpawnIdStore().insert(std::make_pair(_spawnId, this));
@@ -100,7 +100,7 @@ void AreaTrigger::RemoveFromWorld()
if (IsStaticSpawn())
Trinity::Containers::MultimapErasePair(GetMap()->GetAreaTriggerBySpawnIdStore(), _spawnId, this);
GetMap()->GetObjectsStore().Remove<AreaTrigger>(GetGUID());
GetMap()->GetObjectsStore().Remove<AreaTrigger>(this);
}
}

View File

@@ -52,7 +52,7 @@ void Conversation::AddToWorld()
///- Register the Conversation for guid lookup and for caster
if (!IsInWorld())
{
GetMap()->GetObjectsStore().Insert<Conversation>(GetGUID(), this);
GetMap()->GetObjectsStore().Insert<Conversation>(this);
WorldObject::AddToWorld();
}
}
@@ -65,7 +65,7 @@ void Conversation::RemoveFromWorld()
_ai->OnRemove();
WorldObject::RemoveFromWorld();
GetMap()->GetObjectsStore().Remove<Conversation>(GetGUID());
GetMap()->GetObjectsStore().Remove<Conversation>(this);
}
}

View File

@@ -50,7 +50,7 @@ void Corpse::AddToWorld()
{
///- Register the corpse for guid lookup
if (!IsInWorld())
GetMap()->GetObjectsStore().Insert<Corpse>(GetGUID(), this);
GetMap()->GetObjectsStore().Insert<Corpse>(this);
Object::AddToWorld();
}
@@ -59,7 +59,7 @@ void Corpse::RemoveFromWorld()
{
///- Remove the corpse from the accessor
if (IsInWorld())
GetMap()->GetObjectsStore().Remove<Corpse>(GetGUID());
GetMap()->GetObjectsStore().Remove<Corpse>(this);
WorldObject::RemoveFromWorld();
}

View File

@@ -340,7 +340,7 @@ void Creature::AddToWorld()
///- Register the creature for guid lookup
if (!IsInWorld())
{
GetMap()->GetObjectsStore().Insert<Creature>(GetGUID(), this);
GetMap()->GetObjectsStore().Insert<Creature>(this);
if (m_spawnId)
GetMap()->GetCreatureBySpawnIdStore().insert(std::make_pair(m_spawnId, this));
@@ -369,7 +369,7 @@ void Creature::RemoveFromWorld()
if (m_spawnId)
Trinity::Containers::MultimapErasePair(GetMap()->GetCreatureBySpawnIdStore(), m_spawnId, this);
GetMap()->GetObjectsStore().Remove<Creature>(GetGUID());
GetMap()->GetObjectsStore().Remove<Creature>(this);
}
}

View File

@@ -56,7 +56,7 @@ void DynamicObject::AddToWorld()
///- Register the dynamicObject for guid lookup and for caster
if (!IsInWorld())
{
GetMap()->GetObjectsStore().Insert<DynamicObject>(GetGUID(), this);
GetMap()->GetObjectsStore().Insert<DynamicObject>(this);
WorldObject::AddToWorld();
BindToCaster();
}
@@ -79,7 +79,7 @@ void DynamicObject::RemoveFromWorld()
UnbindFromCaster();
WorldObject::RemoveFromWorld();
GetMap()->GetObjectsStore().Remove<DynamicObject>(GetGUID());
GetMap()->GetObjectsStore().Remove<DynamicObject>(this);
}
}

View File

@@ -935,7 +935,7 @@ void GameObject::AddToWorld()
if (m_zoneScript)
m_zoneScript->OnGameObjectCreate(this);
GetMap()->GetObjectsStore().Insert<GameObject>(GetGUID(), this);
GetMap()->GetObjectsStore().Insert<GameObject>(this);
if (m_spawnId)
GetMap()->GetGameObjectBySpawnIdStore().insert(std::make_pair(m_spawnId, this));
@@ -975,7 +975,7 @@ void GameObject::RemoveFromWorld()
if (m_spawnId)
Trinity::Containers::MultimapErasePair(GetMap()->GetGameObjectBySpawnIdStore(), m_spawnId, this);
GetMap()->GetObjectsStore().Remove<GameObject>(GetGUID());
GetMap()->GetObjectsStore().Remove<GameObject>(this);
}
}

View File

@@ -72,7 +72,7 @@ void Pet::AddToWorld()
if (!IsInWorld())
{
///- Register the pet for guid lookup
GetMap()->GetObjectsStore().Insert<Pet>(GetGUID(), this);
GetMap()->GetObjectsStore().Insert<Pet>(this);
Unit::AddToWorld();
AIM_Initialize();
if (ZoneScript* zoneScript = GetZoneScript() ? GetZoneScript() : GetInstanceScript())
@@ -98,7 +98,7 @@ void Pet::RemoveFromWorld()
{
///- Don't call the function for Creature, normal mobs + totems go in a different storage
Unit::RemoveFromWorld();
GetMap()->GetObjectsStore().Remove<Pet>(GetGUID());
GetMap()->GetObjectsStore().Remove<Pet>(this);
}
}

View File

@@ -43,7 +43,7 @@ void SceneObject::AddToWorld()
{
if (!IsInWorld())
{
GetMap()->GetObjectsStore().Insert<SceneObject>(GetGUID(), this);
GetMap()->GetObjectsStore().Insert<SceneObject>(this);
WorldObject::AddToWorld();
}
}
@@ -53,7 +53,7 @@ void SceneObject::RemoveFromWorld()
if (IsInWorld())
{
WorldObject::RemoveFromWorld();
GetMap()->GetObjectsStore().Remove<SceneObject>(GetGUID());
GetMap()->GetObjectsStore().Remove<SceneObject>(this);
}
}

View File

@@ -23,203 +23,71 @@
* types of object at the same time.
*/
#include <unordered_map>
#include "Define.h"
#include "Dynamic/TypeList.h"
#include "GridRefManager.h"
#include <type_traits>
/*
* @class ContainerMapList is a mulit-type container for map elements
* By itself its meaningless but collaborate along with TypeContainers,
* it become the most powerfully container in the whole system.
*/
template<class OBJECT>
struct ContainerMapList
template <template <typename> typename UnderlyingContainer, typename... Types>
struct TypeListContainerStorage
{
GridRefManager<OBJECT> _element;
// empty case
};
template<>
struct ContainerMapList<TypeNull> /* nothing is in type null */
template <template <typename> typename UnderlyingContainer, typename First, typename... Rest>
struct TypeListContainerStorage<UnderlyingContainer, First, Rest...>
{
typename UnderlyingContainer<First>::Container Head;
TypeListContainerStorage<UnderlyingContainer, Rest...> Tail;
template <typename ObjectType>
typename UnderlyingContainer<ObjectType>::Container& FindContainer()
{
if constexpr (std::is_same_v<First, ObjectType>)
return Head;
else
return Tail.template FindContainer<ObjectType>();
}
template <typename ObjectType>
typename UnderlyingContainer<ObjectType>::Container const& FindContainer() const
{
if constexpr (std::is_same_v<First, ObjectType>)
return Head;
else
return Tail.template FindContainer<ObjectType>();
}
};
template<class H, class T>
struct ContainerMapList<TypeList<H, T> >
template <template <typename> typename UnderlyingContainer, typename... Types>
struct TypeListContainer
{
ContainerMapList<H> _elements;
ContainerMapList<T> _TailElements;
TypeListContainerStorage<UnderlyingContainer, Types...> Data;
template <typename ObjectType>
static constexpr bool TypeExists = std::disjunction_v<std::is_same<ObjectType, Types>...>;
template <typename ObjectType> requires TypeExists<ObjectType>
bool Insert(ObjectType* object)
{
return UnderlyingContainer<ObjectType>::Insert(Data.template FindContainer<ObjectType>(), object);
}
template <typename ObjectType> requires TypeExists<ObjectType>
bool Remove(ObjectType* object)
{
return UnderlyingContainer<ObjectType>::Remove(Data.template FindContainer<ObjectType>(), object);
}
template <typename ObjectType> requires TypeExists<ObjectType>
bool Size() const
{
return UnderlyingContainer<ObjectType>::Size(Data.template FindContainer<ObjectType>());
}
template <typename ObjectType> requires TypeExists<ObjectType> && requires { typename UnderlyingContainer<ObjectType>::KeyType; }
ObjectType* Find(typename UnderlyingContainer<ObjectType>::KeyType const& key) const
{
return UnderlyingContainer<ObjectType>::Find(Data.template FindContainer<ObjectType>(), key);
}
};
template<class OBJECT, class KEY_TYPE>
struct ContainerUnorderedMap
{
std::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;
};
#include "TypeContainerFunctions.h"
/*
* @class TypeMapContainer contains a fixed number of types and is
* determined at compile time. This is probably the most complicated
* class and do its simplest thing, that is, holds objects
* of different types.
*/
template<class OBJECT_TYPES>
class TypeMapContainer
{
public:
TypeMapContainer();
TypeMapContainer(TypeMapContainer const&) = default;
TypeMapContainer(TypeMapContainer&&) noexcept = default;
TypeMapContainer& operator=(TypeMapContainer const&) = default;
TypeMapContainer& operator=(TypeMapContainer&&) noexcept = default;
~TypeMapContainer();
template<class SPECIFIC_TYPE>
size_t Count() const;
/// inserts a specific object into the container
template<class SPECIFIC_TYPE>
bool insert(SPECIFIC_TYPE *obj);
/// Removes the object from the container, and returns the removed object
//template<class SPECIFIC_TYPE>
//bool remove(SPECIFIC_TYPE* obj)
//{
// SPECIFIC_TYPE* t = Trinity::Remove(i_elements, obj);
// return (t != nullptr);
//}
ContainerMapList<OBJECT_TYPES>& GetElements(void);
const ContainerMapList<OBJECT_TYPES>& GetElements(void) const;
private:
ContainerMapList<OBJECT_TYPES> i_elements;
};
template <class OBJECT_TYPES>
TypeMapContainer<OBJECT_TYPES>::TypeMapContainer() = default;
template <class OBJECT_TYPES>
TypeMapContainer<OBJECT_TYPES>::~TypeMapContainer() = default;
template <class OBJECT_TYPES>
template <class SPECIFIC_TYPE>
size_t TypeMapContainer<OBJECT_TYPES>::Count() const
{
return Trinity::Count(i_elements, (SPECIFIC_TYPE*)nullptr);
}
template <class OBJECT_TYPES>
template <class SPECIFIC_TYPE>
bool TypeMapContainer<OBJECT_TYPES>::insert(SPECIFIC_TYPE* obj)
{
SPECIFIC_TYPE* t = Trinity::Insert(i_elements, obj);
return (t != nullptr);
}
template <class OBJECT_TYPES>
ContainerMapList<OBJECT_TYPES>& TypeMapContainer<OBJECT_TYPES>::GetElements()
{
return i_elements;
}
template <class OBJECT_TYPES>
const ContainerMapList<OBJECT_TYPES>& TypeMapContainer<OBJECT_TYPES>::GetElements() const
{
return i_elements;
}
template<class OBJECT_TYPES, class KEY_TYPE>
class TypeUnorderedMapContainer
{
public:
TypeUnorderedMapContainer();
TypeUnorderedMapContainer(TypeUnorderedMapContainer const&) = default;
TypeUnorderedMapContainer(TypeUnorderedMapContainer&&) noexcept = default;
TypeUnorderedMapContainer& operator=(TypeUnorderedMapContainer const&) = default;
TypeUnorderedMapContainer& operator=(TypeUnorderedMapContainer&&) noexcept = default;
~TypeUnorderedMapContainer();
template<class SPECIFIC_TYPE>
bool Insert(KEY_TYPE const& handle, SPECIFIC_TYPE* obj);
template<class SPECIFIC_TYPE>
bool Remove(KEY_TYPE const& handle);
template<class SPECIFIC_TYPE>
SPECIFIC_TYPE* Find(KEY_TYPE const& handle);
template<class SPECIFIC_TYPE>
std::size_t Size() const;
ContainerUnorderedMap<OBJECT_TYPES, KEY_TYPE>& GetElements();
ContainerUnorderedMap<OBJECT_TYPES, KEY_TYPE> const& GetElements() const;
private:
ContainerUnorderedMap<OBJECT_TYPES, KEY_TYPE> _elements;
};
template <class OBJECT_TYPES, class KEY_TYPE>
TypeUnorderedMapContainer<OBJECT_TYPES, KEY_TYPE>::TypeUnorderedMapContainer() = default;
template <class OBJECT_TYPES, class KEY_TYPE>
TypeUnorderedMapContainer<OBJECT_TYPES, KEY_TYPE>::~TypeUnorderedMapContainer() = default;
template <class OBJECT_TYPES, class KEY_TYPE>
template <class SPECIFIC_TYPE>
bool TypeUnorderedMapContainer<OBJECT_TYPES, KEY_TYPE>::Insert(KEY_TYPE const& handle, SPECIFIC_TYPE* obj)
{
return Trinity::Insert(_elements, handle, obj);
}
template <class OBJECT_TYPES, class KEY_TYPE>
template <class SPECIFIC_TYPE>
bool TypeUnorderedMapContainer<OBJECT_TYPES, KEY_TYPE>::Remove(KEY_TYPE const& handle)
{
return Trinity::Remove(_elements, handle, (SPECIFIC_TYPE*)nullptr);
}
template <class OBJECT_TYPES, class KEY_TYPE>
template <class SPECIFIC_TYPE>
SPECIFIC_TYPE* TypeUnorderedMapContainer<OBJECT_TYPES, KEY_TYPE>::Find(KEY_TYPE const& handle)
{
return Trinity::Find(_elements, handle, (SPECIFIC_TYPE*)nullptr);
}
template <class OBJECT_TYPES, class KEY_TYPE>
template <class SPECIFIC_TYPE>
std::size_t TypeUnorderedMapContainer<OBJECT_TYPES, KEY_TYPE>::Size() const
{
std::size_t size = 0;
Trinity::Size(_elements, &size, (SPECIFIC_TYPE*)nullptr);
return size;
}
template <class OBJECT_TYPES, class KEY_TYPE>
ContainerUnorderedMap<OBJECT_TYPES, KEY_TYPE>& TypeUnorderedMapContainer<OBJECT_TYPES, KEY_TYPE>::GetElements()
{
return _elements;
}
template <class OBJECT_TYPES, class KEY_TYPE>
ContainerUnorderedMap<OBJECT_TYPES, KEY_TYPE> const& TypeUnorderedMapContainer<OBJECT_TYPES, KEY_TYPE>::GetElements() const
{
return _elements;
}
#endif

View File

@@ -1,157 +0,0 @@
/*
* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef TYPECONTAINER_FUNCTIONS_H
#define TYPECONTAINER_FUNCTIONS_H
/*
* Here you'll find a list of helper functions to make
* the TypeContainer usefull. Without it, its hard
* to access or mutate the container.
*/
#include "Define.h"
#include "Dynamic/TypeList.h"
namespace Trinity
{
// Helpers
// Insert helpers
template<class SPECIFIC_TYPE, class KEY_TYPE, class H, class T>
inline bool Insert(ContainerUnorderedMap<TypeList<H, T>, KEY_TYPE>& elements, KEY_TYPE const& handle, SPECIFIC_TYPE* obj)
{
if constexpr (std::is_same_v<H, SPECIFIC_TYPE>)
{
auto i = elements._elements._element.find(handle);
if (i == elements._elements._element.end())
{
elements._elements._element[handle] = obj;
return true;
}
else
{
ASSERT(i->second == obj, "Object with certain key already in but objects are different!");
return false;
}
}
if constexpr (std::is_same_v<T, TypeNull>)
return false;
else
return Insert(elements._TailElements, handle, obj);
}
// Find helpers
template<class SPECIFIC_TYPE, class KEY_TYPE, class H, class T>
inline SPECIFIC_TYPE* Find(ContainerUnorderedMap<TypeList<H, T>, KEY_TYPE> const& elements, KEY_TYPE const& handle, SPECIFIC_TYPE* obj)
{
if constexpr (std::is_same_v<H, SPECIFIC_TYPE>)
{
auto i = elements._elements._element.find(handle);
if (i == elements._elements._element.end())
return nullptr;
else
return i->second;
}
if constexpr (std::is_same_v<T, TypeNull>)
return nullptr;
else
return Find(elements._TailElements, handle, obj);
}
// Erase helpers
template<class SPECIFIC_TYPE, class KEY_TYPE, class H, class T>
inline bool Remove(ContainerUnorderedMap<TypeList<H, T>, KEY_TYPE>& elements, KEY_TYPE const& handle, SPECIFIC_TYPE* obj)
{
if constexpr (std::is_same_v<H, SPECIFIC_TYPE>)
{
elements._elements._element.erase(handle);
return true;
}
if constexpr (std::is_same_v<T, TypeNull>)
return false;
else
return Remove(elements._TailElements, handle, obj);
}
// Count helpers
template<class SPECIFIC_TYPE, class KEY_TYPE, class H, class T>
inline bool Size(ContainerUnorderedMap<TypeList<H, T>, KEY_TYPE> const& elements, std::size_t* size, SPECIFIC_TYPE* obj)
{
if constexpr (std::is_same_v<H, SPECIFIC_TYPE>)
{
*size = elements._elements._element.size();
return true;
}
if constexpr (std::is_same_v<T, TypeNull>)
return false;
else
return Size(elements._TailElements, size, obj);
}
/* ContainerMapList Helpers */
// count functions
template<class SPECIFIC_TYPE, class H, class T>
inline size_t Count(ContainerMapList<TypeList<H, T>> const& elements, SPECIFIC_TYPE* fake)
{
if constexpr (std::is_same_v<H, SPECIFIC_TYPE>)
{
return elements._elements._element.getSize();
}
if constexpr (std::is_same_v<T, TypeNull>)
return 0;
else
return Count(elements._TailElements, fake);
}
// non-const insert functions
template<class SPECIFIC_TYPE, class H, class T>
inline SPECIFIC_TYPE* Insert(ContainerMapList<TypeList<H, T>>& elements, SPECIFIC_TYPE* obj)
{
if constexpr (std::is_same_v<H, SPECIFIC_TYPE>)
{
obj->AddToGrid(elements._elements._element);
return obj;
}
if constexpr (std::is_same_v<T, TypeNull>)
return nullptr;
else
return Insert(elements._TailElements, obj);
}
//// non-const remove method
//template<class SPECIFIC_TYPE, class H, class T>
//SPECIFIC_TYPE* Remove(ContainerMapList<TypeList<H, T>>& elements, SPECIFIC_TYPE* obj)
//{
// if constexpr (std::is_same_v<H, SPECIFIC_TYPE>)
// {
// obj->GetGridRef().unlink();
// return obj;
// }
// if constexpr (std::is_same_v<T, TypeNull>)
// return nullptr;
// else
// return Remove(elements._TailElements, obj);
//}
}
#endif

View File

@@ -26,76 +26,42 @@
#include "Dynamic/TypeContainer.h"
// forward declaration
template<class T, class Y> class TypeContainerVisitor;
// visitor helper
template<class VISITOR, class TYPE_CONTAINER> void VisitorHelper(VISITOR &v, TYPE_CONTAINER &c)
template <class Visitor, template <typename> typename UnderlyingContainer, typename... Types>
inline void VisitorHelper(Visitor& /*v*/, [[maybe_unused]] TypeListContainerStorage<UnderlyingContainer, Types...>& /*c*/)
{
v.Visit(c);
}
// terminate condition container map list
template<class VISITOR> void VisitorHelper(VISITOR &/*v*/, ContainerMapList<TypeNull> &/*c*/) { }
template<class VISITOR, class T> void VisitorHelper(VISITOR &v, ContainerMapList<T> &c)
template <class Visitor, template <typename> typename UnderlyingContainer, typename First, typename... Types>
inline void VisitorHelper(Visitor& v, TypeListContainerStorage<UnderlyingContainer, First, Types...>& c)
{
v.Visit(c._element);
v.Visit(c.Head);
VisitorHelper(v, c.Tail);
}
// recursion container map list
template<class VISITOR, class H, class T> void VisitorHelper(VISITOR &v, ContainerMapList<TypeList<H, T> > &c)
template <class Visitor, template <typename> typename UnderlyingContainer, typename... Types>
inline void VisitorHelper(Visitor& v, TypeListContainer<UnderlyingContainer, Types...>& c)
{
VisitorHelper(v, c._elements);
VisitorHelper(v, c._TailElements);
VisitorHelper(v, c.Data);
}
// for TypeMapContainer
template<class VISITOR, class OBJECT_TYPES> void VisitorHelper(VISITOR &v, TypeMapContainer<OBJECT_TYPES> &c)
{
VisitorHelper(v, c.GetElements());
}
// TypeUnorderedMapContainer
template<class VISITOR, class KEY_TYPE>
void VisitorHelper(VISITOR& /*v*/, ContainerUnorderedMap<TypeNull, KEY_TYPE>& /*c*/) { }
template<class VISITOR, class KEY_TYPE, class T>
void VisitorHelper(VISITOR& v, ContainerUnorderedMap<T, KEY_TYPE>& c)
{
v.Visit(c._element);
}
template<class VISITOR, class KEY_TYPE, class H, class T>
void VisitorHelper(VISITOR& v, ContainerUnorderedMap<TypeList<H, T>, KEY_TYPE>& c)
{
VisitorHelper(v, c._elements);
VisitorHelper(v, c._TailElements);
}
template<class VISITOR, class OBJECT_TYPES, class KEY_TYPE>
void VisitorHelper(VISITOR& v, TypeUnorderedMapContainer<OBJECT_TYPES, KEY_TYPE>& c)
{
VisitorHelper(v, c.GetElements());
}
template<class VISITOR, class TYPE_CONTAINER>
template<class Visitor, class TypeContainer>
class TypeContainerVisitor
{
public:
TypeContainerVisitor(VISITOR &v) : i_visitor(v) { }
public:
TypeContainerVisitor(Visitor& v) : i_visitor(v) { }
void Visit(TYPE_CONTAINER& c)
{
VisitorHelper(i_visitor, c);
}
void Visit(TypeContainer& c)
{
VisitorHelper(i_visitor, c);
}
void Visit(TYPE_CONTAINER const& c) const
{
VisitorHelper(i_visitor, c);
}
void Visit(TypeContainer const& c) const
{
VisitorHelper(i_visitor, c);
}
private:
VISITOR &i_visitor;
private:
Visitor& i_visitor;
};
#endif

View File

@@ -30,7 +30,7 @@
*/
#include "Define.h"
#include "TypeContainer.h"
#include "Errors.h"
#include "TypeContainerVisitor.h"
// forward declaration
@@ -57,7 +57,7 @@ class Grid
*/
template<class SPECIFIC_OBJECT> void AddWorldObject(SPECIFIC_OBJECT *obj)
{
i_objects.template insert<SPECIFIC_OBJECT>(obj);
i_objects.template Insert<SPECIFIC_OBJECT>(obj);
ASSERT(obj->IsInGrid());
}
@@ -103,14 +103,14 @@ class Grid
template<class T>
uint32 GetWorldObjectCountInGrid() const
{
return uint32(i_objects.template Count<T>());
return uint32(i_objects.template Size<T>());
}
/** Inserts a container type object into the grid.
*/
template<class SPECIFIC_OBJECT> void AddGridObject(SPECIFIC_OBJECT *obj)
{
i_container.template insert<SPECIFIC_OBJECT>(obj);
i_container.template Insert<SPECIFIC_OBJECT>(obj);
ASSERT(obj->IsInGrid());
}
@@ -139,4 +139,5 @@ class Grid
//typedef std::set<void*> ActiveGridObjects;
//ActiveGridObjects m_activeGridObjects;
};
#endif

View File

@@ -62,11 +62,6 @@ class Conversation;
#define MAX_FALL_DISTANCE 250000.0f // "unlimited fall" to find VMap ground if it is available, just larger than MAX_HEIGHT - INVALID_HEIGHT
#define DEFAULT_HEIGHT_SEARCH 50.0f // default search distance to find height at nearby locations
// Creature used instead pet to simplify *::Visit templates (not required duplicate code for Creature->Pet case)
typedef TYPELIST_4(Player, Creature/*pets*/, Corpse/*resurrectable*/, DynamicObject/*farsight target*/) AllWorldObjectTypes;
typedef TYPELIST_7(GameObject, Creature/*except pets*/, DynamicObject, Corpse/*Bones*/, AreaTrigger, SceneObject, Conversation) AllGridObjectTypes;
typedef TYPELIST_8(Creature, GameObject, DynamicObject, Pet, Corpse, AreaTrigger, SceneObject, Conversation) AllMapStoredObjectTypes;
typedef GridRefManager<Corpse> CorpseMapType;
typedef GridRefManager<Creature> CreatureMapType;
typedef GridRefManager<DynamicObject> DynamicObjectMapType;
@@ -89,11 +84,12 @@ enum GridMapTypeMask
GRID_MAP_TYPE_MASK_ALL = 0xFF
};
extern template class TypeMapContainer<AllGridObjectTypes>;
extern template class TypeMapContainer<AllWorldObjectTypes>;
// Creature used instead pet to simplify *::Visit templates (not required duplicate code for Creature->Pet case)
extern template struct TypeListContainer<GridRefManagerContainer, GameObject, Creature/*except pets*/, DynamicObject, Corpse/*Bones*/, AreaTrigger, SceneObject, Conversation>;
extern template struct TypeListContainer<GridRefManagerContainer, Player, Creature/*pets*/, Corpse/*resurrectable*/, DynamicObject/*farsight target*/>;
typedef TypeMapContainer<AllGridObjectTypes> GridTypeMapContainer;
typedef TypeMapContainer<AllWorldObjectTypes> WorldTypeMapContainer;
typedef TypeListContainer<GridRefManagerContainer, GameObject, Creature/*except pets*/, DynamicObject, Corpse/*Bones*/, AreaTrigger, SceneObject, Conversation> GridTypeMapContainer;
typedef TypeListContainer<GridRefManagerContainer, Player, Creature/*pets*/, Corpse/*resurrectable*/, DynamicObject/*farsight target*/> WorldTypeMapContainer;
extern template class Grid<Player, WorldTypeMapContainer, GridTypeMapContainer>;
extern template class NGrid<MAX_NUMBER_OF_CELLS, Player, WorldTypeMapContainer, GridTypeMapContainer>;

View File

@@ -27,4 +27,30 @@ template<class OBJECT>
class GridRefManager : public RefManager<GridReference<OBJECT>>
{
};
template <typename ObjectType>
struct GridRefManagerContainer
{
using Container = GridRefManager<ObjectType>;
using ValueType = ObjectType*;
static bool Insert(Container& container, ValueType object)
{
object->AddToGrid(container);
return true;
}
static bool Remove(Container& /*container*/, ValueType object)
{
object->RemoveFromGrid();
return true;
}
static std::size_t Size(Container const& container)
{
return container.getSize();
}
};
#endif

View File

@@ -32,5 +32,5 @@ GridInfo::GridInfo(time_t expiry, bool unload /*= true */) : i_timer(expiry), vi
template class Grid<Player, WorldTypeMapContainer, GridTypeMapContainer>;
template class NGrid<MAX_NUMBER_OF_CELLS, Player, WorldTypeMapContainer, GridTypeMapContainer>;
template class TC_GAME_API TypeMapContainer<AllGridObjectTypes>;
template class TC_GAME_API TypeMapContainer<AllWorldObjectTypes>;
template struct TC_GAME_API TypeListContainer<GridRefManagerContainer, GameObject, Creature/*except pets*/, DynamicObject, Corpse/*Bones*/, AreaTrigger, SceneObject, Conversation>;
template struct TC_GAME_API TypeListContainer<GridRefManagerContainer, Player, Creature/*pets*/, Corpse/*resurrectable*/, DynamicObject/*farsight target*/>;

View File

@@ -22,6 +22,7 @@
*/
#include "Grid.h"
#include "GridRefManager.h"
#include "GridReference.h"
#include "Timer.h"

View File

@@ -180,52 +180,21 @@ template<class T>
void Map::AddToGrid(T* obj, Cell const& cell)
{
NGridType* grid = getNGrid(cell.GridX(), cell.GridY());
if (obj->IsStoredInWorldObjectGridContainer())
grid->GetGridType(cell.CellX(), cell.CellY()).template AddWorldObject<T>(obj);
else
grid->GetGridType(cell.CellX(), cell.CellY()).template AddGridObject<T>(obj);
}
if constexpr (WorldTypeMapContainer::TypeExists<T> && GridTypeMapContainer::TypeExists<T>)
{
NGridType::GridType& cellType = grid->GetGridType(cell.CellX(), cell.CellY());
if (obj->IsStoredInWorldObjectGridContainer())
cellType.AddWorldObject<T>(obj);
else
cellType.AddGridObject<T>(obj);
}
else if constexpr (WorldTypeMapContainer::TypeExists<T>)
grid->GetGridType(cell.CellX(), cell.CellY()).AddWorldObject<T>(obj);
else if constexpr (GridTypeMapContainer::TypeExists<T>)
grid->GetGridType(cell.CellX(), cell.CellY()).AddGridObject<T>(obj);
template<>
void Map::AddToGrid(Creature* obj, Cell const& cell)
{
NGridType* grid = getNGrid(cell.GridX(), cell.GridY());
if (obj->IsStoredInWorldObjectGridContainer())
grid->GetGridType(cell.CellX(), cell.CellY()).AddWorldObject(obj);
else
grid->GetGridType(cell.CellX(), cell.CellY()).AddGridObject(obj);
obj->SetCurrentCell(cell);
}
template<>
void Map::AddToGrid(GameObject* obj, Cell const& cell)
{
NGridType* grid = getNGrid(cell.GridX(), cell.GridY());
grid->GetGridType(cell.CellX(), cell.CellY()).AddGridObject(obj);
obj->SetCurrentCell(cell);
}
template<>
void Map::AddToGrid(DynamicObject* obj, Cell const& cell)
{
NGridType* grid = getNGrid(cell.GridX(), cell.GridY());
if (obj->IsStoredInWorldObjectGridContainer())
grid->GetGridType(cell.CellX(), cell.CellY()).AddWorldObject(obj);
else
grid->GetGridType(cell.CellX(), cell.CellY()).AddGridObject(obj);
obj->SetCurrentCell(cell);
}
template<>
void Map::AddToGrid(AreaTrigger* obj, Cell const& cell)
{
NGridType* grid = getNGrid(cell.GridX(), cell.GridY());
grid->GetGridType(cell.CellX(), cell.CellY()).AddGridObject(obj);
obj->SetCurrentCell(cell);
if constexpr (std::is_base_of_v<MapObject, T>)
obj->SetCurrentCell(cell);
}
template<>
@@ -240,10 +209,11 @@ void Map::AddToGrid(Corpse* obj, Cell const& cell)
// to avoid failing an assertion in GridObject::AddToGrid
if (grid->isGridObjectDataLoaded())
{
NGridType::GridType& cellType = grid->GetGridType(cell.CellX(), cell.CellY());
if (obj->IsStoredInWorldObjectGridContainer())
grid->GetGridType(cell.CellX(), cell.CellY()).AddWorldObject(obj);
cellType.AddWorldObject(obj);
else
grid->GetGridType(cell.CellX(), cell.CellY()).AddGridObject(obj);
cellType.AddGridObject(obj);
}
}
@@ -4094,4 +4064,4 @@ std::string InstanceMap::GetDebugInfo() const
return sstr.str();
}
template class TC_GAME_API TypeUnorderedMapContainer<AllMapStoredObjectTypes, ObjectGuid>;
template struct TC_GAME_API TypeListContainer<MapStoredObjectsUnorderedMap, Creature, GameObject, DynamicObject, Pet, Corpse, AreaTrigger, SceneObject, Conversation>;

View File

@@ -183,8 +183,40 @@ inline bool CompareRespawnInfo::operator()(RespawnInfo const* a, RespawnInfo con
return a->type < b->type;
}
extern template class TypeUnorderedMapContainer<AllMapStoredObjectTypes, ObjectGuid>;
typedef TypeUnorderedMapContainer<AllMapStoredObjectTypes, ObjectGuid> MapStoredObjectTypesContainer;
template <typename ObjectType>
struct MapStoredObjectsUnorderedMap
{
using Container = std::unordered_map<ObjectGuid, ObjectType*>;
using KeyType = ObjectGuid;
using ValueType = ObjectType*;
static bool Insert(Container& container, ValueType object)
{
auto [itr, isNew] = container.try_emplace(object->GetGUID(), object);
ASSERT(isNew || itr->second == object, "Object with certain key already in but objects are different!");
return true;
}
static bool Remove(Container& container, ValueType object)
{
container.erase(object->GetGUID());
return true;
}
static std::size_t Size(Container const& container)
{
return container.size();
}
static ValueType Find(Container const& container, KeyType const& key)
{
auto itr = container.find(key);
return itr != container.end() ? itr->second : nullptr;
}
};
extern template struct TypeListContainer<MapStoredObjectsUnorderedMap, Creature, GameObject, DynamicObject, Pet, Corpse, AreaTrigger, SceneObject, Conversation>;
typedef TypeListContainer<MapStoredObjectsUnorderedMap, Creature, GameObject, DynamicObject, Pet, Corpse, AreaTrigger, SceneObject, Conversation> MapStoredObjectTypesContainer;
class TC_GAME_API Map : public GridRefManager<NGridType>
{

View File

@@ -729,7 +729,7 @@ class instance_culling_of_stratholme : public InstanceMapScript
// Reset respawn time on all permanent spawns, despawn all temporary spawns
// @todo dynspawn, this won't work
std::vector<Creature*> toDespawn;
std::unordered_map<ObjectGuid, Creature*> const& objects = instance->GetObjectsStore().GetElements()._elements._element;
std::unordered_map<ObjectGuid, Creature*> const& objects = instance->GetObjectsStore().Data.Head;
for (std::unordered_map<ObjectGuid, Creature*>::const_iterator itr = objects.cbegin(); itr != objects.cend(); ++itr)
{
if (itr->second && (itr->second->isDead() || !itr->second->GetSpawnId() || itr->second->GetOriginalEntry() != itr->second->GetEntry()))

View File

@@ -1,45 +0,0 @@
/*
* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef TRINITY_TYPELIST_H
#define TRINITY_TYPELIST_H
/*
@struct TypeList
TypeList is the most simple but yet the most powerfull class of all. It holds
at compile time the different type of objects in a linked list.
*/
class TypeNull;
template<typename HEAD, typename TAIL>
struct TypeList
{
typedef HEAD Head;
typedef TAIL Tail;
};
// enough for now.. can be expand at any point in time as needed
#define TYPELIST_1(T1) TypeList<T1, TypeNull>
#define TYPELIST_2(T1, T2) TypeList<T1, TYPELIST_1(T2) >
#define TYPELIST_3(T1, T2, T3) TypeList<T1, TYPELIST_2(T2, T3) >
#define TYPELIST_4(T1, T2, T3, T4) TypeList<T1, TYPELIST_3(T2, T3, T4) >
#define TYPELIST_5(T1, T2, T3, T4, T5) TypeList<T1, TYPELIST_4(T2, T3, T4, T5) >
#define TYPELIST_6(T1, T2, T3, T4, T5, T6) TypeList<T1, TYPELIST_5(T2, T3, T4, T5, T6) >
#define TYPELIST_7(T1, T2, T3, T4, T5, T6, T7) TypeList<T1, TYPELIST_6(T2, T3, T4, T5, T6, T7) >
#define TYPELIST_8(T1, T2, T3, T4, T5, T6, T7, T8) TypeList<T1, TYPELIST_7(T2, T3, T4, T5, T6, T7, T8) >
#endif