BonusCache.h 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. /*
  2. * BonusCache.h, part of VCMI engine
  3. *
  4. * Authors: listed in file AUTHORS in main folder
  5. *
  6. * License: GNU General Public License v2.0 or later
  7. * Full text of license available in license.txt file, in main folder
  8. *
  9. */
  10. #pragma once
  11. #include "BonusSelector.h"
  12. enum class BonusCacheMode : int8_t
  13. {
  14. VALUE, // total value of bonus will be cached
  15. PRESENCE, // presence of bonus will be cached
  16. };
  17. /// Internal base class with no own cache
  18. class BonusCacheBase
  19. {
  20. protected:
  21. const IBonusBearer * target;
  22. explicit BonusCacheBase(const IBonusBearer * target):
  23. target(target)
  24. {}
  25. struct BonusCacheEntry
  26. {
  27. std::atomic<int64_t> version = 0;
  28. std::atomic<int64_t> value = 0;
  29. };
  30. int getBonusValueImpl(BonusCacheEntry & currentValue, const CSelector & selector, BonusCacheMode) const;
  31. };
  32. /// Cache that tracks a single query to bonus system
  33. class BonusValueCache : public BonusCacheBase
  34. {
  35. CSelector selector;
  36. mutable BonusCacheEntry value;
  37. public:
  38. BonusValueCache(const IBonusBearer * target, const CSelector selector);
  39. int getValue() const;
  40. };
  41. /// Cache that can track a list of queries to bonus system
  42. template<typename EnumType, size_t SIZE>
  43. class BonusValuesArrayCache : public BonusCacheBase
  44. {
  45. public:
  46. using SelectorsArray = std::array<const CSelector, SIZE>;
  47. BonusValuesArrayCache(const IBonusBearer * target, const SelectorsArray * selectors)
  48. : BonusCacheBase(target)
  49. , selectors(selectors)
  50. {}
  51. int getBonusValue(EnumType which) const
  52. {
  53. auto index = static_cast<size_t>(which);
  54. return getBonusValueImpl(cache[index], (*selectors)[index], BonusCacheMode::VALUE);
  55. }
  56. int hasBonus(EnumType which) const
  57. {
  58. auto index = static_cast<size_t>(which);
  59. return getBonusValueImpl(cache[index], (*selectors)[index], BonusCacheMode::PRESENCE);
  60. }
  61. private:
  62. using CacheArray = std::array<BonusCacheEntry, SIZE>;
  63. const SelectorsArray * selectors;
  64. mutable CacheArray cache;
  65. };
  66. /// Cache that tracks values of primary skill values in bonus system
  67. class PrimarySkillsCache
  68. {
  69. const IBonusBearer * target;
  70. mutable std::atomic<int64_t> version = 0;
  71. mutable std::array<std::atomic<int32_t>, 4> skills;
  72. void update() const;
  73. public:
  74. PrimarySkillsCache(const IBonusBearer * target);
  75. const std::array<std::atomic<int32_t>, 4> & getSkills() const;
  76. };
  77. /// Cache that tracks values for different values of bonus duration
  78. class BonusCachePerTurn : public BonusCacheBase
  79. {
  80. static constexpr int cachedTurns = 8;
  81. const CSelector selector;
  82. mutable TConstBonusListPtr bonusList;
  83. mutable std::mutex bonusListMutex;
  84. mutable std::atomic<int64_t> bonusListVersion = 0;
  85. mutable std::array<BonusCacheEntry, cachedTurns> cache;
  86. const BonusCacheMode mode;
  87. int getValueUncached(int turns) const;
  88. public:
  89. BonusCachePerTurn(const IBonusBearer * target, const CSelector & selector, BonusCacheMode mode)
  90. : BonusCacheBase(target)
  91. , selector(selector)
  92. , mode(mode)
  93. {}
  94. int getValue(int turns) const;
  95. };