| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206 | 
							- /*
 
-  * BonusCache.h, part of VCMI engine
 
-  *
 
-  * Authors: listed in file AUTHORS in main folder
 
-  *
 
-  * License: GNU General Public License v2.0 or later
 
-  * Full text of license available in license.txt file, in main folder
 
-  *
 
-  */
 
- #pragma once
 
- #include "BonusSelector.h"
 
- VCMI_LIB_NAMESPACE_BEGIN
 
- enum class BonusCacheMode : int8_t
 
- {
 
- 	VALUE, // total value of bonus will be cached
 
- 	PRESENCE, // presence of bonus will be cached
 
- };
 
- /// Internal base class with no own cache
 
- class BonusCacheBase
 
- {
 
- protected:
 
- 	const IBonusBearer * target;
 
- 	explicit BonusCacheBase(const IBonusBearer * target):
 
- 		target(target)
 
- 	{}
 
- 	struct BonusCacheEntry
 
- 	{
 
- 		std::atomic<int32_t> version = 0;
 
- 		std::atomic<int32_t> value = 0;
 
- 		BonusCacheEntry() = default;
 
- 		BonusCacheEntry(const BonusCacheEntry & other)
 
- 			: version(other.version.load())
 
- 			, value(other.value.load())
 
- 		{
 
- 		}
 
- 		BonusCacheEntry & operator =(const BonusCacheEntry & other)
 
- 		{
 
- 			version = other.version.load();
 
- 			value = other.value.load();
 
- 			return *this;
 
- 		}
 
- 	};
 
- 	int getBonusValueImpl(BonusCacheEntry & currentValue, const CSelector & selector, BonusCacheMode) const;
 
- };
 
- /// Cache that tracks a single query to bonus system
 
- class BonusValueCache : public BonusCacheBase
 
- {
 
- 	CSelector selector;
 
- 	mutable BonusCacheEntry value;
 
- public:
 
- 	BonusValueCache(const IBonusBearer * target, const CSelector & selector);
 
- 	int getValue() const;
 
- 	bool hasBonus() const;
 
- };
 
- /// Cache that can track a list of queries to bonus system
 
- template<size_t SIZE>
 
- class BonusValuesArrayCache : public BonusCacheBase
 
- {
 
- public:
 
- 	using SelectorsArray = std::array<const CSelector, SIZE>;
 
- 	BonusValuesArrayCache(const IBonusBearer * target, const SelectorsArray * selectors)
 
- 		: BonusCacheBase(target)
 
- 		, selectors(selectors)
 
- 	{}
 
- 	int getBonusValue(int index) const
 
- 	{
 
- 		return getBonusValueImpl(cache[index], (*selectors)[index], BonusCacheMode::VALUE);
 
- 	}
 
- 	int hasBonus(int index) const
 
- 	{
 
- 		return getBonusValueImpl(cache[index], (*selectors)[index], BonusCacheMode::PRESENCE);
 
- 	}
 
- private:
 
- 	using CacheArray = std::array<BonusCacheEntry, SIZE>;
 
- 	const SelectorsArray * selectors;
 
- 	mutable CacheArray cache;
 
- };
 
- class UnitBonusValuesProxy
 
- {
 
- public:
 
- 	enum ECacheKeys : int8_t
 
- 	{
 
- 		TOTAL_ATTACKS_MELEE,
 
- 		TOTAL_ATTACKS_RANGED,
 
- 		MIN_DAMAGE_MELEE,
 
- 		MIN_DAMAGE_RANGED,
 
- 		MAX_DAMAGE_MELEE,
 
- 		MAX_DAMAGE_RANGED,
 
- 		ATTACK_MELEE,
 
- 		ATTACK_RANGED,
 
- 		DEFENCE_MELEE,
 
- 		DEFENCE_RANGED,
 
- 		IN_FRENZY,
 
- 		HYPNOTIZED,
 
- 		FORGETFULL,
 
- 		HAS_FREE_SHOOTING,
 
- 		STACK_HEALTH,
 
- 		INVINCIBLE,
 
- 		CLONE_MARKER,
 
- 		TOTAL_KEYS,
 
- 	};
 
- 	static constexpr size_t KEYS_COUNT = static_cast<size_t>(ECacheKeys::TOTAL_KEYS);
 
- 	using SelectorsArray = BonusValuesArrayCache<KEYS_COUNT>::SelectorsArray;
 
- 	UnitBonusValuesProxy(const IBonusBearer * Target):
 
- 		cache(Target, generateSelectors())
 
- 	{}
 
- 	int getBonusValue(ECacheKeys which) const
 
- 	{
 
- 		auto index = static_cast<size_t>(which);
 
- 		return cache.getBonusValue(index);
 
- 	}
 
- 	int hasBonus(ECacheKeys which) const
 
- 	{
 
- 		auto index = static_cast<size_t>(which);
 
- 		return cache.hasBonus(index);
 
- 	}
 
- private:
 
- 	const SelectorsArray * generateSelectors();
 
- 	BonusValuesArrayCache<KEYS_COUNT> cache;
 
- };
 
- /// Cache that tracks values of primary skill values in bonus system
 
- class PrimarySkillsCache
 
- {
 
- 	const IBonusBearer * target;
 
- 	mutable std::atomic<int32_t> version = 0;
 
- 	mutable std::array<std::atomic<int32_t>, 4> skills;
 
- 	void update() const;
 
- public:
 
- 	PrimarySkillsCache(const IBonusBearer * target);
 
- 	const std::array<std::atomic<int32_t>, 4> & getSkills() const;
 
- 	const std::atomic<int32_t> & getSkill(PrimarySkill id) const
 
- 	{
 
- 		return getSkills()[id.getNum()];
 
- 	}
 
- };
 
- /// Cache that tracks values of spell school mastery in bonus system
 
- class MagicSchoolMasteryCache
 
- {
 
- 	const IBonusBearer * target;
 
- 	mutable std::atomic<int32_t> version = 0;
 
- 	mutable std::vector<std::atomic<int32_t>> schools;
 
- 	void update() const;
 
- public:
 
- 	MagicSchoolMasteryCache(const IBonusBearer * target);
 
- 	int32_t getMastery(const SpellSchool & school) const;
 
- };
 
- /// Cache that tracks values for different values of bonus duration
 
- class BonusCachePerTurn : public BonusCacheBase
 
- {
 
- 	static constexpr int cachedTurns = 8;
 
- 	const CSelector selector;
 
- 	mutable TConstBonusListPtr bonusList;
 
- 	mutable std::mutex bonusListMutex;
 
- 	mutable std::atomic<int32_t> bonusListVersion = 0;
 
- 	mutable std::array<BonusCacheEntry, cachedTurns> cache;
 
- 	const BonusCacheMode mode;
 
- 	int getValueUncached(int turns) const;
 
- public:
 
- 	BonusCachePerTurn(const IBonusBearer * target, const CSelector & selector, BonusCacheMode mode)
 
- 		: BonusCacheBase(target)
 
- 		, selector(selector)
 
- 		, mode(mode)
 
- 	{}
 
- 	int getValue(int turns) const;
 
- };
 
- VCMI_LIB_NAMESPACE_END
 
 
  |