mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-19 08:55:32 +01:00
Core/Misc: fix interaction of spells like Shadowmeld with Threat reducing effects
- SPELL_AURA_MOD_TOTAL_THREAT should be temporary and not added/subtracted from total, only computed
- Cleanup of reference related code
- Kill getLast() and reverse iterator obsevers, LinkedList iterator can't be used as a standard reverse_iterator (ie with operator++). They weren't used anyways
(cherry picked from commit 3b6fd226be)
# Conflicts:
# src/server/game/Combat/ThreatManager.cpp
# src/server/game/Loot/LootMgr.h
This commit is contained in:
@@ -28,8 +28,8 @@ HostileRefManager::~HostileRefManager()
|
||||
}
|
||||
|
||||
//=================================================
|
||||
// send threat to all my hateres for the victim
|
||||
// The victim is hated than by them as well
|
||||
// send threat to all my haters for the victim
|
||||
// The victim is then hated by them as well
|
||||
// use for buffs and healing threat functionality
|
||||
|
||||
void HostileRefManager::threatAssist(Unit* victim, float baseThreat, SpellInfo const* threatSpell)
|
||||
@@ -37,9 +37,10 @@ void HostileRefManager::threatAssist(Unit* victim, float baseThreat, SpellInfo c
|
||||
if (getSize() == 0)
|
||||
return;
|
||||
|
||||
HostileReference* ref = getFirst();
|
||||
float threat = ThreatCalcHelper::calcThreat(victim, iOwner, baseThreat, (threatSpell ? threatSpell->GetSchoolMask() : SPELL_SCHOOL_MASK_NORMAL), threatSpell);
|
||||
threat /= getSize();
|
||||
|
||||
HostileReference* ref = getFirst();
|
||||
while (ref)
|
||||
{
|
||||
if (ThreatCalcHelper::isValidProcess(victim, ref->GetSource()->GetOwner(), threatSpell))
|
||||
@@ -54,7 +55,6 @@ void HostileRefManager::threatAssist(Unit* victim, float baseThreat, SpellInfo c
|
||||
void HostileRefManager::addTempThreat(float threat, bool apply)
|
||||
{
|
||||
HostileReference* ref = getFirst();
|
||||
|
||||
while (ref)
|
||||
{
|
||||
if (apply)
|
||||
|
||||
@@ -31,18 +31,16 @@ class SpellInfo;
|
||||
|
||||
class TC_GAME_API HostileRefManager : public RefManager<Unit, ThreatManager>
|
||||
{
|
||||
private:
|
||||
Unit* iOwner;
|
||||
public:
|
||||
explicit HostileRefManager(Unit* owner) { iOwner = owner; }
|
||||
explicit HostileRefManager(Unit* owner) : iOwner(owner) { }
|
||||
~HostileRefManager();
|
||||
|
||||
Unit* GetOwner() { return iOwner; }
|
||||
Unit* GetOwner() const { return iOwner; }
|
||||
|
||||
// send threat to all my hateres for the victim
|
||||
// The victim is hated than by them as well
|
||||
// use for buffs and healing threat functionality
|
||||
void threatAssist(Unit* victim, float baseThreat, SpellInfo const* threatSpell = NULL);
|
||||
void threatAssist(Unit* victim, float baseThreat, SpellInfo const* threatSpell = nullptr);
|
||||
|
||||
void addTempThreat(float threat, bool apply);
|
||||
|
||||
@@ -68,6 +66,9 @@ class TC_GAME_API HostileRefManager : public RefManager<Unit, ThreatManager>
|
||||
void deleteReference(Unit* creature);
|
||||
|
||||
void UpdateVisibility();
|
||||
|
||||
private:
|
||||
Unit* iOwner;
|
||||
};
|
||||
//=================================================
|
||||
#endif
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
//==============================================================
|
||||
|
||||
// The hatingUnit is not used yet
|
||||
float ThreatCalcHelper::calcThreat(Unit* hatedUnit, Unit* /*hatingUnit*/, float threat, SpellSchoolMask schoolMask, SpellInfo const* threatSpell)
|
||||
float ThreatCalcHelper::calcThreat(Unit* hatedUnit, Unit* /*hatingUnit*/, float threat, SpellSchoolMask schoolMask, SpellInfo const* threatSpell /*= nullptr*/)
|
||||
{
|
||||
if (threatSpell)
|
||||
{
|
||||
@@ -40,7 +40,7 @@ float ThreatCalcHelper::calcThreat(Unit* hatedUnit, Unit* /*hatingUnit*/, float
|
||||
threat *= threatEntry->pctMod;
|
||||
|
||||
// Energize is not affected by Mods
|
||||
for (SpellEffectInfo const* effect : threatSpell->GetEffectsForDifficulty(hatedUnit->GetMap()->GetDifficultyID()))
|
||||
for (SpellEffectInfo const* effect : threatSpell->GetEffectsForDifficulty(hatedUnit->GetMap()->GetDifficultyID()))
|
||||
if (effect && (effect->Effect == SPELL_EFFECT_ENERGIZE || effect->ApplyAuraName == SPELL_AURA_PERIODIC_ENERGIZE))
|
||||
return threat;
|
||||
|
||||
@@ -51,7 +51,7 @@ float ThreatCalcHelper::calcThreat(Unit* hatedUnit, Unit* /*hatingUnit*/, float
|
||||
return hatedUnit->ApplyTotalThreatModifier(threat, schoolMask);
|
||||
}
|
||||
|
||||
bool ThreatCalcHelper::isValidProcess(Unit* hatedUnit, Unit* hatingUnit, SpellInfo const* threatSpell)
|
||||
bool ThreatCalcHelper::isValidProcess(Unit* hatedUnit, Unit* hatingUnit, SpellInfo const* threatSpell /*= nullptr*/)
|
||||
{
|
||||
//function deals with adding threat and adding players and pets into ThreatList
|
||||
//mobs, NPCs, guards have ThreatList and HateOfflineList
|
||||
@@ -135,18 +135,20 @@ void HostileReference::fireStatusChanged(ThreatRefStatusChangeEvent& threatRefSt
|
||||
|
||||
void HostileReference::addThreat(float modThreat)
|
||||
{
|
||||
if (!modThreat)
|
||||
return;
|
||||
|
||||
iThreat += modThreat;
|
||||
|
||||
// the threat is changed. Source and target unit have to be available
|
||||
// if the link was cut before relink it again
|
||||
if (!isOnline())
|
||||
updateOnlineStatus();
|
||||
if (modThreat != 0.0f)
|
||||
{
|
||||
ThreatRefStatusChangeEvent event(UEV_THREAT_REF_THREAT_CHANGE, this, modThreat);
|
||||
fireStatusChanged(event);
|
||||
}
|
||||
|
||||
if (isValid() && modThreat >= 0.0f)
|
||||
ThreatRefStatusChangeEvent event(UEV_THREAT_REF_THREAT_CHANGE, this, modThreat);
|
||||
fireStatusChanged(event);
|
||||
|
||||
if (isValid() && modThreat > 0.0f)
|
||||
{
|
||||
Unit* victimOwner = getTarget()->GetCharmerOrOwner();
|
||||
if (victimOwner && victimOwner->IsAlive())
|
||||
@@ -156,9 +158,7 @@ void HostileReference::addThreat(float modThreat)
|
||||
|
||||
void HostileReference::addThreatPercent(int32 percent)
|
||||
{
|
||||
float tmpThreat = iThreat;
|
||||
AddPct(tmpThreat, percent);
|
||||
addThreat(tmpThreat - iThreat);
|
||||
addThreat(CalculatePct(iThreat, percent));
|
||||
}
|
||||
|
||||
//============================================================
|
||||
@@ -194,6 +194,7 @@ void HostileReference::updateOnlineStatus()
|
||||
else
|
||||
accessible = true;
|
||||
}
|
||||
|
||||
setAccessibleState(accessible);
|
||||
setOnlineOfflineState(online);
|
||||
}
|
||||
@@ -222,7 +223,7 @@ void HostileReference::setAccessibleState(bool isAccessible)
|
||||
{
|
||||
iAccessible = isAccessible;
|
||||
|
||||
ThreatRefStatusChangeEvent event(UEV_THREAT_REF_ASSECCIBLE_STATUS, this);
|
||||
ThreatRefStatusChangeEvent event(UEV_THREAT_REF_ACCESSIBLE_STATUS, this);
|
||||
fireStatusChanged(event);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,8 +41,8 @@ class SpellInfo;
|
||||
|
||||
struct TC_GAME_API ThreatCalcHelper
|
||||
{
|
||||
static float calcThreat(Unit* hatedUnit, Unit* hatingUnit, float threat, SpellSchoolMask schoolMask = SPELL_SCHOOL_MASK_NORMAL, SpellInfo const* threatSpell = NULL);
|
||||
static bool isValidProcess(Unit* hatedUnit, Unit* hatingUnit, SpellInfo const* threatSpell = NULL);
|
||||
static float calcThreat(Unit* hatedUnit, Unit* hatingUnit, float threat, SpellSchoolMask schoolMask = SPELL_SCHOOL_MASK_NORMAL, SpellInfo const* threatSpell = nullptr);
|
||||
static bool isValidProcess(Unit* hatedUnit, Unit* hatingUnit, SpellInfo const* threatSpell = nullptr);
|
||||
};
|
||||
|
||||
//==============================================================
|
||||
@@ -54,11 +54,11 @@ class TC_GAME_API HostileReference : public Reference<Unit, ThreatManager>
|
||||
//=================================================
|
||||
void addThreat(float modThreat);
|
||||
|
||||
void setThreat(float threat) { addThreat(threat - getThreat()); }
|
||||
void setThreat(float threat) { addThreat(threat - iThreat); }
|
||||
|
||||
void addThreatPercent(int32 percent);
|
||||
|
||||
float getThreat() const { return iThreat; }
|
||||
float getThreat() const { return iThreat + iTempThreatModifier; }
|
||||
|
||||
bool isOnline() const { return iOnline; }
|
||||
|
||||
@@ -66,27 +66,27 @@ class TC_GAME_API HostileReference : public Reference<Unit, ThreatManager>
|
||||
// in this case online = true, but accessible = false
|
||||
bool isAccessible() const { return iAccessible; }
|
||||
|
||||
// used for temporary setting a threat and reducting it later again.
|
||||
// used for temporary setting a threat and reducing it later again.
|
||||
// the threat modification is stored
|
||||
void setTempThreat(float threat)
|
||||
{
|
||||
addTempThreat(threat - getThreat());
|
||||
addTempThreat(threat - iTempThreatModifier);
|
||||
}
|
||||
|
||||
void addTempThreat(float threat)
|
||||
{
|
||||
iTempThreatModifier = threat;
|
||||
if (iTempThreatModifier != 0.0f)
|
||||
addThreat(iTempThreatModifier);
|
||||
if (!threat)
|
||||
return;
|
||||
|
||||
iTempThreatModifier += threat;
|
||||
|
||||
ThreatRefStatusChangeEvent event(UEV_THREAT_REF_THREAT_CHANGE, this, threat);
|
||||
fireStatusChanged(event);
|
||||
}
|
||||
|
||||
void resetTempThreat()
|
||||
{
|
||||
if (iTempThreatModifier != 0.0f)
|
||||
{
|
||||
addThreat(-iTempThreatModifier);
|
||||
iTempThreatModifier = 0.0f;
|
||||
}
|
||||
addTempThreat(-iTempThreatModifier);
|
||||
}
|
||||
|
||||
float getTempThreatModifier() { return iTempThreatModifier; }
|
||||
@@ -100,7 +100,7 @@ class TC_GAME_API HostileReference : public Reference<Unit, ThreatManager>
|
||||
void setAccessibleState(bool isAccessible);
|
||||
//=================================================
|
||||
|
||||
bool operator == (const HostileReference& hostileRef) const { return hostileRef.getUnitGuid() == getUnitGuid(); }
|
||||
bool operator==(HostileReference const& hostileRef) const { return hostileRef.getUnitGuid() == getUnitGuid(); }
|
||||
|
||||
//=================================================
|
||||
|
||||
@@ -113,7 +113,7 @@ class TC_GAME_API HostileReference : public Reference<Unit, ThreatManager>
|
||||
|
||||
//=================================================
|
||||
|
||||
HostileReference* next() { return ((HostileReference*) Reference<Unit, ThreatManager>::next()); }
|
||||
HostileReference* next() { return static_cast<HostileReference*>(Reference<Unit, ThreatManager>::next()); }
|
||||
|
||||
//=================================================
|
||||
|
||||
@@ -125,14 +125,17 @@ class TC_GAME_API HostileReference : public Reference<Unit, ThreatManager>
|
||||
|
||||
// Tell our refFrom (source) object, that the link is cut (Target destroyed)
|
||||
void sourceObjectDestroyLink() override;
|
||||
|
||||
private:
|
||||
// Inform the source, that the status of that reference was changed
|
||||
void fireStatusChanged(ThreatRefStatusChangeEvent& threatRefStatusChangeEvent);
|
||||
|
||||
Unit* GetSourceUnit();
|
||||
|
||||
private:
|
||||
float iThreat;
|
||||
float iTempThreatModifier; // used for taunt
|
||||
float iTempThreatModifier; // used for SPELL_AURA_MOD_TOTAL_THREAT
|
||||
|
||||
ObjectGuid iUnitGuid;
|
||||
bool iOnline;
|
||||
bool iAccessible;
|
||||
|
||||
@@ -40,7 +40,7 @@ enum UNIT_EVENT_TYPE
|
||||
UEV_THREAT_REF_REMOVE_FROM_LIST = 1<<2,
|
||||
|
||||
// Player/Pet entered/left water or some other place where it is/was not accessible for the creature
|
||||
UEV_THREAT_REF_ASSECCIBLE_STATUS = 1<<3,
|
||||
UEV_THREAT_REF_ACCESSIBLE_STATUS = 1<<3,
|
||||
|
||||
// Threat list is going to be sorted (if dirty flag is set)
|
||||
UEV_THREAT_SORT_LIST = 1<<4,
|
||||
@@ -58,7 +58,7 @@ enum UNIT_EVENT_TYPE
|
||||
//UEV_UNIT_HEALTH_CHANGE = 1<<8,
|
||||
};
|
||||
|
||||
#define UEV_THREAT_REF_EVENT_MASK (UEV_THREAT_REF_ONLINE_STATUS | UEV_THREAT_REF_THREAT_CHANGE | UEV_THREAT_REF_REMOVE_FROM_LIST | UEV_THREAT_REF_ASSECCIBLE_STATUS)
|
||||
#define UEV_THREAT_REF_EVENT_MASK (UEV_THREAT_REF_ONLINE_STATUS | UEV_THREAT_REF_THREAT_CHANGE | UEV_THREAT_REF_REMOVE_FROM_LIST | UEV_THREAT_REF_ACCESSIBLE_STATUS)
|
||||
#define UEV_THREAT_MANAGER_EVENT_MASK (UEV_THREAT_SORT_LIST | UEV_THREAT_SET_NEXT_TARGET | UEV_THREAT_VICTIM_CHANGED)
|
||||
#define UEV_ALL_EVENT_MASK (0xffffffff)
|
||||
|
||||
@@ -69,14 +69,16 @@ enum UNIT_EVENT_TYPE
|
||||
|
||||
class UnitBaseEvent
|
||||
{
|
||||
private:
|
||||
uint32 iType;
|
||||
public:
|
||||
UnitBaseEvent(uint32 pType) { iType = pType; }
|
||||
explicit UnitBaseEvent(uint32 pType) { iType = pType; }
|
||||
uint32 getType() const { return iType; }
|
||||
bool matchesTypeMask(uint32 pMask) const { return (iType & pMask) != 0; }
|
||||
|
||||
void setType(uint32 pType) { iType = pType; }
|
||||
private:
|
||||
uint32 iType;
|
||||
|
||||
protected:
|
||||
~UnitBaseEvent() { }
|
||||
};
|
||||
|
||||
//==============================================================
|
||||
@@ -92,14 +94,15 @@ class TC_GAME_API ThreatRefStatusChangeEvent : public UnitBaseEvent
|
||||
bool iBValue;
|
||||
};
|
||||
ThreatManager* iThreatManager;
|
||||
|
||||
public:
|
||||
ThreatRefStatusChangeEvent(uint32 pType) : UnitBaseEvent(pType), iThreatManager(NULL) { iHostileReference = NULL; }
|
||||
explicit ThreatRefStatusChangeEvent(uint32 pType) : UnitBaseEvent(pType), iHostileReference(nullptr), iThreatManager(nullptr) { }
|
||||
|
||||
ThreatRefStatusChangeEvent(uint32 pType, HostileReference* pHostileReference) : UnitBaseEvent(pType), iThreatManager(NULL) { iHostileReference = pHostileReference; }
|
||||
ThreatRefStatusChangeEvent(uint32 pType, HostileReference* pHostileReference) : UnitBaseEvent(pType), iHostileReference(pHostileReference), iThreatManager(nullptr) { }
|
||||
|
||||
ThreatRefStatusChangeEvent(uint32 pType, HostileReference* pHostileReference, float pValue) : UnitBaseEvent(pType), iThreatManager(NULL) { iHostileReference = pHostileReference; iFValue = pValue; }
|
||||
ThreatRefStatusChangeEvent(uint32 pType, HostileReference* pHostileReference, float pValue) : UnitBaseEvent(pType), iHostileReference(pHostileReference), iFValue(pValue), iThreatManager(nullptr) { }
|
||||
|
||||
ThreatRefStatusChangeEvent(uint32 pType, HostileReference* pHostileReference, bool pValue) : UnitBaseEvent(pType), iThreatManager(NULL) { iHostileReference = pHostileReference; iBValue = pValue; }
|
||||
ThreatRefStatusChangeEvent(uint32 pType, HostileReference* pHostileReference, bool pValue) : UnitBaseEvent(pType), iHostileReference(pHostileReference), iBValue(pValue), iThreatManager(nullptr) { }
|
||||
|
||||
int32 getIValue() const { return iIValue; }
|
||||
|
||||
@@ -116,20 +119,4 @@ class TC_GAME_API ThreatRefStatusChangeEvent : public UnitBaseEvent
|
||||
ThreatManager* getThreatManager() const { return iThreatManager; }
|
||||
};
|
||||
|
||||
//==============================================================
|
||||
|
||||
class ThreatManagerEvent : public ThreatRefStatusChangeEvent
|
||||
{
|
||||
private:
|
||||
ThreatContainer* iThreatContainer;
|
||||
public:
|
||||
ThreatManagerEvent(uint32 pType) : ThreatRefStatusChangeEvent(pType), iThreatContainer(NULL) { }
|
||||
ThreatManagerEvent(uint32 pType, HostileReference* pHostileReference) : ThreatRefStatusChangeEvent(pType, pHostileReference), iThreatContainer(NULL) { }
|
||||
|
||||
void setThreatContainer(ThreatContainer* pThreatContainer) { iThreatContainer = pThreatContainer; }
|
||||
|
||||
ThreatContainer* getThreatContainer() const { return iThreatContainer; }
|
||||
};
|
||||
|
||||
//==============================================================
|
||||
#endif
|
||||
|
||||
@@ -35,7 +35,5 @@ class GridRefManager : public RefManager<GridRefManager<OBJECT>, OBJECT>
|
||||
|
||||
iterator begin() { return iterator(getFirst()); }
|
||||
iterator end() { return iterator(NULL); }
|
||||
iterator rbegin() { return iterator(getLast()); }
|
||||
iterator rend() { return iterator(NULL); }
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -199,12 +199,9 @@ public:
|
||||
typedef LinkedListHead::Iterator<LootValidatorRef> iterator;
|
||||
|
||||
LootValidatorRef* getFirst() { return (LootValidatorRef*)RefManager<Loot, LootValidatorRef>::getFirst(); }
|
||||
LootValidatorRef* getLast() { return (LootValidatorRef*)RefManager<Loot, LootValidatorRef>::getLast(); }
|
||||
|
||||
iterator begin() { return iterator(getFirst()); }
|
||||
iterator end() { return iterator(NULL); }
|
||||
iterator rbegin() { return iterator(getLast()); }
|
||||
iterator rend() { return iterator(NULL); }
|
||||
iterator end() { return iterator(nullptr); }
|
||||
};
|
||||
|
||||
//=====================================================
|
||||
|
||||
@@ -131,8 +131,8 @@ class TC_GAME_API LootTemplate
|
||||
LootGroups Groups; // groups have own (optimised) processing, grouped entries go there
|
||||
|
||||
// Objects of this class must never be copied, we are storing pointers in container
|
||||
LootTemplate(LootTemplate const&);
|
||||
LootTemplate& operator=(LootTemplate const&);
|
||||
LootTemplate(LootTemplate const&) = delete;
|
||||
LootTemplate& operator=(LootTemplate const&) = delete;
|
||||
};
|
||||
|
||||
//=====================================================
|
||||
|
||||
@@ -26,20 +26,17 @@ class MapReference;
|
||||
class MapRefManager : public RefManager<Map, Player>
|
||||
{
|
||||
public:
|
||||
typedef LinkedListHead::Iterator< MapReference > iterator;
|
||||
typedef LinkedListHead::Iterator< MapReference const > const_iterator;
|
||||
typedef LinkedListHead::Iterator<MapReference> iterator;
|
||||
typedef LinkedListHead::Iterator<MapReference const> const_iterator;
|
||||
|
||||
MapReference* getFirst() { return (MapReference*)RefManager<Map, Player>::getFirst(); }
|
||||
MapReference* getFirst() { return (MapReference*)RefManager<Map, Player>::getFirst(); }
|
||||
MapReference const* getFirst() const { return (MapReference const*)RefManager<Map, Player>::getFirst(); }
|
||||
MapReference* getLast() { return (MapReference*)RefManager<Map, Player>::getLast(); }
|
||||
MapReference const* getLast() const { return (MapReference const*)RefManager<Map, Player>::getLast(); }
|
||||
|
||||
iterator begin() { return iterator(getFirst()); }
|
||||
iterator end() { return iterator(NULL); }
|
||||
iterator rbegin() { return iterator(getLast()); }
|
||||
iterator rend() { return iterator(NULL); }
|
||||
iterator end() { return iterator(nullptr); }
|
||||
|
||||
const_iterator begin() const { return const_iterator(getFirst()); }
|
||||
const_iterator end() const { return const_iterator(NULL); }
|
||||
const_iterator end() const { return const_iterator(nullptr); }
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
@@ -32,18 +32,18 @@ class LinkedListElement
|
||||
|
||||
LinkedListElement* iNext;
|
||||
LinkedListElement* iPrev;
|
||||
|
||||
public:
|
||||
LinkedListElement() : iNext(NULL), iPrev(NULL) { }
|
||||
virtual ~LinkedListElement() { delink(); }
|
||||
LinkedListElement() : iNext(nullptr), iPrev(nullptr) { }
|
||||
|
||||
bool hasNext() const { return(iNext && iNext->iNext != NULL); }
|
||||
bool hasPrev() const { return(iPrev && iPrev->iPrev != NULL); }
|
||||
bool isInList() const { return(iNext != NULL && iPrev != NULL); }
|
||||
bool hasNext() const { return (iNext && iNext->iNext != nullptr); }
|
||||
bool hasPrev() const { return (iPrev && iPrev->iPrev != nullptr); }
|
||||
bool isInList() const { return (iNext != nullptr && iPrev != nullptr); }
|
||||
|
||||
LinkedListElement * next() { return hasNext() ? iNext : NULL; }
|
||||
LinkedListElement const* next() const { return hasNext() ? iNext : NULL; }
|
||||
LinkedListElement * prev() { return hasPrev() ? iPrev : NULL; }
|
||||
LinkedListElement const* prev() const { return hasPrev() ? iPrev : NULL; }
|
||||
LinkedListElement * next() { return hasNext() ? iNext : nullptr; }
|
||||
LinkedListElement const* next() const { return hasNext() ? iNext : nullptr; }
|
||||
LinkedListElement * prev() { return hasPrev() ? iPrev : nullptr; }
|
||||
LinkedListElement const* prev() const { return hasPrev() ? iPrev : nullptr; }
|
||||
|
||||
LinkedListElement * nocheck_next() { return iNext; }
|
||||
LinkedListElement const* nocheck_next() const { return iNext; }
|
||||
@@ -52,10 +52,13 @@ class LinkedListElement
|
||||
|
||||
void delink()
|
||||
{
|
||||
if (isInList())
|
||||
{
|
||||
iNext->iPrev = iPrev; iPrev->iNext = iNext; iNext = NULL; iPrev = NULL;
|
||||
}
|
||||
if (!isInList())
|
||||
return;
|
||||
|
||||
iNext->iPrev = iPrev;
|
||||
iPrev->iNext = iNext;
|
||||
iNext = nullptr;
|
||||
iPrev = nullptr;
|
||||
}
|
||||
|
||||
void insertBefore(LinkedListElement* pElem)
|
||||
@@ -75,8 +78,14 @@ class LinkedListElement
|
||||
}
|
||||
|
||||
private:
|
||||
LinkedListElement(LinkedListElement const&);
|
||||
LinkedListElement& operator=(LinkedListElement const&);
|
||||
LinkedListElement(LinkedListElement const&) = delete;
|
||||
LinkedListElement& operator=(LinkedListElement const&) = delete;
|
||||
|
||||
protected:
|
||||
~LinkedListElement()
|
||||
{
|
||||
delink();
|
||||
}
|
||||
};
|
||||
|
||||
//============================================
|
||||
@@ -97,15 +106,13 @@ class LinkedListHead
|
||||
iLast.iPrev = &iFirst;
|
||||
}
|
||||
|
||||
virtual ~LinkedListHead() { }
|
||||
|
||||
bool isEmpty() const { return(!iFirst.iNext->isInList()); }
|
||||
|
||||
LinkedListElement * getFirst() { return(isEmpty() ? NULL : iFirst.iNext); }
|
||||
LinkedListElement const* getFirst() const { return(isEmpty() ? NULL : iFirst.iNext); }
|
||||
LinkedListElement * getFirst() { return (isEmpty() ? nullptr : iFirst.iNext); }
|
||||
LinkedListElement const* getFirst() const { return (isEmpty() ? nullptr : iFirst.iNext); }
|
||||
|
||||
LinkedListElement * getLast() { return(isEmpty() ? NULL : iLast.iPrev); }
|
||||
LinkedListElement const* getLast() const { return(isEmpty() ? NULL : iLast.iPrev); }
|
||||
LinkedListElement * getLast() { return(isEmpty() ? nullptr : iLast.iPrev); }
|
||||
LinkedListElement const* getLast() const { return(isEmpty() ? nullptr : iLast.iPrev); }
|
||||
|
||||
void insertFirst(LinkedListElement* pElem)
|
||||
{
|
||||
@@ -248,8 +255,11 @@ class LinkedListHead
|
||||
typedef Iterator<LinkedListElement> iterator;
|
||||
|
||||
private:
|
||||
LinkedListHead(LinkedListHead const&);
|
||||
LinkedListHead& operator=(LinkedListHead const&);
|
||||
LinkedListHead(LinkedListHead const&) = delete;
|
||||
LinkedListHead& operator=(LinkedListHead const&) = delete;
|
||||
|
||||
protected:
|
||||
~LinkedListHead() { }
|
||||
};
|
||||
|
||||
//============================================
|
||||
|
||||
@@ -23,31 +23,29 @@
|
||||
#include "Dynamic/LinkedList.h"
|
||||
#include "Dynamic/LinkedReference/Reference.h"
|
||||
|
||||
template <class TO, class FROM> class RefManager : public LinkedListHead
|
||||
template <class TO, class FROM>
|
||||
class RefManager : public LinkedListHead
|
||||
{
|
||||
public:
|
||||
typedef LinkedListHead::Iterator< Reference<TO, FROM> > iterator;
|
||||
typedef LinkedListHead::Iterator<Reference<TO, FROM>> iterator;
|
||||
RefManager() { }
|
||||
virtual ~RefManager() { clearReferences(); }
|
||||
|
||||
Reference<TO, FROM>* getFirst() { return ((Reference<TO, FROM>*) LinkedListHead::getFirst()); }
|
||||
Reference<TO, FROM> const* getFirst() const { return ((Reference<TO, FROM> const*) LinkedListHead::getFirst()); }
|
||||
Reference<TO, FROM>* getLast() { return ((Reference<TO, FROM>*) LinkedListHead::getLast()); }
|
||||
Reference<TO, FROM> const* getLast() const { return ((Reference<TO, FROM> const*) LinkedListHead::getLast()); }
|
||||
Reference<TO, FROM>* getFirst() { return static_cast<Reference<TO, FROM>*>(LinkedListHead::getFirst()); }
|
||||
|
||||
Reference<TO, FROM> const* getFirst() const { return static_cast<Reference<TO, FROM> const*>(LinkedListHead::getFirst()); }
|
||||
|
||||
iterator begin() { return iterator(getFirst()); }
|
||||
iterator end() { return iterator(NULL); }
|
||||
iterator rbegin() { return iterator(getLast()); }
|
||||
iterator rend() { return iterator(NULL); }
|
||||
iterator end() { return iterator(nullptr); }
|
||||
|
||||
virtual ~RefManager()
|
||||
{
|
||||
clearReferences();
|
||||
}
|
||||
|
||||
void clearReferences()
|
||||
{
|
||||
LinkedListElement* ref;
|
||||
while ((ref = getFirst()) != NULL)
|
||||
{
|
||||
((Reference<TO, FROM>*) ref)->invalidate();
|
||||
ref->delink(); // the delink might be already done by invalidate(), but doing it here again does not hurt and insures an empty list
|
||||
}
|
||||
while (Reference<TO, FROM>* ref = getFirst())
|
||||
ref->invalidate();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ template <class TO, class FROM> class Reference : public LinkedListElement
|
||||
private:
|
||||
TO* iRefTo;
|
||||
FROM* iRefFrom;
|
||||
|
||||
protected:
|
||||
// Tell our refTo (target) object that we have a link
|
||||
virtual void targetObjectBuildLink() = 0;
|
||||
@@ -90,14 +91,14 @@ template <class TO, class FROM> class Reference : public LinkedListElement
|
||||
Reference<TO, FROM> * nocheck_prev() { return((Reference<TO, FROM> *) LinkedListElement::nocheck_prev()); }
|
||||
Reference<TO, FROM> const* nocheck_prev() const { return((Reference<TO, FROM> const*) LinkedListElement::nocheck_prev()); }
|
||||
|
||||
TO* operator ->() const { return iRefTo; }
|
||||
TO* operator->() const { return iRefTo; }
|
||||
TO* getTarget() const { return iRefTo; }
|
||||
|
||||
FROM* GetSource() const { return iRefFrom; }
|
||||
|
||||
private:
|
||||
Reference(Reference const&);
|
||||
Reference& operator=(Reference const&);
|
||||
Reference(Reference const&) = delete;
|
||||
Reference& operator=(Reference const&) = delete;
|
||||
};
|
||||
|
||||
//=====================================================
|
||||
|
||||
Reference in New Issue
Block a user