From ca83e14f8b141fab0a13e08f48fca6c1ace0c4c7 Mon Sep 17 00:00:00 2001 From: Shauren Date: Wed, 25 Feb 2015 00:13:14 +0100 Subject: Core/Entities: Reworked guid scopes * Added ObjectGuid traits to easily access whether guid type can be generated globally (ObjectMgr) or not * This adds separate (per map) guid sequences depending on object type * Ported map object container from cmangos/mangos-wotlk@a2d396eb0bb195efc460944dd4e0fab2a858b300 * Added type container visitor for TypeUnorderedMapContainer * Implemented helper function to erase unique pairs from multimap containers * Moved object storage of all objects except players and transports to map level * Added containers linking database spawn id with creature/gameobject in world * Renamed DBTableGuid to spawnId * Added a separate spawn id sequence generator for creatures and gameobjects - this will be used in db tables * Moved building SMSG_UPDATE_OBJECT - updatefields changes broadcast to map update --- src/server/shared/Containers.h | 13 ++ .../Database/Implementation/CharacterDatabase.cpp | 17 ++- .../Database/Implementation/CharacterDatabase.h | 7 +- src/server/shared/Dynamic/TypeContainer.h | 83 ++++++++----- src/server/shared/Dynamic/TypeContainerFunctions.h | 136 ++++++++++++++++++--- src/server/shared/Dynamic/TypeContainerVisitor.h | 39 +++--- src/server/shared/Dynamic/TypeList.h | 1 + 7 files changed, 210 insertions(+), 86 deletions(-) (limited to 'src/server/shared') diff --git a/src/server/shared/Containers.h b/src/server/shared/Containers.h index 5dee18cb752..685acea05e3 100644 --- a/src/server/shared/Containers.h +++ b/src/server/shared/Containers.h @@ -92,6 +92,19 @@ namespace Trinity return false; } + + template class M, class... Rest> + void MultimapErasePair(M& multimap, K const& key, V const& value) + { + auto range = multimap.equal_range(key); + for (auto itr = range.first; itr != range.second;) + { + if (itr->second == value) + itr = multimap.erase(itr); + else + ++itr; + } + } } //! namespace Containers } diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.cpp b/src/server/shared/Database/Implementation/CharacterDatabase.cpp index c7a63911a4c..6c18a0e76ee 100644 --- a/src/server/shared/Database/Implementation/CharacterDatabase.cpp +++ b/src/server/shared/Database/Implementation/CharacterDatabase.cpp @@ -338,16 +338,13 @@ void CharacterDatabaseConnection::DoPrepareStatements() PrepareStatement(CHAR_DEL_PLAYER_HOMEBIND, "DELETE FROM character_homebind WHERE guid = ?", CONNECTION_ASYNC); // Corpse - PrepareStatement(CHAR_SEL_CORPSES, "SELECT posX, posY, posZ, orientation, mapId, displayId, itemCache, bytes1, bytes2, flags, dynFlags, time, corpseType, instanceId, corpseGuid, guid FROM corpse WHERE corpseType <> 0", CONNECTION_SYNCH); - PrepareStatement(CHAR_INS_CORPSE, "INSERT INTO corpse (corpseGuid, guid, posX, posY, posZ, orientation, mapId, displayId, itemCache, bytes1, bytes2, flags, dynFlags, time, corpseType, instanceId) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_CORPSE, "DELETE FROM corpse WHERE corpseGuid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_PLAYER_CORPSES, "DELETE FROM corpse WHERE guid = ? AND corpseType <> 0", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_OLD_CORPSES, "DELETE FROM corpse WHERE corpseType = 0 OR time < (UNIX_TIMESTAMP(NOW()) - ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_CORPSE_PHASES, "SELECT Guid, PhaseId FROM corpse_phases", CONNECTION_SYNCH); - PrepareStatement(CHAR_DEL_CORPSE_PHASES, "DELETE FROM corpse_phases WHERE Guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_PLAYER_CORPSES_PHASES, "DELETE FROM corpse_phases WHERE OwnerGuid = ? AND CorpseType <> 0", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_OLD_CORPSE_PHASES, "DELETE FROM corpse_phases WHERE CorpseType = 0 OR Time < (UNIX_TIMESTAMP(NOW()) - ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_INS_CORPSE_PHASES, "INSERT INTO corpse_phases (Guid, PhaseId, OwnerGuid, Time, CorpseType) VALUES (?, ?, ?, ?, ?)", CONNECTION_ASYNC); + PrepareStatement(CHAR_SEL_CORPSES, "SELECT posX, posY, posZ, orientation, mapId, displayId, itemCache, bytes1, bytes2, flags, dynFlags, time, corpseType, instanceId, guid FROM corpse WHERE mapId = ?", CONNECTION_SYNCH); + PrepareStatement(CHAR_INS_CORPSE, "INSERT INTO corpse (guid, posX, posY, posZ, orientation, mapId, displayId, itemCache, bytes1, bytes2, flags, dynFlags, time, corpseType, instanceId) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); + PrepareStatement(CHAR_DEL_CORPSE, "DELETE FROM corpse WHERE guid = ?", CONNECTION_ASYNC); + PrepareStatement(CHAR_DEL_CORPSES_FROM_MAP, "DELETE cp, c FROM corpse_phases cp INNER JOIN corpse c ON cp.OwnerGuid = c.guid WHERE c.mapId = ?", CONNECTION_ASYNC); + PrepareStatement(CHAR_SEL_CORPSE_PHASES, "SELECT cp.OwnerGuid, cp.PhaseId FROM corpse_phases cp LEFT JOIN corpse c ON cp.OwnerGuid = c.guid WHERE c.mapId = ?", CONNECTION_SYNCH); + PrepareStatement(CHAR_INS_CORPSE_PHASES, "INSERT INTO corpse_phases (OwnerGuid, PhaseId) VALUES (?, ?)", CONNECTION_ASYNC); + PrepareStatement(CHAR_DEL_CORPSE_PHASES, "DELETE FROM corpse_phases WHERE OwnerGuid = ?", CONNECTION_ASYNC); // Creature respawn PrepareStatement(CHAR_SEL_CREATURE_RESPAWNS, "SELECT guid, respawnTime FROM creature_respawn WHERE mapId = ? AND instanceId = ?", CONNECTION_SYNCH); diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.h b/src/server/shared/Database/Implementation/CharacterDatabase.h index b6897204b6a..ed3b6dd8098 100644 --- a/src/server/shared/Database/Implementation/CharacterDatabase.h +++ b/src/server/shared/Database/Implementation/CharacterDatabase.h @@ -294,13 +294,10 @@ enum CharacterDatabaseStatements CHAR_SEL_CORPSES, CHAR_INS_CORPSE, CHAR_DEL_CORPSE, - CHAR_DEL_PLAYER_CORPSES, - CHAR_DEL_OLD_CORPSES, + CHAR_DEL_CORPSES_FROM_MAP, CHAR_SEL_CORPSE_PHASES, - CHAR_DEL_CORPSE_PHASES, - CHAR_DEL_PLAYER_CORPSES_PHASES, - CHAR_DEL_OLD_CORPSE_PHASES, CHAR_INS_CORPSE_PHASES, + CHAR_DEL_CORPSE_PHASES, CHAR_SEL_CREATURE_RESPAWNS, CHAR_REP_CREATURE_RESPAWN, diff --git a/src/server/shared/Dynamic/TypeContainer.h b/src/server/shared/Dynamic/TypeContainer.h index 2165945d119..9b264fdea7f 100644 --- a/src/server/shared/Dynamic/TypeContainer.h +++ b/src/server/shared/Dynamic/TypeContainer.h @@ -25,6 +25,7 @@ */ #include +#include #include #include "Define.h" #include "Dynamic/TypeList.h" @@ -35,54 +36,41 @@ * By itself its meaningless but collaborate along with TypeContainers, * it become the most powerfully container in the whole system. */ -template struct ContainerMapList +template +struct ContainerMapList { //std::map _element; GridRefManager _element; }; -template<> struct ContainerMapList /* nothing is in type null */ +template<> +struct ContainerMapList /* nothing is in type null */ { }; -template struct ContainerMapList > + +template +struct ContainerMapList > { ContainerMapList _elements; ContainerMapList _TailElements; }; -/* - * @class ContaierArrayList is a multi-type container for - * array of elements. - */ -template struct ContainerArrayList +template +struct ContainerUnorderedMap { - std::vector _element; + std::unordered_map _element; }; -// termination condition -template<> struct ContainerArrayList { }; -// recursion -template struct ContainerArrayList > +template +struct ContainerUnorderedMap { - ContainerArrayList _elements; - ContainerArrayList _TailElements; }; -/* - * @class ContainerList is a simple list of different types of elements - * - */ -template struct ContainerList +template +struct ContainerUnorderedMap, KEY_TYPE> { - OBJECT _element; -}; - -/* TypeNull is underfined */ -template<> struct ContainerList { }; -template struct ContainerList > -{ - ContainerList _elements; - ContainerMapList _TailElements; + ContainerUnorderedMap _elements; + ContainerUnorderedMap _TailElements; }; #include "TypeContainerFunctions.h" @@ -101,14 +89,16 @@ class TypeMapContainer template size_t Count() const { return Trinity::Count(i_elements, (SPECIFIC_TYPE*)NULL); } /// inserts a specific object into the container - template bool insert(SPECIFIC_TYPE *obj) + template + bool insert(SPECIFIC_TYPE *obj) { SPECIFIC_TYPE* t = Trinity::Insert(i_elements, obj); return (t != NULL); } /// Removes the object from the container, and returns the removed object - //template bool remove(SPECIFIC_TYPE* obj) + //template + //bool remove(SPECIFIC_TYPE* obj) //{ // SPECIFIC_TYPE* t = Trinity::Remove(i_elements, obj); // return (t != NULL); @@ -120,5 +110,34 @@ class TypeMapContainer private: ContainerMapList i_elements; }; -#endif +template +class TypeUnorderedMapContainer +{ +public: + template + bool Insert(KEY_TYPE const& handle, SPECIFIC_TYPE* obj) + { + return Trinity::Insert(_elements, handle, obj); + } + + template + bool Remove(KEY_TYPE const& handle) + { + return Trinity::Remove(_elements, handle, (SPECIFIC_TYPE*)NULL); + } + + template + SPECIFIC_TYPE* Find(KEY_TYPE const& handle) + { + return Trinity::Find(_elements, handle, (SPECIFIC_TYPE*)NULL); + } + + ContainerUnorderedMap& GetElements() { return _elements; } + ContainerUnorderedMap const& GetElements() const { return _elements; } + +private: + ContainerUnorderedMap _elements; +}; + +#endif diff --git a/src/server/shared/Dynamic/TypeContainerFunctions.h b/src/server/shared/Dynamic/TypeContainerFunctions.h index a89f5bd10d4..4a841cfda56 100644 --- a/src/server/shared/Dynamic/TypeContainerFunctions.h +++ b/src/server/shared/Dynamic/TypeContainerFunctions.h @@ -28,60 +28,164 @@ #include "Define.h" #include "Dynamic/TypeList.h" #include +#include namespace Trinity { + // Helpers + // Insert helpers + template + bool Insert(ContainerUnorderedMap& elements, KEY_TYPE const& handle, SPECIFIC_TYPE* obj) + { + auto 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 + bool Insert(ContainerUnorderedMap& /*elements*/, KEY_TYPE const& /*handle*/, SPECIFIC_TYPE* /*obj*/) + { + return false; + } + + template + bool Insert(ContainerUnorderedMap& /*elements*/, KEY_TYPE const& /*handle*/, SPECIFIC_TYPE* /*obj*/) + { + return false; + } + + template + bool Insert(ContainerUnorderedMap, KEY_TYPE>& elements, KEY_TYPE const& handle, SPECIFIC_TYPE* obj) + { + bool ret = Insert(elements._elements, handle, obj); + return ret ? ret : Insert(elements._TailElements, handle, obj); + } + + // Find helpers + template + SPECIFIC_TYPE* Find(ContainerUnorderedMap const& elements, KEY_TYPE const& handle, SPECIFIC_TYPE* /*obj*/) + { + auto i = elements._element.find(handle); + if (i == elements._element.end()) + return nullptr; + else + return i->second; + } + + template + SPECIFIC_TYPE* Find(ContainerUnorderedMap const& /*elements*/, KEY_TYPE const& /*handle*/, SPECIFIC_TYPE* /*obj*/) + { + return nullptr; + } + + template + SPECIFIC_TYPE* Find(ContainerUnorderedMap const& /*elements*/, KEY_TYPE const& /*handle*/, SPECIFIC_TYPE* /*obj*/) + { + return nullptr; + } + + template + SPECIFIC_TYPE* Find(ContainerUnorderedMap, KEY_TYPE> const& elements, KEY_TYPE const& handle, SPECIFIC_TYPE* /*obj*/) + { + SPECIFIC_TYPE* ret = Find(elements._elements, handle, (SPECIFIC_TYPE*)nullptr); + return ret ? ret : Find(elements._TailElements, handle, (SPECIFIC_TYPE*)nullptr); + } + + // Erase helpers + template + bool Remove(ContainerUnorderedMap& elements, KEY_TYPE const& handle, SPECIFIC_TYPE* /*obj*/) + { + elements._element.erase(handle); + return true; + } + + template + bool Remove(ContainerUnorderedMap& /*elements*/, KEY_TYPE const& /*handle*/, SPECIFIC_TYPE* /*obj*/) + { + return false; + } + + template + bool Remove(ContainerUnorderedMap& /*elements*/, KEY_TYPE const& /*handle*/, SPECIFIC_TYPE* /*obj*/) + { + return false; + } + + template + bool Remove(ContainerUnorderedMap, KEY_TYPE>& elements, KEY_TYPE const& handle, SPECIFIC_TYPE* /*obj*/) + { + bool ret = Remove(elements._elements, handle, (SPECIFIC_TYPE*)nullptr); + return ret ? ret : Remove(elements._TailElements, handle, (SPECIFIC_TYPE*)nullptr); + } + /* ContainerMapList Helpers */ // count functions - template size_t Count(const ContainerMapList &elements, SPECIFIC_TYPE* /*fake*/) + template + size_t Count(ContainerMapList const& elements, SPECIFIC_TYPE* /*fake*/) { return elements._element.getSize(); } - template size_t Count(const ContainerMapList &/*elements*/, SPECIFIC_TYPE* /*fake*/) + template + size_t Count(ContainerMapList const& /*elements*/, SPECIFIC_TYPE* /*fake*/) { return 0; } - template size_t Count(const ContainerMapList &/*elements*/, SPECIFIC_TYPE* /*fake*/) + template + size_t Count(ContainerMapList const& /*elements*/, SPECIFIC_TYPE* /*fake*/) { return 0; } - template size_t Count(const ContainerMapList >&elements, SPECIFIC_TYPE* fake) + template + size_t Count(ContainerMapList> const& elements, SPECIFIC_TYPE* fake) { return Count(elements._elements, fake); } - template size_t Count(const ContainerMapList >&elements, SPECIFIC_TYPE* fake) + template + size_t Count(ContainerMapList> const& elements, SPECIFIC_TYPE* fake) { return Count(elements._TailElements, fake); } // non-const insert functions - template SPECIFIC_TYPE* Insert(ContainerMapList &elements, SPECIFIC_TYPE *obj) + template + SPECIFIC_TYPE* Insert(ContainerMapList& elements, SPECIFIC_TYPE* obj) { //elements._element[hdl] = obj; obj->AddToGrid(elements._element); return obj; } - template SPECIFIC_TYPE* Insert(ContainerMapList &/*elements*/, SPECIFIC_TYPE * /*obj*/) + template + SPECIFIC_TYPE* Insert(ContainerMapList& /*elements*/, SPECIFIC_TYPE* /*obj*/) { - return NULL; + return nullptr; } // this is a missed - template SPECIFIC_TYPE* Insert(ContainerMapList &/*elements*/, SPECIFIC_TYPE * /*obj*/) + template + SPECIFIC_TYPE* Insert(ContainerMapList& /*elements*/, SPECIFIC_TYPE* /*obj*/) { - return NULL; // a missed + return nullptr; // a missed } // Recursion - template SPECIFIC_TYPE* Insert(ContainerMapList >&elements, SPECIFIC_TYPE *obj) + template + SPECIFIC_TYPE* Insert(ContainerMapList>& elements, SPECIFIC_TYPE* obj) { - SPECIFIC_TYPE* t= Insert(elements._elements, obj); - return (t != NULL ? t : Insert(elements._TailElements, obj)); + SPECIFIC_TYPE* t = Insert(elements._elements, obj); + return (t != nullptr ? t : Insert(elements._TailElements, obj)); } //// non-const remove method @@ -93,20 +197,20 @@ namespace Trinity //template SPECIFIC_TYPE* Remove(ContainerMapList &/*elements*/, SPECIFIC_TYPE * /*obj*/) //{ - // return NULL; + // return nullptr; //} //// this is a missed //template SPECIFIC_TYPE* Remove(ContainerMapList &/*elements*/, SPECIFIC_TYPE * /*obj*/) //{ - // return NULL; // a missed + // return nullptr; // a missed //} //template SPECIFIC_TYPE* Remove(ContainerMapList > &elements, SPECIFIC_TYPE *obj) //{ // // The head element is bad // SPECIFIC_TYPE* t = Remove(elements._elements, obj); - // return ( t != NULL ? t : Remove(elements._TailElements, obj) ); + // return (t != nullptr ? t : Remove(elements._TailElements, obj)); //} } #endif diff --git a/src/server/shared/Dynamic/TypeContainerVisitor.h b/src/server/shared/Dynamic/TypeContainerVisitor.h index 514b52d3dfe..e10a2331e25 100644 --- a/src/server/shared/Dynamic/TypeContainerVisitor.h +++ b/src/server/shared/Dynamic/TypeContainerVisitor.h @@ -37,21 +37,6 @@ template void VisitorHelper(VISITOR &v, TYP v.Visit(c); } -// terminate condition for container list -template void VisitorHelper(VISITOR &/*v*/, ContainerList &/*c*/) { } - -template void VisitorHelper(VISITOR &v, ContainerList &c) -{ - v.Visit(c._element); -} - -// recursion for container list -template void VisitorHelper(VISITOR &v, ContainerList > &c) -{ - VisitorHelper(v, c._elements); - VisitorHelper(v, c._TailElements); -} - // terminate condition container map list template void VisitorHelper(VISITOR &/*v*/, ContainerMapList &/*c*/) { } @@ -67,23 +52,31 @@ template void VisitorHelper(VISITOR &v, Contain VisitorHelper(v, c._TailElements); } -// array list -template void VisitorHelper(VISITOR &v, ContainerArrayList &c) +// for TypeMapContainer +template void VisitorHelper(VISITOR &v, TypeMapContainer &c) { - v.Visit(c._element); + VisitorHelper(v, c.GetElements()); } -template void VisitorHelper(VISITOR &/*v*/, ContainerArrayList &/*c*/) { } +// TypeUnorderedMapContainer +template +void VisitorHelper(VISITOR& /*v*/, ContainerUnorderedMap& /*c*/) { } + +template +void VisitorHelper(VISITOR& v, ContainerUnorderedMap& c) +{ + v.Visit(c._element); +} -// recursion -template void VisitorHelper(VISITOR &v, ContainerArrayList > &c) +template +void VisitorHelper(VISITOR& v, ContainerUnorderedMap, KEY_TYPE>& c) { VisitorHelper(v, c._elements); VisitorHelper(v, c._TailElements); } -// for TypeMapContainer -template void VisitorHelper(VISITOR &v, TypeMapContainer &c) +template +void VisitorHelper(VISITOR& v, TypeUnorderedMapContainer& c) { VisitorHelper(v, c.GetElements()); } diff --git a/src/server/shared/Dynamic/TypeList.h b/src/server/shared/Dynamic/TypeList.h index f1ccca9b043..f0355929700 100644 --- a/src/server/shared/Dynamic/TypeList.h +++ b/src/server/shared/Dynamic/TypeList.h @@ -40,5 +40,6 @@ struct TypeList #define TYPELIST_3(T1, T2, T3) TypeList #define TYPELIST_4(T1, T2, T3, T4) TypeList #define TYPELIST_5(T1, T2, T3, T4, T5) TypeList +#define TYPELIST_6(T1, T2, T3, T4, T5, T6) TypeList #endif -- cgit v1.2.3