From 6684d6eba5e9e0525da2730a65794755a2f70f24 Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Sun, 23 Nov 2025 11:53:39 -0500 Subject: [PATCH 1/8] Use move semantics in aiFollowPath and aiFollowExitProductionPath --- Generals/Code/GameEngine/Include/GameLogic/AI.h | 8 ++++---- GeneralsMD/Code/GameEngine/Include/GameLogic/AI.h | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Generals/Code/GameEngine/Include/GameLogic/AI.h b/Generals/Code/GameEngine/Include/GameLogic/AI.h index 502a2723cf..703db686f6 100644 --- a/Generals/Code/GameEngine/Include/GameLogic/AI.h +++ b/Generals/Code/GameEngine/Include/GameLogic/AI.h @@ -536,18 +536,18 @@ class AICommandInterface aiDoCommand(&parms); } - inline void aiFollowExitProductionPath( const std::vector* path, Object *ignoreObject, CommandSourceType cmdSource ) + inline void aiFollowExitProductionPath( std::vector* path, Object *ignoreObject, CommandSourceType cmdSource ) { AICommandParms parms(AICMD_FOLLOW_EXITPRODUCTION_PATH, cmdSource); - parms.m_coords = *path; + parms.m_coords = std::move(*path); parms.m_obj = ignoreObject; aiDoCommand(&parms); } - inline void aiFollowPath( const std::vector* path, Object *ignoreObject, CommandSourceType cmdSource ) + inline void aiFollowPath( std::vector* path, Object *ignoreObject, CommandSourceType cmdSource ) { AICommandParms parms(AICMD_FOLLOW_PATH, cmdSource); - parms.m_coords = *path; + parms.m_coords = std::move(*path); parms.m_obj = ignoreObject; aiDoCommand(&parms); } diff --git a/GeneralsMD/Code/GameEngine/Include/GameLogic/AI.h b/GeneralsMD/Code/GameEngine/Include/GameLogic/AI.h index 710bdf2f0a..a96e66943e 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameLogic/AI.h +++ b/GeneralsMD/Code/GameEngine/Include/GameLogic/AI.h @@ -550,18 +550,18 @@ class AICommandInterface aiDoCommand(&parms); } - inline void aiFollowExitProductionPath( const std::vector* path, Object *ignoreObject, CommandSourceType cmdSource ) + inline void aiFollowExitProductionPath( std::vector* path, Object *ignoreObject, CommandSourceType cmdSource ) { AICommandParms parms(AICMD_FOLLOW_EXITPRODUCTION_PATH, cmdSource); - parms.m_coords = *path; + parms.m_coords = std::move(*path); parms.m_obj = ignoreObject; aiDoCommand(&parms); } - inline void aiFollowPath( const std::vector* path, Object *ignoreObject, CommandSourceType cmdSource ) + inline void aiFollowPath( std::vector* path, Object *ignoreObject, CommandSourceType cmdSource ) { AICommandParms parms(AICMD_FOLLOW_PATH, cmdSource); - parms.m_coords = *path; + parms.m_coords = std::move(*path); parms.m_obj = ignoreObject; aiDoCommand(&parms); } From 17353e64b28bb5fbe79f46559d4de0be9ead3c3e Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Sun, 23 Nov 2025 11:53:45 -0500 Subject: [PATCH 2/8] Use move semantics in AIStateMachine::setGoalPath --- Generals/Code/GameEngine/Include/GameLogic/AIStateMachine.h | 2 +- Generals/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp | 4 ++-- GeneralsMD/Code/GameEngine/Include/GameLogic/AIStateMachine.h | 2 +- GeneralsMD/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Generals/Code/GameEngine/Include/GameLogic/AIStateMachine.h b/Generals/Code/GameEngine/Include/GameLogic/AIStateMachine.h index 03f0de0e73..7e39c8ec7c 100644 --- a/Generals/Code/GameEngine/Include/GameLogic/AIStateMachine.h +++ b/Generals/Code/GameEngine/Include/GameLogic/AIStateMachine.h @@ -138,7 +138,7 @@ class AIStateMachine : public StateMachine virtual StateReturnType setState( StateID newStateID ); /// @todo Rethink state parameter passing. Continuing in this fashion will have a pile of params in the machine (MSB) - void setGoalPath( const std::vector* path ); + void setGoalPath( std::vector* path ); void addToGoalPath( const Coord3D *pathPoint ); const Coord3D *getGoalPathPosition( Int i ) const; ///< return path position at index "i" Int getGoalPathSize() const { return m_goalPath.size(); } diff --git a/Generals/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp b/Generals/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp index 79913a7c7d..2105a4c121 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp @@ -816,9 +816,9 @@ void AIStateMachine::loadPostProcess( void ) /** * Define a simple path */ -void AIStateMachine::setGoalPath( const std::vector* path ) +void AIStateMachine::setGoalPath( std::vector* path ) { - m_goalPath = *path; + m_goalPath = std::move(*path); } #ifdef STATE_MACHINE_DEBUG diff --git a/GeneralsMD/Code/GameEngine/Include/GameLogic/AIStateMachine.h b/GeneralsMD/Code/GameEngine/Include/GameLogic/AIStateMachine.h index 3171df36bc..8d96e65997 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameLogic/AIStateMachine.h +++ b/GeneralsMD/Code/GameEngine/Include/GameLogic/AIStateMachine.h @@ -141,7 +141,7 @@ class AIStateMachine : public StateMachine virtual StateReturnType setState( StateID newStateID ); /// @todo Rethink state parameter passing. Continuing in this fashion will have a pile of params in the machine (MSB) - void setGoalPath( const std::vector* path ); + void setGoalPath( std::vector* path ); void addToGoalPath( const Coord3D *pathPoint ); const Coord3D *getGoalPathPosition( Int i ) const; ///< return path position at index "i" Int getGoalPathSize() const { return m_goalPath.size(); } diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp index 6988747599..449a7834a3 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp @@ -821,9 +821,9 @@ void AIStateMachine::loadPostProcess( void ) /** * Define a simple path */ -void AIStateMachine::setGoalPath( const std::vector* path ) +void AIStateMachine::setGoalPath( std::vector* path ) { - m_goalPath = *path; + m_goalPath = std::move(*path); } #ifdef STATE_MACHINE_DEBUG From 0d9caa11cbe93455d67d86cad0259aec1a906c39 Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Sun, 23 Nov 2025 11:53:51 -0500 Subject: [PATCH 3/8] Update privateFollowPath to use move semantics --- Generals/Code/GameEngine/Include/GameLogic/Module/AIUpdate.h | 4 ++-- .../Code/GameEngine/Include/GameLogic/Module/JetAIUpdate.h | 4 ++-- .../GameEngine/Source/GameLogic/Object/Update/AIUpdate.cpp | 4 ++-- .../Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp | 2 +- .../Code/GameEngine/Include/GameLogic/Module/AIUpdate.h | 4 ++-- .../Code/GameEngine/Include/GameLogic/Module/JetAIUpdate.h | 4 ++-- .../GameEngine/Source/GameLogic/Object/Update/AIUpdate.cpp | 4 ++-- .../Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp | 2 +- 8 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Generals/Code/GameEngine/Include/GameLogic/Module/AIUpdate.h b/Generals/Code/GameEngine/Include/GameLogic/Module/AIUpdate.h index 76fdff185c..97432322a9 100644 --- a/Generals/Code/GameEngine/Include/GameLogic/Module/AIUpdate.h +++ b/Generals/Code/GameEngine/Include/GameLogic/Module/AIUpdate.h @@ -244,7 +244,7 @@ class AIUpdateInterface : public UpdateModule, public AICommandInterface virtual void privateFollowWaypointPathAsTeam( const Waypoint *way, CommandSourceType cmdSource );///< start following the path from the given point virtual void privateFollowWaypointPathExact( const Waypoint *way, CommandSourceType cmdSource );///< start following the path from the given point virtual void privateFollowWaypointPathAsTeamExact( const Waypoint *way, CommandSourceType cmdSource );///< start following the path from the given point - virtual void privateFollowPath( const std::vector* path, Object *ignoreObject, CommandSourceType cmdSource, Bool exitProduction );///< follow the path defined by the given array of points + virtual void privateFollowPath( std::vector* path, Object *ignoreObject, CommandSourceType cmdSource, Bool exitProduction );///< follow the path defined by the given array of points virtual void privateFollowPathAppend( const Coord3D *pos, CommandSourceType cmdSource ); virtual void privateAttackObject( Object *victim, Int maxShotsToFire, CommandSourceType cmdSource ); ///< attack given object virtual void privateForceAttackObject( Object *victim, Int maxShotsToFire, CommandSourceType cmdSource ); ///< attack given object @@ -338,7 +338,7 @@ class AIUpdateInterface : public UpdateModule, public AICommandInterface virtual Bool isBusy() const; virtual void onObjectCreated(); - virtual void doQuickExit( const std::vector* path ); ///< get out of this Object + virtual void doQuickExit( std::vector* path ); ///< get out of this Object virtual void aiDoCommand(const AICommandParms* parms); diff --git a/Generals/Code/GameEngine/Include/GameLogic/Module/JetAIUpdate.h b/Generals/Code/GameEngine/Include/GameLogic/Module/JetAIUpdate.h index c1b5facba1..f2e8b792e1 100644 --- a/Generals/Code/GameEngine/Include/GameLogic/Module/JetAIUpdate.h +++ b/Generals/Code/GameEngine/Include/GameLogic/Module/JetAIUpdate.h @@ -104,7 +104,7 @@ class JetAIUpdate : public AIUpdateInterface Real friend_getMinHeight() const { return getJetAIUpdateModuleData()->m_minHeight; } Real friend_getParkingOffset() const { return getJetAIUpdateModuleData()->m_parkingOffset; } UnsignedInt friend_getTakeoffPause() const { return getJetAIUpdateModuleData()->m_takeoffPause; } - void friend_setGoalPath( const std::vector* path ) { getStateMachine()->setGoalPath(path); } + void friend_setGoalPath( std::vector* path ) { getStateMachine()->setGoalPath(path); } void friend_setTakeoffInProgress(Bool v) { setFlag(TAKEOFF_IN_PROGRESS, v); } void friend_setLandingInProgress(Bool v) { setFlag(LANDING_IN_PROGRESS, v); } void friend_setTaxiInProgress(Bool v) { setFlag(TAXI_IN_PROGRESS, v); } @@ -122,7 +122,7 @@ class JetAIUpdate : public AIUpdateInterface virtual AIStateMachine* makeStateMachine(); - virtual void privateFollowPath( const std::vector* path, Object *ignoreObject, CommandSourceType cmdSource, Bool exitProduction );///< follow the path defined by the given array of points + virtual void privateFollowPath( std::vector* path, Object *ignoreObject, CommandSourceType cmdSource, Bool exitProduction );///< follow the path defined by the given array of points virtual void privateFollowPathAppend( const Coord3D *pos, CommandSourceType cmdSource ); virtual void privateEnter( Object *obj, CommandSourceType cmdSource ); ///< enter the given object virtual void privateGetRepaired( Object *repairDepot, CommandSourceType cmdSource );///< get repaired at repair depot diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate.cpp index e515ff54a4..75193a1953 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate.cpp @@ -3240,7 +3240,7 @@ void AIUpdateInterface::privateFollowPathAppend( const Coord3D *pos, CommandSour /** * Follow the path defined by the given array of points */ -void AIUpdateInterface::privateFollowPath( const std::vector* path, Object *ignoreObject, CommandSourceType cmdSource, Bool exitProduction ) +void AIUpdateInterface::privateFollowPath( std::vector* path, Object *ignoreObject, CommandSourceType cmdSource, Bool exitProduction ) { if (getObject()->isMobile() == FALSE) return; @@ -3681,7 +3681,7 @@ void AIUpdateInterface::privateExit( Object *objectToExit, CommandSourceType cmd /** * Get out of whatever it is inside of */ -void AIUpdateInterface::doQuickExit( const std::vector* path ) +void AIUpdateInterface::doQuickExit( std::vector* path ) { Bool locked = getStateMachine()->isLocked(); diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp index 29034934a4..93b7c257e2 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp @@ -2175,7 +2175,7 @@ Bool JetAIUpdate::getTreatAsAircraftForLocoDistToGoal() const /** * Follow the path defined by the given array of points */ -void JetAIUpdate::privateFollowPath( const std::vector* path, Object *ignoreObject, CommandSourceType cmdSource, Bool exitProduction ) +void JetAIUpdate::privateFollowPath( std::vector* path, Object *ignoreObject, CommandSourceType cmdSource, Bool exitProduction ) { if (exitProduction) { diff --git a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/AIUpdate.h b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/AIUpdate.h index 3f5a9d4e9e..4b2024645d 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/AIUpdate.h +++ b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/AIUpdate.h @@ -249,7 +249,7 @@ class AIUpdateInterface : public UpdateModule, public AICommandInterface virtual void privateFollowWaypointPathAsTeam( const Waypoint *way, CommandSourceType cmdSource );///< start following the path from the given point virtual void privateFollowWaypointPathExact( const Waypoint *way, CommandSourceType cmdSource );///< start following the path from the given point virtual void privateFollowWaypointPathAsTeamExact( const Waypoint *way, CommandSourceType cmdSource );///< start following the path from the given point - virtual void privateFollowPath( const std::vector* path, Object *ignoreObject, CommandSourceType cmdSource, Bool exitProduction );///< follow the path defined by the given array of points + virtual void privateFollowPath( std::vector* path, Object *ignoreObject, CommandSourceType cmdSource, Bool exitProduction );///< follow the path defined by the given array of points virtual void privateFollowPathAppend( const Coord3D *pos, CommandSourceType cmdSource ); virtual void privateAttackObject( Object *victim, Int maxShotsToFire, CommandSourceType cmdSource ); ///< attack given object virtual void privateForceAttackObject( Object *victim, Int maxShotsToFire, CommandSourceType cmdSource ); ///< attack given object @@ -351,7 +351,7 @@ class AIUpdateInterface : public UpdateModule, public AICommandInterface virtual Bool isBusy() const; virtual void onObjectCreated(); - virtual void doQuickExit( const std::vector* path ); ///< get out of this Object + virtual void doQuickExit( std::vector* path ); ///< get out of this Object virtual void aiDoCommand(const AICommandParms* parms); diff --git a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/JetAIUpdate.h b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/JetAIUpdate.h index 1840d30a4b..a7cd1157aa 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/JetAIUpdate.h +++ b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/JetAIUpdate.h @@ -110,7 +110,7 @@ class JetAIUpdate : public AIUpdateInterface Real friend_getMinHeight() const { return getJetAIUpdateModuleData()->m_minHeight; } Real friend_getParkingOffset() const { return getJetAIUpdateModuleData()->m_parkingOffset; } UnsignedInt friend_getTakeoffPause() const { return getJetAIUpdateModuleData()->m_takeoffPause; } - void friend_setGoalPath( const std::vector* path ) { getStateMachine()->setGoalPath(path); } + void friend_setGoalPath( std::vector* path ) { getStateMachine()->setGoalPath(path); } void friend_setTakeoffInProgress(Bool v) { setFlag(TAKEOFF_IN_PROGRESS, v); } void friend_setLandingInProgress(Bool v) { setFlag(LANDING_IN_PROGRESS, v); } void friend_setTaxiInProgress(Bool v) { setFlag(TAXI_IN_PROGRESS, v); } @@ -131,7 +131,7 @@ class JetAIUpdate : public AIUpdateInterface virtual AIStateMachine* makeStateMachine(); - virtual void privateFollowPath( const std::vector* path, Object *ignoreObject, CommandSourceType cmdSource, Bool exitProduction );///< follow the path defined by the given array of points + virtual void privateFollowPath( std::vector* path, Object *ignoreObject, CommandSourceType cmdSource, Bool exitProduction );///< follow the path defined by the given array of points virtual void privateFollowPathAppend( const Coord3D *pos, CommandSourceType cmdSource ); virtual void privateEnter( Object *obj, CommandSourceType cmdSource ); ///< enter the given object virtual void privateGetRepaired( Object *repairDepot, CommandSourceType cmdSource );///< get repaired at repair depot diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate.cpp index 2200bfd823..d3259a3609 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate.cpp @@ -3381,7 +3381,7 @@ void AIUpdateInterface::privateFollowPathAppend( const Coord3D *pos, CommandSour /** * Follow the path defined by the given array of points */ -void AIUpdateInterface::privateFollowPath( const std::vector* path, Object *ignoreObject, CommandSourceType cmdSource, Bool exitProduction ) +void AIUpdateInterface::privateFollowPath( std::vector* path, Object *ignoreObject, CommandSourceType cmdSource, Bool exitProduction ) { if (getObject()->isMobile() == FALSE) return; @@ -3873,7 +3873,7 @@ void AIUpdateInterface::privateExitInstantly( Object *objectToExit, CommandSourc /** * Get out of whatever it is inside of */ -void AIUpdateInterface::doQuickExit( const std::vector* path ) +void AIUpdateInterface::doQuickExit( std::vector* path ) { Bool locked = getStateMachine()->isLocked(); diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp index cac797bc77..601173951b 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp @@ -2402,7 +2402,7 @@ Bool JetAIUpdate::getTreatAsAircraftForLocoDistToGoal() const /** * Follow the path defined by the given array of points */ -void JetAIUpdate::privateFollowPath( const std::vector* path, Object *ignoreObject, CommandSourceType cmdSource, Bool exitProduction ) +void JetAIUpdate::privateFollowPath( std::vector* path, Object *ignoreObject, CommandSourceType cmdSource, Bool exitProduction ) { if (exitProduction) { From 315d16fa2489df4a65ea5cf5b0470cee4dbf80ee Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Sun, 23 Nov 2025 12:18:17 -0500 Subject: [PATCH 4/8] Use swap instead of move for VC6 compatibility --- Generals/Code/GameEngine/Include/GameLogic/AI.h | 4 ++-- Generals/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp | 2 +- GeneralsMD/Code/GameEngine/Include/GameLogic/AI.h | 4 ++-- GeneralsMD/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Generals/Code/GameEngine/Include/GameLogic/AI.h b/Generals/Code/GameEngine/Include/GameLogic/AI.h index 703db686f6..c0dff6e831 100644 --- a/Generals/Code/GameEngine/Include/GameLogic/AI.h +++ b/Generals/Code/GameEngine/Include/GameLogic/AI.h @@ -539,7 +539,7 @@ class AICommandInterface inline void aiFollowExitProductionPath( std::vector* path, Object *ignoreObject, CommandSourceType cmdSource ) { AICommandParms parms(AICMD_FOLLOW_EXITPRODUCTION_PATH, cmdSource); - parms.m_coords = std::move(*path); + parms.m_coords.swap(*path); parms.m_obj = ignoreObject; aiDoCommand(&parms); } @@ -547,7 +547,7 @@ class AICommandInterface inline void aiFollowPath( std::vector* path, Object *ignoreObject, CommandSourceType cmdSource ) { AICommandParms parms(AICMD_FOLLOW_PATH, cmdSource); - parms.m_coords = std::move(*path); + parms.m_coords.swap(*path); parms.m_obj = ignoreObject; aiDoCommand(&parms); } diff --git a/Generals/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp b/Generals/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp index 2105a4c121..5034532a26 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp @@ -818,7 +818,7 @@ void AIStateMachine::loadPostProcess( void ) */ void AIStateMachine::setGoalPath( std::vector* path ) { - m_goalPath = std::move(*path); + m_goalPath.swap(*path); } #ifdef STATE_MACHINE_DEBUG diff --git a/GeneralsMD/Code/GameEngine/Include/GameLogic/AI.h b/GeneralsMD/Code/GameEngine/Include/GameLogic/AI.h index a96e66943e..0a75746734 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameLogic/AI.h +++ b/GeneralsMD/Code/GameEngine/Include/GameLogic/AI.h @@ -553,7 +553,7 @@ class AICommandInterface inline void aiFollowExitProductionPath( std::vector* path, Object *ignoreObject, CommandSourceType cmdSource ) { AICommandParms parms(AICMD_FOLLOW_EXITPRODUCTION_PATH, cmdSource); - parms.m_coords = std::move(*path); + parms.m_coords.swap(*path); parms.m_obj = ignoreObject; aiDoCommand(&parms); } @@ -561,7 +561,7 @@ class AICommandInterface inline void aiFollowPath( std::vector* path, Object *ignoreObject, CommandSourceType cmdSource ) { AICommandParms parms(AICMD_FOLLOW_PATH, cmdSource); - parms.m_coords = std::move(*path); + parms.m_coords.swap(*path); parms.m_obj = ignoreObject; aiDoCommand(&parms); } diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp index 449a7834a3..12599f8453 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp @@ -823,7 +823,7 @@ void AIStateMachine::loadPostProcess( void ) */ void AIStateMachine::setGoalPath( std::vector* path ) { - m_goalPath = std::move(*path); + m_goalPath.swap(*path); } #ifdef STATE_MACHINE_DEBUG From e951e6c99a3110b5bd5530e6558c1d43b0935795 Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Sun, 23 Nov 2025 12:19:47 -0500 Subject: [PATCH 5/8] Use const_cast in aiDoCommand to pass non-const vector to privateFollowPath --- .../GameEngine/Source/GameLogic/Object/Update/AIUpdate.cpp | 4 ++-- .../GameEngine/Source/GameLogic/Object/Update/AIUpdate.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate.cpp index 75193a1953..2b6bba6b56 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate.cpp @@ -2619,13 +2619,13 @@ void AIUpdateInterface::aiDoCommand(const AICommandParms* parms) privateFollowWaypointPathAsTeamExact(parms->m_waypoint, parms->m_cmdSource); break; case AICMD_FOLLOW_PATH: - privateFollowPath(&parms->m_coords, parms->m_obj, parms->m_cmdSource, FALSE); + privateFollowPath(&const_cast(parms)->m_coords, parms->m_obj, parms->m_cmdSource, FALSE); break; case AICMD_FOLLOW_PATH_APPEND: privateFollowPathAppend(&parms->m_pos, parms->m_cmdSource); break; case AICMD_FOLLOW_EXITPRODUCTION_PATH: - privateFollowPath(&parms->m_coords, parms->m_obj, parms->m_cmdSource, TRUE); + privateFollowPath(&const_cast(parms)->m_coords, parms->m_obj, parms->m_cmdSource, TRUE); break; case AICMD_ATTACK_OBJECT: privateAttackObject(parms->m_obj, parms->m_intValue, parms->m_cmdSource); diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate.cpp index d3259a3609..4e2e1df3e5 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate.cpp @@ -2681,13 +2681,13 @@ void AIUpdateInterface::aiDoCommand(const AICommandParms* parms) privateFollowWaypointPathAsTeamExact(parms->m_waypoint, parms->m_cmdSource); break; case AICMD_FOLLOW_PATH: - privateFollowPath(&parms->m_coords, parms->m_obj, parms->m_cmdSource, FALSE); + privateFollowPath(&const_cast(parms)->m_coords, parms->m_obj, parms->m_cmdSource, FALSE); break; case AICMD_FOLLOW_PATH_APPEND: privateFollowPathAppend(&parms->m_pos, parms->m_cmdSource); break; case AICMD_FOLLOW_EXITPRODUCTION_PATH: - privateFollowPath(&parms->m_coords, parms->m_obj, parms->m_cmdSource, TRUE); + privateFollowPath(&const_cast(parms)->m_coords, parms->m_obj, parms->m_cmdSource, TRUE); break; case AICMD_ATTACK_OBJECT: privateAttackObject(parms->m_obj, parms->m_intValue, parms->m_cmdSource); From 2a5e8f826c41e78ea3e53a3922e2fcc70d4b4ac6 Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Tue, 25 Nov 2025 12:48:08 -0500 Subject: [PATCH 6/8] Add conditional compilation for move vs swap and clear source vector --- Generals/Code/GameEngine/Include/GameLogic/AI.h | 12 ++++++++++++ .../Code/GameEngine/Source/GameLogic/AI/AIStates.cpp | 7 +++++++ GeneralsMD/Code/GameEngine/Include/GameLogic/AI.h | 12 ++++++++++++ .../Code/GameEngine/Source/GameLogic/AI/AIStates.cpp | 7 +++++++ 4 files changed, 38 insertions(+) diff --git a/Generals/Code/GameEngine/Include/GameLogic/AI.h b/Generals/Code/GameEngine/Include/GameLogic/AI.h index c0dff6e831..70d3ca3f0f 100644 --- a/Generals/Code/GameEngine/Include/GameLogic/AI.h +++ b/Generals/Code/GameEngine/Include/GameLogic/AI.h @@ -539,7 +539,13 @@ class AICommandInterface inline void aiFollowExitProductionPath( std::vector* path, Object *ignoreObject, CommandSourceType cmdSource ) { AICommandParms parms(AICMD_FOLLOW_EXITPRODUCTION_PATH, cmdSource); +#if __cplusplus >= 201103L + parms.m_coords = std::move(*path); +#else + // TheSuperHackers @performance bobtista 23/11/2025 Use swap to emulate move semantics for VC6 compatibility parms.m_coords.swap(*path); + path->clear(); +#endif parms.m_obj = ignoreObject; aiDoCommand(&parms); } @@ -547,7 +553,13 @@ class AICommandInterface inline void aiFollowPath( std::vector* path, Object *ignoreObject, CommandSourceType cmdSource ) { AICommandParms parms(AICMD_FOLLOW_PATH, cmdSource); +#if __cplusplus >= 201103L + parms.m_coords = std::move(*path); +#else + // TheSuperHackers @performance bobtista 23/11/2025 Use swap to emulate move semantics for VC6 compatibility parms.m_coords.swap(*path); + path->clear(); +#endif parms.m_obj = ignoreObject; aiDoCommand(&parms); } diff --git a/Generals/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp b/Generals/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp index 5034532a26..39b3540a21 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp @@ -818,7 +818,14 @@ void AIStateMachine::loadPostProcess( void ) */ void AIStateMachine::setGoalPath( std::vector* path ) { +#if __cplusplus >= 201103L + m_goalPath = std::move(*path); +#else + // TheSuperHackers @performance bobtista 23/11/2025 Use swap to emulate move semantics for VC6 compatibility + // Swap transfers ownership without copying. Clear source to make intent explicit. m_goalPath.swap(*path); + path->clear(); +#endif } #ifdef STATE_MACHINE_DEBUG diff --git a/GeneralsMD/Code/GameEngine/Include/GameLogic/AI.h b/GeneralsMD/Code/GameEngine/Include/GameLogic/AI.h index 0a75746734..ab8e886c2c 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameLogic/AI.h +++ b/GeneralsMD/Code/GameEngine/Include/GameLogic/AI.h @@ -553,7 +553,13 @@ class AICommandInterface inline void aiFollowExitProductionPath( std::vector* path, Object *ignoreObject, CommandSourceType cmdSource ) { AICommandParms parms(AICMD_FOLLOW_EXITPRODUCTION_PATH, cmdSource); +#if __cplusplus >= 201103L + parms.m_coords = std::move(*path); +#else + // TheSuperHackers @performance bobtista 23/11/2025 Use swap to emulate move semantics for VC6 compatibility parms.m_coords.swap(*path); + path->clear(); +#endif parms.m_obj = ignoreObject; aiDoCommand(&parms); } @@ -561,7 +567,13 @@ class AICommandInterface inline void aiFollowPath( std::vector* path, Object *ignoreObject, CommandSourceType cmdSource ) { AICommandParms parms(AICMD_FOLLOW_PATH, cmdSource); +#if __cplusplus >= 201103L + parms.m_coords = std::move(*path); +#else + // TheSuperHackers @performance bobtista 23/11/2025 Use swap to emulate move semantics for VC6 compatibility parms.m_coords.swap(*path); + path->clear(); +#endif parms.m_obj = ignoreObject; aiDoCommand(&parms); } diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp index 12599f8453..8be2816239 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp @@ -823,7 +823,14 @@ void AIStateMachine::loadPostProcess( void ) */ void AIStateMachine::setGoalPath( std::vector* path ) { +#if __cplusplus >= 201103L + m_goalPath = std::move(*path); +#else + // TheSuperHackers @performance bobtista 23/11/2025 Use swap to emulate move semantics for VC6 compatibility + // Swap transfers ownership without copying. Clear source to make intent explicit. m_goalPath.swap(*path); + path->clear(); +#endif } #ifdef STATE_MACHINE_DEBUG From fae80299e12e123bcd77e3899433351318de844a Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Tue, 25 Nov 2025 14:18:54 -0500 Subject: [PATCH 7/8] nit: make comments consistent --- Generals/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp | 1 - GeneralsMD/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp | 1 - 2 files changed, 2 deletions(-) diff --git a/Generals/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp b/Generals/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp index 39b3540a21..7292a43200 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp @@ -822,7 +822,6 @@ void AIStateMachine::setGoalPath( std::vector* path ) m_goalPath = std::move(*path); #else // TheSuperHackers @performance bobtista 23/11/2025 Use swap to emulate move semantics for VC6 compatibility - // Swap transfers ownership without copying. Clear source to make intent explicit. m_goalPath.swap(*path); path->clear(); #endif diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp index 8be2816239..17dc02d19b 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp @@ -827,7 +827,6 @@ void AIStateMachine::setGoalPath( std::vector* path ) m_goalPath = std::move(*path); #else // TheSuperHackers @performance bobtista 23/11/2025 Use swap to emulate move semantics for VC6 compatibility - // Swap transfers ownership without copying. Clear source to make intent explicit. m_goalPath.swap(*path); path->clear(); #endif From 69c373c57e34d2f5e9cac2bf484193159b988b04 Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Tue, 25 Nov 2025 14:34:08 -0500 Subject: [PATCH 8/8] refactor(perf): centralize move semantics helper in CppMacros.h --- Dependencies/Utility/Utility/CppMacros.h | 16 ++++++++++++++++ Generals/Code/GameEngine/Include/GameLogic/AI.h | 17 +++-------------- .../Include/GameLogic/AIStateMachine.h | 2 ++ .../GameEngine/Source/GameLogic/AI/AIStates.cpp | 8 +------- .../Code/GameEngine/Include/GameLogic/AI.h | 17 +++-------------- .../Include/GameLogic/AIStateMachine.h | 2 ++ .../GameEngine/Source/GameLogic/AI/AIStates.cpp | 8 +------- 7 files changed, 28 insertions(+), 42 deletions(-) diff --git a/Dependencies/Utility/Utility/CppMacros.h b/Dependencies/Utility/Utility/CppMacros.h index 8bfb0297f2..aa7b8cf4c6 100644 --- a/Dependencies/Utility/Utility/CppMacros.h +++ b/Dependencies/Utility/Utility/CppMacros.h @@ -19,6 +19,10 @@ // This file contains macros to help upgrade the code for newer cpp standards. #pragma once +#if __cplusplus >= 201103L +#include +#endif + #if __cplusplus >= 201703L #define NOEXCEPT_17 noexcept #define REGISTER @@ -44,3 +48,15 @@ #define constexpr #define nullptr 0 #endif + +// TheSuperHackers @performance bobtista 25/11/2025 Helper to move-assign from pointer: uses std::move in C++11, swap in C++98 +template +inline void move_assign_from_pointer(T& dest, T* src) +{ +#if __cplusplus >= 201103L + dest = std::move(*src); +#else + // Use swap to emulate move semantics for VC6 compatibility + dest.swap(*src); +#endif +} diff --git a/Generals/Code/GameEngine/Include/GameLogic/AI.h b/Generals/Code/GameEngine/Include/GameLogic/AI.h index 70d3ca3f0f..3f4c6b081e 100644 --- a/Generals/Code/GameEngine/Include/GameLogic/AI.h +++ b/Generals/Code/GameEngine/Include/GameLogic/AI.h @@ -35,6 +35,7 @@ #include "GameLogic/Damage.h" #include "Common/STLTypedefs.h" #include "ref_ptr.h" +#include "Utility/CppMacros.h" class AIGroup; class AttackPriorityInfo; @@ -539,13 +540,7 @@ class AICommandInterface inline void aiFollowExitProductionPath( std::vector* path, Object *ignoreObject, CommandSourceType cmdSource ) { AICommandParms parms(AICMD_FOLLOW_EXITPRODUCTION_PATH, cmdSource); -#if __cplusplus >= 201103L - parms.m_coords = std::move(*path); -#else - // TheSuperHackers @performance bobtista 23/11/2025 Use swap to emulate move semantics for VC6 compatibility - parms.m_coords.swap(*path); - path->clear(); -#endif + move_assign_from_pointer(parms.m_coords, path); parms.m_obj = ignoreObject; aiDoCommand(&parms); } @@ -553,13 +548,7 @@ class AICommandInterface inline void aiFollowPath( std::vector* path, Object *ignoreObject, CommandSourceType cmdSource ) { AICommandParms parms(AICMD_FOLLOW_PATH, cmdSource); -#if __cplusplus >= 201103L - parms.m_coords = std::move(*path); -#else - // TheSuperHackers @performance bobtista 23/11/2025 Use swap to emulate move semantics for VC6 compatibility - parms.m_coords.swap(*path); - path->clear(); -#endif + move_assign_from_pointer(parms.m_coords, path); parms.m_obj = ignoreObject; aiDoCommand(&parms); } diff --git a/Generals/Code/GameEngine/Include/GameLogic/AIStateMachine.h b/Generals/Code/GameEngine/Include/GameLogic/AIStateMachine.h index 7e39c8ec7c..3992972456 100644 --- a/Generals/Code/GameEngine/Include/GameLogic/AIStateMachine.h +++ b/Generals/Code/GameEngine/Include/GameLogic/AIStateMachine.h @@ -108,6 +108,8 @@ extern Bool outOfWeaponRangeObject( State *thisState, void* userData ); extern Bool outOfWeaponRangePosition( State *thisState, void* userData ); extern Bool wantToSquishTarget( State *thisState, void* userData ); +#include "Utility/CppMacros.h" + //----------------------------------------------------------------------------------------------------------- /** The AI state machine. This is used by AIUpdate to implement all of the diff --git a/Generals/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp b/Generals/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp index 7292a43200..ad1ca0207f 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp @@ -818,13 +818,7 @@ void AIStateMachine::loadPostProcess( void ) */ void AIStateMachine::setGoalPath( std::vector* path ) { -#if __cplusplus >= 201103L - m_goalPath = std::move(*path); -#else - // TheSuperHackers @performance bobtista 23/11/2025 Use swap to emulate move semantics for VC6 compatibility - m_goalPath.swap(*path); - path->clear(); -#endif + move_assign_from_pointer(m_goalPath, path); } #ifdef STATE_MACHINE_DEBUG diff --git a/GeneralsMD/Code/GameEngine/Include/GameLogic/AI.h b/GeneralsMD/Code/GameEngine/Include/GameLogic/AI.h index ab8e886c2c..41c24482b2 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameLogic/AI.h +++ b/GeneralsMD/Code/GameEngine/Include/GameLogic/AI.h @@ -35,6 +35,7 @@ #include "GameLogic/Damage.h" #include "Common/STLTypedefs.h" #include "ref_ptr.h" +#include "Utility/CppMacros.h" class AIGroup; class AttackPriorityInfo; @@ -553,13 +554,7 @@ class AICommandInterface inline void aiFollowExitProductionPath( std::vector* path, Object *ignoreObject, CommandSourceType cmdSource ) { AICommandParms parms(AICMD_FOLLOW_EXITPRODUCTION_PATH, cmdSource); -#if __cplusplus >= 201103L - parms.m_coords = std::move(*path); -#else - // TheSuperHackers @performance bobtista 23/11/2025 Use swap to emulate move semantics for VC6 compatibility - parms.m_coords.swap(*path); - path->clear(); -#endif + move_assign_from_pointer(parms.m_coords, path); parms.m_obj = ignoreObject; aiDoCommand(&parms); } @@ -567,13 +562,7 @@ class AICommandInterface inline void aiFollowPath( std::vector* path, Object *ignoreObject, CommandSourceType cmdSource ) { AICommandParms parms(AICMD_FOLLOW_PATH, cmdSource); -#if __cplusplus >= 201103L - parms.m_coords = std::move(*path); -#else - // TheSuperHackers @performance bobtista 23/11/2025 Use swap to emulate move semantics for VC6 compatibility - parms.m_coords.swap(*path); - path->clear(); -#endif + move_assign_from_pointer(parms.m_coords, path); parms.m_obj = ignoreObject; aiDoCommand(&parms); } diff --git a/GeneralsMD/Code/GameEngine/Include/GameLogic/AIStateMachine.h b/GeneralsMD/Code/GameEngine/Include/GameLogic/AIStateMachine.h index 8d96e65997..67274eae0d 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameLogic/AIStateMachine.h +++ b/GeneralsMD/Code/GameEngine/Include/GameLogic/AIStateMachine.h @@ -111,6 +111,8 @@ extern Bool outOfWeaponRangeObject( State *thisState, void* userData ); extern Bool outOfWeaponRangePosition( State *thisState, void* userData ); extern Bool wantToSquishTarget( State *thisState, void* userData ); +#include "Utility/CppMacros.h" + //----------------------------------------------------------------------------------------------------------- /** The AI state machine. This is used by AIUpdate to implement all of the diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp index 17dc02d19b..c064b6d5b1 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp @@ -823,13 +823,7 @@ void AIStateMachine::loadPostProcess( void ) */ void AIStateMachine::setGoalPath( std::vector* path ) { -#if __cplusplus >= 201103L - m_goalPath = std::move(*path); -#else - // TheSuperHackers @performance bobtista 23/11/2025 Use swap to emulate move semantics for VC6 compatibility - m_goalPath.swap(*path); - path->clear(); -#endif + move_assign_from_pointer(m_goalPath, path); } #ifdef STATE_MACHINE_DEBUG