diff options
| author | Shauren <shauren.trinity@gmail.com> | 2023-01-06 16:54:16 +0100 |
|---|---|---|
| committer | Shauren <shauren.trinity@gmail.com> | 2023-01-06 16:54:16 +0100 |
| commit | e8e330addd55dffa8e34716c7e1969ad243d65b3 (patch) | |
| tree | 2e5cd08a6d1758d9867cc5c4b8aca4591d0e931d /src/server/game/Combat | |
| parent | b65c3f5f4a4edbc953c405bfacd33f186f3a1931 (diff) | |
Core/Misc: Remove boost::heap::fibonacci_heap from header files
Diffstat (limited to 'src/server/game/Combat')
| -rw-r--r-- | src/server/game/Combat/ThreatManager.cpp | 89 | ||||
| -rw-r--r-- | src/server/game/Combat/ThreatManager.h | 49 |
2 files changed, 101 insertions, 37 deletions
diff --git a/src/server/game/Combat/ThreatManager.cpp b/src/server/game/Combat/ThreatManager.cpp index ea41b10e61e..81640f2eca3 100644 --- a/src/server/game/Combat/ThreatManager.cpp +++ b/src/server/game/Combat/ThreatManager.cpp @@ -26,12 +26,17 @@ #include "SpellAuraEffects.h" #include "SpellMgr.h" #include "TemporarySummon.h" +#include <boost/heap/fibonacci_heap.hpp> #include "Hacks/boost_1_74_fibonacci_heap.h" BOOST_1_74_FIBONACCI_HEAP_MSVC_COMPILE_FIX(ThreatManager::threat_list_heap::value_type) const CompareThreatLessThan ThreatManager::CompareThreat; +class ThreatManager::Heap : public boost::heap::fibonacci_heap<ThreatReference const*, boost::heap::compare<CompareThreatLessThan>> +{ +}; + void ThreatReference::AddThreat(float amount) { if (amount == 0.0f) @@ -148,6 +153,24 @@ void ThreatReference::UnregisterAndFree() delete this; } +class ThreatReferenceImpl : public ThreatReference +{ +public: + explicit ThreatReferenceImpl(ThreatManager* mgr, Unit* victim) : ThreatReference(mgr, victim) { } + + ThreatManager::Heap::handle_type _handle; +}; + +void ThreatReference::HeapNotifyIncreased() +{ + _mgr._sortedThreatList->increase(static_cast<ThreatReferenceImpl*>(this)->_handle); +} + +void ThreatReference::HeapNotifyDecreased() +{ + _mgr._sortedThreatList->decrease(static_cast<ThreatReferenceImpl*>(this)->_handle); +} + /*static*/ bool ThreatManager::CanHaveThreatList(Unit const* who) { Creature const* cWho = who->ToCreature(); @@ -168,7 +191,8 @@ void ThreatReference::UnregisterAndFree() return true; } -ThreatManager::ThreatManager(Unit* owner) : _owner(owner), _ownerCanHaveThreatList(false), _needClientUpdate(false), _updateTimer(THREAT_UPDATE_INTERVAL), _currentVictimRef(nullptr), _fixateRef(nullptr) +ThreatManager::ThreatManager(Unit* owner) : _owner(owner), _ownerCanHaveThreatList(false), _needClientUpdate(false), _updateTimer(THREAT_UPDATE_INTERVAL), + _sortedThreatList(std::make_unique<Heap>()), _currentVictimRef(nullptr), _fixateRef(nullptr) { for (int8 i = 0; i < MAX_SPELL_SCHOOL; ++i) _singleSchoolModifiers[i] = 1.0f; @@ -177,7 +201,7 @@ ThreatManager::ThreatManager(Unit* owner) : _owner(owner), _ownerCanHaveThreatLi ThreatManager::~ThreatManager() { ASSERT(_myThreatListEntries.empty(), "ThreatManager::~ThreatManager - %s: we still have %zu things threatening us, one of them is %s.", _owner->GetGUID().ToString().c_str(), _myThreatListEntries.size(), _myThreatListEntries.begin()->first.ToString().c_str()); - ASSERT(_sortedThreatList.empty(), "ThreatManager::~ThreatManager - %s: we still have %zu things threatening us, one of them is %s.", _owner->GetGUID().ToString().c_str(), _sortedThreatList.size(), (*_sortedThreatList.begin())->GetVictim()->GetGUID().ToString().c_str()); + ASSERT(_sortedThreatList->empty(), "ThreatManager::~ThreatManager - %s: we still have %zu things threatening us, one of them is %s.", _owner->GetGUID().ToString().c_str(), _sortedThreatList->size(), (*_sortedThreatList->begin())->GetVictim()->GetGUID().ToString().c_str()); ASSERT(_threatenedByMe.empty(), "ThreatManager::~ThreatManager - %s: we are still threatening %zu things, one of them is %s.", _owner->GetGUID().ToString().c_str(), _threatenedByMe.size(), _threatenedByMe.begin()->first.ToString().c_str()); } @@ -216,7 +240,7 @@ Unit* ThreatManager::GetLastVictim() const Unit* ThreatManager::GetAnyTarget() const { - for (ThreatReference const* ref : _sortedThreatList) + for (ThreatReference const* ref : *_sortedThreatList) if (!ref->IsOffline()) return ref->GetVictim(); return nullptr; @@ -225,8 +249,8 @@ Unit* ThreatManager::GetAnyTarget() const bool ThreatManager::IsThreatListEmpty(bool includeOffline) const { if (includeOffline) - return _sortedThreatList.empty(); - for (ThreatReference const* ref : _sortedThreatList) + return _sortedThreatList->empty(); + for (ThreatReference const* ref : *_sortedThreatList) if (ref->IsAvailable()) return false; return true; @@ -249,11 +273,44 @@ float ThreatManager::GetThreat(Unit const* who, bool includeOffline) const return (includeOffline || it->second->IsAvailable()) ? it->second->GetThreat() : 0.0f; } +size_t ThreatManager::GetThreatListSize() const +{ + return _sortedThreatList->size(); +} + +Trinity::IteratorPair<ThreatManager::ThreatListIterator, std::nullptr_t> ThreatManager::GetUnsortedThreatList() const +{ + auto itr = _myThreatListEntries.begin(); + auto end = _myThreatListEntries.end(); + std::function<ThreatReference const* ()> generator = [itr, end]() mutable -> ThreatReference const* + { + if (itr == end) + return nullptr; + + return (itr++)->second; + }; + return { ThreatListIterator{ std::move(generator) }, nullptr }; +} + +Trinity::IteratorPair<ThreatManager::ThreatListIterator, std::nullptr_t> ThreatManager::GetSortedThreatList() const +{ + auto itr = _sortedThreatList->ordered_begin(); + auto end = _sortedThreatList->ordered_end(); + std::function<ThreatReference const* ()> generator = [itr, end]() mutable -> ThreatReference const* + { + if (itr == end) + return nullptr; + + return *(itr++); + }; + return { ThreatListIterator{ std::move(generator) }, nullptr }; +} + std::vector<ThreatReference*> ThreatManager::GetModifiableThreatList() { std::vector<ThreatReference*> list; list.reserve(_myThreatListEntries.size()); - for (auto it = _sortedThreatList.ordered_begin(), end = _sortedThreatList.ordered_end(); it != end; ++it) + for (auto it = _sortedThreatList->ordered_begin(), end = _sortedThreatList->ordered_end(); it != end; ++it) list.push_back(const_cast<ThreatReference*>(*it)); return list; } @@ -395,7 +452,7 @@ void ThreatManager::AddThreat(Unit* target, float amount, SpellInfo const* spell } // ok, we're now in combat - create the threat list reference and push it to the respective managers - ThreatReference* ref = new ThreatReference(this, target); + ThreatReference* ref = new ThreatReferenceImpl(this, target); PutThreatListRef(target->GetGUID(), ref); target->GetThreatManager().PutThreatenedByMeRef(_owner->GetGUID(), ref); @@ -418,10 +475,10 @@ void ThreatManager::ScaleThreat(Unit* target, float factor) void ThreatManager::MatchUnitThreatToHighestThreat(Unit* target) { - if (_sortedThreatList.empty()) + if (_sortedThreatList->empty()) return; - auto it = _sortedThreatList.ordered_begin(), end = _sortedThreatList.ordered_end(); + auto it = _sortedThreatList->ordered_begin(), end = _sortedThreatList->ordered_end(); ThreatReference const* highest = *it; if (!highest->IsAvailable()) return; @@ -530,7 +587,7 @@ void ThreatManager::UpdateVictim() ThreatReference const* ThreatManager::ReselectVictim() { - if (_sortedThreatList.empty()) + if (_sortedThreatList->empty()) return nullptr; for (auto const& pair : _myThreatListEntries) @@ -544,7 +601,7 @@ ThreatReference const* ThreatManager::ReselectVictim() if (oldVictimRef && oldVictimRef->IsOffline()) oldVictimRef = nullptr; // in 99% of cases - we won't need to actually look at anything beyond the first element - ThreatReference const* highest = _sortedThreatList.top(); + ThreatReference const* highest = _sortedThreatList->top(); // if the highest reference is offline, the entire list is offline, and we indicate this if (!highest->IsAvailable()) return nullptr; @@ -562,7 +619,7 @@ ThreatReference const* ThreatManager::ReselectVictim() return highest; // If we get here, highest threat is ranged, but below 130% of current - there might be a melee that breaks 110% below us somewhere, so now we need to actually look at the next highest element // luckily, this is a heap, so getting the next highest element is O(log n), and we're just gonna do that repeatedly until we've seen enough targets (or find a target) - auto it = _sortedThreatList.ordered_begin(), end = _sortedThreatList.ordered_end(); + auto it = _sortedThreatList->ordered_begin(), end = _sortedThreatList->ordered_end(); while (it != end) { ThreatReference const* next = *it; @@ -772,8 +829,8 @@ void ThreatManager::SendThreatListToClients(bool newHighest) const auto fillSharedPacketDataAndSend = [&](auto& packet) { packet.UnitGUID = _owner->GetGUID(); - packet.ThreatList.reserve(_sortedThreatList.size()); - for (ThreatReference const* ref : _sortedThreatList) + packet.ThreatList.reserve(_sortedThreatList->size()); + for (ThreatReference const* ref : *_sortedThreatList) { if (!ref->IsAvailable()) continue; @@ -805,7 +862,7 @@ void ThreatManager::PutThreatListRef(ObjectGuid const& guid, ThreatReference* re auto& inMap = _myThreatListEntries[guid]; ASSERT(!inMap, "Duplicate threat reference at %p being inserted on %s for %s - memory leak!", ref, _owner->GetGUID().ToString().c_str(), guid.ToString().c_str()); inMap = ref; - ref->_handle = _sortedThreatList.push(ref); + static_cast<ThreatReferenceImpl*>(ref)->_handle = _sortedThreatList->push(ref); } void ThreatManager::PurgeThreatListRef(ObjectGuid const& guid) @@ -815,7 +872,7 @@ void ThreatManager::PurgeThreatListRef(ObjectGuid const& guid) return; ThreatReference* ref = it->second; _myThreatListEntries.erase(it); - _sortedThreatList.erase(ref->_handle); + _sortedThreatList->erase(static_cast<ThreatReferenceImpl*>(ref)->_handle); if (_fixateRef == ref) _fixateRef = nullptr; diff --git a/src/server/game/Combat/ThreatManager.h b/src/server/game/Combat/ThreatManager.h index 8e722707f91..36885802068 100644 --- a/src/server/game/Combat/ThreatManager.h +++ b/src/server/game/Combat/ThreatManager.h @@ -22,7 +22,6 @@ #include "IteratorPair.h" #include "ObjectGuid.h" #include "SharedDefines.h" -#include <boost/heap/fibonacci_heap.hpp> #include <array> #include <unordered_map> #include <vector> @@ -81,7 +80,7 @@ struct CompareThreatLessThan class TC_GAME_API ThreatManager { public: - typedef boost::heap::fibonacci_heap<ThreatReference const*, boost::heap::compare<CompareThreatLessThan>> threat_list_heap; + class Heap; class ThreatListIterator; static const uint32 THREAT_UPDATE_INTERVAL = 1000u; @@ -115,14 +114,14 @@ class TC_GAME_API ThreatManager bool IsThreatenedBy(Unit const* who, bool includeOffline = false) const; // returns ThreatReference amount if a ref exists, 0.0f otherwise float GetThreat(Unit const* who, bool includeOffline = false) const; - size_t GetThreatListSize() const { return _sortedThreatList.size(); } + size_t GetThreatListSize() const; // fastest of the three threat list getters - gets the threat list in "arbitrary" order // iterators will invalidate on adding/removing entries from the threat list; slightly less finicky than GetSorted. - Trinity::IteratorPair<ThreatListIterator> GetUnsortedThreatList() const { return { _myThreatListEntries.begin(), _myThreatListEntries.end() }; } + Trinity::IteratorPair<ThreatListIterator, std::nullptr_t> GetUnsortedThreatList() const; // slightly slower than GetUnsorted, but, well...sorted - only use it if you need the sorted property, of course // this iterator pair will invalidate on any modification (even indirect) of the threat list; spell casts and similar can all induce this! // note: current tank is NOT guaranteed to be the first entry in this list - check GetLastVictim separately if you want that! - Trinity::IteratorPair<threat_list_heap::ordered_iterator> GetSortedThreatList() const { return { _sortedThreatList.ordered_begin(), _sortedThreatList.ordered_end() }; } + Trinity::IteratorPair<ThreatListIterator, std::nullptr_t> GetSortedThreatList() const; // slowest of the three threat list getters (by far), but lets you modify the threat references - this is also sorted std::vector<ThreatReference*> GetModifiableThreatList(); @@ -198,7 +197,7 @@ class TC_GAME_API ThreatManager bool _needClientUpdate; uint32 _updateTimer; - threat_list_heap _sortedThreatList; + std::unique_ptr<Heap> _sortedThreatList; std::unordered_map<ObjectGuid, ThreatReference*> _myThreatListEntries; // AI notifies are delayed to ensure we are in a consistent state before we call out to arbitrary logic @@ -231,19 +230,26 @@ class TC_GAME_API ThreatManager class ThreatListIterator { - private: - decltype(_myThreatListEntries)::const_iterator _it; - - public: - ThreatReference const* operator*() const { return _it->second; } - ThreatReference const* operator->() const { return _it->second; } - ThreatListIterator& operator++() { ++_it; return *this; } - bool operator==(ThreatListIterator const& o) const { return _it == o._it; } - bool operator!=(ThreatListIterator const& o) const { return _it != o._it; } - ThreatListIterator(decltype(_it) it) : _it(it) {} + private: + std::function<ThreatReference const* ()> _generator; + ThreatReference const* _current; + + friend ThreatManager; + explicit ThreatListIterator(std::function<ThreatReference const* ()>&& generator) + : _generator(std::move(generator)), _current(_generator()) {} + + public: + ThreatReference const* operator*() const { return _current; } + ThreatReference const* operator->() const { return _current; } + ThreatListIterator& operator++() { _current = _generator(); return *this; } + bool operator==(ThreatListIterator const& o) const { return _current == o._current; } + bool operator!=(ThreatListIterator const& o) const { return _current != o._current; } + bool operator==(std::nullptr_t) const { return _current == nullptr; } + bool operator!=(std::nullptr_t) const { return _current != nullptr; } }; friend class ThreatReference; + friend class ThreatReferenceImpl; friend struct CompareThreatLessThan; friend class debug_commandscript; }; @@ -274,16 +280,18 @@ class TC_GAME_API ThreatReference void ClearThreat(); // dealloc's this - private: + protected: static bool FlagsAllowFighting(Unit const* a, Unit const* b); - ThreatReference(ThreatManager* mgr, Unit* victim) : + explicit ThreatReference(ThreatManager* mgr, Unit* victim) : _owner(reinterpret_cast<Creature*>(mgr->_owner)), _mgr(*mgr), _victim(victim), _baseAmount(0.0f), _tempModifier(0), _taunted(TAUNT_STATE_NONE) { _online = ONLINE_STATE_OFFLINE; } + virtual ~ThreatReference() = default; + void UnregisterAndFree(); bool ShouldBeOffline() const; @@ -291,14 +299,13 @@ class TC_GAME_API ThreatReference void UpdateTauntState(TauntState state = TAUNT_STATE_NONE); Creature* const _owner; ThreatManager& _mgr; - void HeapNotifyIncreased() { _mgr._sortedThreatList.increase(_handle); } - void HeapNotifyDecreased() { _mgr._sortedThreatList.decrease(_handle); } + void HeapNotifyIncreased(); + void HeapNotifyDecreased(); Unit* const _victim; OnlineState _online; float _baseAmount; int32 _tempModifier; // Temporary effects (auras with SPELL_AURA_MOD_TOTAL_THREAT) - set from victim's threatmanager in ThreatManager::UpdateMyTempModifiers TauntState _taunted; - ThreatManager::threat_list_heap::handle_type _handle; public: ThreatReference(ThreatReference const&) = delete; |
