Browse Source

Merge pull request #4261 from kaja47/shrinkage

Reduce size of Bonus struct from 320 bytes to 296 bytes.
Ivan Savenko 1 year ago
parent
commit
e8aa6efbb9

+ 2 - 2
lib/bonuses/Bonus.cpp

@@ -119,7 +119,7 @@ std::string Bonus::Description(std::optional<si32> customValue) const
 	if(descriptionHelper.empty())
 	{
 		// still no description - try to generate one based on duration
-		if ((duration & BonusDuration::ONE_BATTLE).any())
+		if ((duration & BonusDuration::ONE_BATTLE) != 0)
 		{
 			if (val > 0)
 				descriptionHelper.appendTextID("core.arraytxt.110"); //+%d Temporary until next battle"
@@ -248,7 +248,7 @@ DLL_LINKAGE std::ostream & operator<<(std::ostream &out, const Bonus &bonus)
 #define printField(field) out << "\t" #field ": " << (int)bonus.field << "\n"
 	printField(val);
 	out << "\tSubtype: " << bonus.subtype.toString() << "\n";
-	printField(duration.to_ulong());
+	printField(duration);
 	printField(source);
 	out << "\tSource ID: " << bonus.sid.toString() << "\n";
 	if(bonus.additionalInfo != CAddInfo::NONE)

+ 19 - 18
lib/bonuses/Bonus.h

@@ -58,21 +58,22 @@ public:
 /// Struct for handling bonuses of several types. Can be transferred to any hero
 struct DLL_LINKAGE Bonus : public std::enable_shared_from_this<Bonus>, public Serializeable
 {
-	BonusDuration::Type duration = BonusDuration::PERMANENT; //uses BonusDuration values
+	BonusDuration::Type duration = BonusDuration::PERMANENT; //uses BonusDuration values - 2 bytes
 	si16 turnsRemain = 0; //used if duration is N_TURNS, N_DAYS or ONE_WEEK
+	si32 val = 0;
 
+	BonusValueType valType = BonusValueType::ADDITIVE_VALUE; // 1 byte
+	BonusSource source = BonusSource::OTHER; //source type" uses BonusSource values - what gave that bonus - 1 byte
+	BonusSource targetSourceType = BonusSource::OTHER;//Bonuses of what origin this amplifies, uses BonusSource values. Needed for PERCENT_TO_TARGET_TYPE. - 1 byte
 	BonusType type = BonusType::NONE; //uses BonusType values - says to what is this bonus - 1 byte
-	BonusSubtypeID subtype;
+	BonusLimitEffect effectRange = BonusLimitEffect::NO_LIMIT; // 1 byte
+	// 3 bytes padding
 
-	BonusSource source = BonusSource::OTHER; //source type" uses BonusSource values - what gave that bonus
-	BonusSource targetSourceType = BonusSource::OTHER;//Bonuses of what origin this amplifies, uses BonusSource values. Needed for PERCENT_TO_TARGET_TYPE.
-	si32 val = 0;
+	BonusSubtypeID subtype;
 	BonusSourceID sid; //source id: id of object/artifact/spell
-	BonusValueType valType = BonusValueType::ADDITIVE_VALUE;
 	std::string stacking; // bonuses with the same stacking value don't stack (e.g. Angel/Archangel morale bonus)
 
 	CAddInfo additionalInfo;
-	BonusLimitEffect effectRange = BonusLimitEffect::NO_LIMIT;
 
 	TLimiterPtr limiter;
 	TPropagatorPtr propagator;
@@ -128,57 +129,57 @@ struct DLL_LINKAGE Bonus : public std::enable_shared_from_this<Bonus>, public Se
 	static bool NDays(const Bonus *hb)
 	{
 		auto set = hb->duration & BonusDuration::N_DAYS;
-		return set.any();
+		return set != 0;
 	}
 	static bool NTurns(const Bonus *hb)
 	{
 		auto set = hb->duration & BonusDuration::N_TURNS;
-		return set.any();
+		return set != 0;
 	}
 	static bool OneDay(const Bonus *hb)
 	{
 		auto set = hb->duration & BonusDuration::ONE_DAY;
-		return set.any();
+		return set != 0;
 	}
 	static bool OneWeek(const Bonus *hb)
 	{
 		auto set = hb->duration & BonusDuration::ONE_WEEK;
-		return set.any();
+		return set != 0;
 	}
 	static bool OneBattle(const Bonus *hb)
 	{
 		auto set = hb->duration & BonusDuration::ONE_BATTLE;
-		return set.any();
+		return set != 0;
 	}
 	static bool Permanent(const Bonus *hb)
 	{
 		auto set = hb->duration & BonusDuration::PERMANENT;
-		return set.any();
+		return set != 0;
 	}
 	static bool UntilGetsTurn(const Bonus *hb)
 	{
 		auto set = hb->duration & BonusDuration::STACK_GETS_TURN;
-		return set.any();
+		return set != 0;
 	}
 	static bool UntilAttack(const Bonus *hb)
 	{
 		auto set = hb->duration & BonusDuration::UNTIL_ATTACK;
-		return set.any();
+		return set != 0;
 	}
 	static bool UntilBeingAttacked(const Bonus *hb)
 	{
 		auto set = hb->duration & BonusDuration::UNTIL_BEING_ATTACKED;
-		return set.any();
+		return set != 0;
 	}
 	static bool UntilCommanderKilled(const Bonus *hb)
 	{
 		auto set = hb->duration & BonusDuration::COMMANDER_KILLED;
-		return set.any();
+		return set != 0;
 	}
 	static bool UntilOwnAttack(const Bonus *hb)
 	{
 		auto set = hb->duration & BonusDuration::UNTIL_OWN_ATTACK;
-		return set.any();
+		return set != 0;
 	}
 	inline bool operator == (const BonusType & cf) const
 	{

+ 4 - 3
lib/bonuses/BonusEnum.cpp

@@ -60,10 +60,11 @@ namespace BonusDuration
 	JsonNode toJson(const Type & duration)
 	{
 		std::vector<std::string> durationNames;
-		for(auto durBit = 0; durBit < duration.size(); durBit++)
+		for(size_t durBit = 0; durBit < Size; durBit++)
 		{
-			if(duration[durBit])
-				durationNames.push_back(vstd::findKey(bonusDurationMap, duration & Type().set(durBit)));
+			Type value = duration & (1 << durBit);
+			if(value)
+				durationNames.push_back(vstd::findKey(bonusDurationMap, value));
 		}
 		if(durationNames.size() == 1)
 		{

+ 22 - 16
lib/bonuses/BonusEnum.h

@@ -212,7 +212,7 @@ class JsonNode;
 	BONUS_VALUE(INDEPENDENT_MIN) //used for SECONDARY_SKILL_PREMY bonus
 
 
-enum class BonusType
+enum class BonusType : uint8_t
 {
 #define BONUS_NAME(x) x,
     BONUS_LIST
@@ -220,21 +220,27 @@ enum class BonusType
 };
 namespace BonusDuration  //when bonus is automatically removed
 {
-	using Type = std::bitset<11>;
+	// We use uint16_t directly because std::bitset<11> eats whole 8 byte word.
+	using Type = uint16_t;
+	constexpr static size_t Size = 11;
+
+	enum BonusDuration : Type {
+		PERMANENT = 1 << 0,
+		ONE_BATTLE = 1 << 1, //at the end of battle
+		ONE_DAY = 1 << 2,   //at the end of day
+		ONE_WEEK = 1 << 3, //at the end of week (bonus lasts till the end of week, thats NOT 7 days
+		N_TURNS = 1 << 4, //used during battles, after battle bonus is always removed
+		N_DAYS = 1 << 5,
+		UNTIL_BEING_ATTACKED = 1 << 6, /*removed after attack and counterattacks are performed*/
+		UNTIL_ATTACK = 1 << 7, /*removed after attack and counterattacks are performed*/
+		STACK_GETS_TURN = 1 << 8, /*removed when stack gets its turn - used for defensive stance*/
+		COMMANDER_KILLED = 1 << 9,
+		UNTIL_OWN_ATTACK = 1 << 10 /*removed after attack is performed (not counterattack)*/,
+	};
+
 	extern JsonNode toJson(const Type & duration);
-	constexpr Type PERMANENT = 1 << 0;
-	constexpr Type ONE_BATTLE = 1 << 1; //at the end of battle
-	constexpr Type ONE_DAY = 1 << 2;   //at the end of day
-	constexpr Type ONE_WEEK = 1 << 3; //at the end of week (bonus lasts till the end of week, thats NOT 7 days
-	constexpr Type N_TURNS = 1 << 4; //used during battles, after battle bonus is always removed
-	constexpr Type N_DAYS = 1 << 5;
-	constexpr Type UNTIL_BEING_ATTACKED = 1 << 6; /*removed after attack and counterattacks are performed*/
-	constexpr Type UNTIL_ATTACK = 1 << 7; /*removed after attack and counterattacks are performed*/
-	constexpr Type STACK_GETS_TURN = 1 << 8; /*removed when stack gets its turn - used for defensive stance*/
-	constexpr Type COMMANDER_KILLED = 1 << 9;
-	constexpr Type UNTIL_OWN_ATTACK = 1 << 10; /*removed after attack is performed (not counterattack)*/;
 };
-enum class BonusSource
+enum class BonusSource : uint8_t
 {
 #define BONUS_SOURCE(x) x,
     BONUS_SOURCE_LIST
@@ -242,13 +248,13 @@ enum class BonusSource
     NUM_BONUS_SOURCE /*This is a dummy value, which will be always last*/
 };
 
-enum class BonusLimitEffect
+enum class BonusLimitEffect : uint8_t
 {
     NO_LIMIT = 0,
     ONLY_DISTANCE_FIGHT=1, ONLY_MELEE_FIGHT, //used to mark bonuses for attack/defense primary skills from spells like Precision (distance only)
 };
 
-enum class BonusValueType
+enum class BonusValueType : uint8_t
 {
 #define BONUS_VALUE(x) x,
     BONUS_VALUE_LIST

+ 1 - 1
server/battles/BattleActionProcessor.h

@@ -19,7 +19,7 @@ class CBattleInfoCallback;
 struct BattleHex;
 class CStack;
 class PlayerColor;
-enum class BonusType;
+enum class BonusType : uint8_t;
 
 namespace battle
 {