mirror of
https://github.com/vcmi/vcmi.git
synced 2025-09-16 09:26:28 +02:00
Fix invalidation of bonus propagation updaters
This commit is contained in:
@@ -833,6 +833,7 @@ void CStackInstance::setCount(TQuantity newCount)
|
||||
}
|
||||
|
||||
CStackBasicDescriptor::setCount(newCount);
|
||||
nodeHasChanged();
|
||||
}
|
||||
|
||||
std::string CStackInstance::bonusToString(const std::shared_ptr<Bonus>& bonus) const
|
||||
|
@@ -64,22 +64,18 @@ void CBonusSystemNode::getAllParents(TCNodes & out) const //retrieves list of pa
|
||||
}
|
||||
}
|
||||
|
||||
void CBonusSystemNode::getAllBonusesRec(BonusList &out, const CSelector & selector) const
|
||||
void CBonusSystemNode::getAllBonusesRec(BonusList &out) const
|
||||
{
|
||||
BonusList beforeUpdate;
|
||||
|
||||
for(const auto * parent : parentsToInherit)
|
||||
parent->getAllBonusesRec(beforeUpdate, selector);
|
||||
parent->getAllBonusesRec(beforeUpdate);
|
||||
|
||||
bonuses.getAllBonuses(beforeUpdate);
|
||||
|
||||
for(const auto & b : beforeUpdate)
|
||||
{
|
||||
//We should not run updaters on non-selected bonuses
|
||||
auto updated = selector(b.get()) && b->updater
|
||||
? getUpdatedBonus(b, b->updater)
|
||||
: b;
|
||||
|
||||
auto updated = b->updater ? getUpdatedBonus(b, b->updater) : b;
|
||||
out.push_back(updated);
|
||||
}
|
||||
}
|
||||
@@ -126,7 +122,7 @@ TConstBonusListPtr CBonusSystemNode::getAllBonuses(const CSelector &selector, co
|
||||
|
||||
cachedBonuses.clear();
|
||||
|
||||
getAllBonusesRec(allBonuses, Selector::all);
|
||||
getAllBonusesRec(allBonuses);
|
||||
limitBonuses(allBonuses, cachedBonuses);
|
||||
cachedBonuses.stackBonuses();
|
||||
cachedLast = nodeChanged;
|
||||
@@ -162,7 +158,7 @@ TConstBonusListPtr CBonusSystemNode::getAllBonusesWithoutCaching(const CSelector
|
||||
// Get bonus results without caching enabled.
|
||||
BonusList beforeLimiting;
|
||||
BonusList afterLimiting;
|
||||
getAllBonusesRec(beforeLimiting, selector);
|
||||
getAllBonusesRec(beforeLimiting);
|
||||
limitBonuses(beforeLimiting, afterLimiting);
|
||||
afterLimiting.getBonuses(*ret, selector, limit);
|
||||
ret->stackBonuses();
|
||||
@@ -382,7 +378,7 @@ void CBonusSystemNode::propagateBonus(const std::shared_ptr<Bonus> & b, const CB
|
||||
: b;
|
||||
bonuses.push_back(propagated);
|
||||
logBonus->trace("#$# %s #propagated to# %s", propagated->Description(nullptr), nodeName());
|
||||
nodeHasChanged();
|
||||
invalidateChildrenNodes(nodeChanged);
|
||||
}
|
||||
|
||||
TNodes lchildren;
|
||||
@@ -404,7 +400,7 @@ void CBonusSystemNode::unpropagateBonus(const std::shared_ptr<Bonus> & b)
|
||||
{
|
||||
if (bonus->propagationUpdater && bonus->propagationUpdater == b->propagationUpdater)
|
||||
{
|
||||
nodeHasChanged();
|
||||
invalidateChildrenNodes(nodeChanged);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -617,6 +613,18 @@ void CBonusSystemNode::nodeHasChanged()
|
||||
invalidateChildrenNodes(++globalCounter);
|
||||
}
|
||||
|
||||
void CBonusSystemNode::recomputePropagationUpdaters(const CBonusSystemNode & source)
|
||||
{
|
||||
for(const auto & b : exportedBonuses)
|
||||
{
|
||||
if (b->propagator && b->propagationUpdater)
|
||||
{
|
||||
unpropagateBonus(b);
|
||||
propagateBonus(b, source);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CBonusSystemNode::invalidateChildrenNodes(int32_t changeCounter)
|
||||
{
|
||||
if (nodeChanged == changeCounter)
|
||||
@@ -624,6 +632,11 @@ void CBonusSystemNode::invalidateChildrenNodes(int32_t changeCounter)
|
||||
|
||||
nodeChanged = changeCounter;
|
||||
|
||||
recomputePropagationUpdaters(*this);
|
||||
for(const CBonusSystemNode * parent : parentsToInherit)
|
||||
if (parent->actsAsBonusSourceOnly())
|
||||
recomputePropagationUpdaters(*parent);
|
||||
|
||||
for(CBonusSystemNode * child : children)
|
||||
child->invalidateChildrenNodes(changeCounter);
|
||||
}
|
||||
|
@@ -69,7 +69,7 @@ private:
|
||||
mutable RequestsMap cachedRequests;
|
||||
mutable std::shared_mutex sync;
|
||||
|
||||
void getAllBonusesRec(BonusList &out, const CSelector & selector) const;
|
||||
void getAllBonusesRec(BonusList &out) const;
|
||||
TConstBonusListPtr getAllBonusesWithoutCaching(const CSelector &selector, const CSelector &limit) const;
|
||||
std::shared_ptr<Bonus> getUpdatedBonus(const std::shared_ptr<Bonus> & b, const TUpdaterPtr & updater) const;
|
||||
void limitBonuses(const BonusList &allBonuses, BonusList &out) const; //out will bo populed with bonuses that are not limited here
|
||||
@@ -82,6 +82,7 @@ private:
|
||||
|
||||
void propagateBonus(const std::shared_ptr<Bonus> & b, const CBonusSystemNode & source);
|
||||
void unpropagateBonus(const std::shared_ptr<Bonus> & b);
|
||||
void recomputePropagationUpdaters(const CBonusSystemNode & source);
|
||||
bool actsAsBonusSourceOnly() const;
|
||||
|
||||
void newRedDescendant(CBonusSystemNode & descendant) const; //propagation needed
|
||||
|
Reference in New Issue
Block a user