1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-09-16 09:26:28 +02:00

TurnInfo: implement internal bonus cache for most used bonuses

Bonus system even with caching add too big overhead so we'll only use it once for these bonuses.
Still I'm like it to be transparent for external code so it's a bit hacky code.
This commit is contained in:
ArseniyShestakov
2015-11-21 10:00:09 +03:00
parent e91d79414b
commit 5ae6225ebc
2 changed files with 50 additions and 0 deletions

View File

@@ -709,6 +709,21 @@ bool CPathfinder::addTeleportWhirlpool(const CGWhirlpool * obj) const
return options.useTeleportWhirlpool && hlp->hasBonusOfType(Bonus::WHIRLPOOL_PROTECTION) && obj;
}
TurnInfo::BonusCache::BonusCache(TBonusListPtr bl)
{
noTerrainPenalty.reserve(ETerrainType::ROCK);
for(int i = 0; i < ETerrainType::ROCK; i++)
{
noTerrainPenalty.push_back(bl->getFirst(Selector::type(Bonus::NO_TERRAIN_PENALTY).And(Selector::subtype(i))));
}
freeShipBoarding = bl->getFirst(Selector::type(Bonus::FREE_SHIP_BOARDING));
flyingMovement = bl->getFirst(Selector::type(Bonus::FLYING_MOVEMENT));
flyingMovementVal = bl->valOfBonuses(Selector::type(Bonus::FLYING_MOVEMENT));
waterWalking = bl->getFirst(Selector::type(Bonus::WATER_WALKING));
waterWalkingVal = bl->valOfBonuses(Selector::type(Bonus::WATER_WALKING));
}
TurnInfo::TurnInfo(const CGHeroInstance * Hero, const int turn)
: hero(Hero), maxMovePointsLand(-1), maxMovePointsWater(-1)
{
@@ -716,6 +731,7 @@ TurnInfo::TurnInfo(const CGHeroInstance * Hero, const int turn)
cachingStr << "days_" << turn;
bonuses = hero->getAllBonuses(Selector::days(turn), nullptr, nullptr, cachingStr.str());
bonusCache = make_unique<BonusCache>(bonuses);
}
bool TurnInfo::isLayerAvailable(const EPathfindingLayer layer) const
@@ -740,11 +756,31 @@ bool TurnInfo::isLayerAvailable(const EPathfindingLayer layer) const
bool TurnInfo::hasBonusOfType(Bonus::BonusType type, int subtype) const
{
switch(type)
{
case Bonus::FREE_SHIP_BOARDING:
return bonusCache->freeShipBoarding;
case Bonus::FLYING_MOVEMENT:
return bonusCache->flyingMovement;
case Bonus::WATER_WALKING:
return bonusCache->waterWalking;
case Bonus::NO_TERRAIN_PENALTY:
return bonusCache->noTerrainPenalty[subtype];
}
return bonuses->getFirst(Selector::type(type).And(Selector::subtype(subtype)));
}
int TurnInfo::valOfBonuses(Bonus::BonusType type, int subtype) const
{
switch(type)
{
case Bonus::FLYING_MOVEMENT:
return bonusCache->flyingMovementVal;
case Bonus::WATER_WALKING:
return bonusCache->waterWalkingVal;
}
return bonuses->valOfBonuses(Selector::type(type).And(Selector::subtype(subtype)));
}

View File

@@ -209,6 +209,20 @@ private:
struct DLL_LINKAGE TurnInfo
{
/// This is certainly not the best design ever and certainly can be improved
/// Unfortunately for pathfinder that do hundreds of thousands calls onus system add too big overhead
struct BonusCache {
std::vector<bool> noTerrainPenalty;
bool freeShipBoarding;
bool flyingMovement;
int flyingMovementVal;
bool waterWalking;
int waterWalkingVal;
BonusCache(TBonusListPtr bonusList);
};
unique_ptr<BonusCache> bonusCache;
const CGHeroInstance * hero;
TBonusListPtr bonuses;
mutable int maxMovePointsLand;