You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This change splits the data off of the BattlePlanBonuses class so that instances can be created on the stack for fast manipulations. Reason being, the destructor of BattlePlanBonuses is protected, and therefore it always required an allocation to create an instance. The new BattlePlanBonusesData does not have this restriction.
xezon
added
Minor
Severity: Minor < Major < Critical < Blocker
Gen
Relates to Generals
ZH
Relates to Zero Hour
Refactor
Edits the code with insignificant behavior changes, is never user facing
labels
Feb 21, 2026
Successfully refactors BattlePlanBonuses by extracting data members into a new BattlePlanBonusesData struct, enabling stack allocation for fast bonus manipulations.
Key Changes:
Introduced BattlePlanBonusesData struct with default constructor that initializes scalar bonuses to 1.0f and counters to 0
Made BattlePlanBonuses inherit from both BattlePlanBonusesData and MemoryPoolObject, maintaining memory pool allocation for persistent instances
Updated method signatures throughout to accept BattlePlanBonusesData* where appropriate
Eliminated heap allocation in Player::removeBattlePlanBonusesForObject() by creating inverted bonuses on the stack
Applied appropriate static_cast operations when converting between base and derived types
Impact:
This is a clean refactoring that improves performance by allowing temporary bonus calculations to avoid heap allocation while maintaining the memory pool pattern for persistent bonus storage.
Confidence Score: 5/5
This PR is safe to merge with minimal risk
Clean refactoring with proper inheritance hierarchy, all casts are correct, default constructor properly initializes all members, and the change eliminates unnecessary heap allocations for temporary objects
Looks good. I see that we don't have to, but could initialize m_validKindOf / m_invalidKindOf in the constructor. There are a couple of static_casts that are probably only needed for VC6 if anything.
Should probably replicate to Generals too, no?
Looks good. I see that we don't have to, but could initialize m_validKindOf / m_invalidKindOf in the constructor. There are a couple of static_casts that are probably only needed for VC6 if anything. Should probably replicate to Generals too, no?
KindOfMaskType are default initialized to 0, so no problem.
static_cast's are required because inherited classes can have pointer offsets that need to be explicitly communicated on cast to void*.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
GenRelates to GeneralsMinorSeverity: Minor < Major < Critical < BlockerRefactorEdits the code with insignificant behavior changes, is never user facingZHRelates to Zero Hour
2 participants
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This change splits the data off of the
BattlePlanBonusesclass so that instances can be created on the stack for fast manipulations. Reason being, the destructor ofBattlePlanBonusesis protected, and therefore it always required an allocation to create an instance. The newBattlePlanBonusesDatadoes not have this restriction.TODO