Skip to content

Commit 925ecf1

Browse files
authored
perf(ai): Avoid a few std::vector copies when passing ai paths to functions (#1895)
1 parent 0d6c776 commit 925ecf1

File tree

15 files changed

+68
-32
lines changed

15 files changed

+68
-32
lines changed

Dependencies/Utility/Utility/CppMacros.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@
1919
// This file contains macros to help upgrade the code for newer cpp standards.
2020
#pragma once
2121

22+
#if __cplusplus >= 201103L
23+
#include <utility>
24+
#endif
25+
2226
#if __cplusplus >= 201703L
2327
#define NOEXCEPT_17 noexcept
2428
#define REGISTER
@@ -44,3 +48,23 @@
4448
#define constexpr
4549
#define nullptr 0
4650
#endif
51+
52+
namespace stl
53+
{
54+
55+
// Helper to move-assign from reference: uses std::move in C++11, swap in C++98
56+
template<typename T>
57+
inline void move_or_swap(T& dest, T& src)
58+
{
59+
#if __cplusplus >= 201103L
60+
dest = std::move(src);
61+
#else
62+
// C++03 fallback: mimic move semantics
63+
// dest gets src's value, src becomes empty
64+
T empty;
65+
dest.swap(src);
66+
src.swap(empty);
67+
#endif
68+
}
69+
70+
} // namespace stl

Generals/Code/GameEngine/Include/GameLogic/AI.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -536,18 +536,18 @@ class AICommandInterface
536536
aiDoCommand(&parms);
537537
}
538538

539-
void aiFollowExitProductionPath( const std::vector<Coord3D>* path, Object *ignoreObject, CommandSourceType cmdSource )
539+
void aiFollowExitProductionPath( std::vector<Coord3D>* path, Object *ignoreObject, CommandSourceType cmdSource )
540540
{
541541
AICommandParms parms(AICMD_FOLLOW_EXITPRODUCTION_PATH, cmdSource);
542-
parms.m_coords = *path;
542+
stl::move_or_swap(parms.m_coords, *path);
543543
parms.m_obj = ignoreObject;
544544
aiDoCommand(&parms);
545545
}
546546

547-
void aiFollowPath( const std::vector<Coord3D>* path, Object *ignoreObject, CommandSourceType cmdSource )
547+
void aiFollowPath( std::vector<Coord3D>* path, Object *ignoreObject, CommandSourceType cmdSource )
548548
{
549549
AICommandParms parms(AICMD_FOLLOW_PATH, cmdSource);
550-
parms.m_coords = *path;
550+
stl::move_or_swap(parms.m_coords, *path);
551551
parms.m_obj = ignoreObject;
552552
aiDoCommand(&parms);
553553
}

Generals/Code/GameEngine/Include/GameLogic/AIStateMachine.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ class AIStateMachine : public StateMachine
138138
virtual StateReturnType setState( StateID newStateID );
139139

140140
/// @todo Rethink state parameter passing. Continuing in this fashion will have a pile of params in the machine (MSB)
141-
void setGoalPath( const std::vector<Coord3D>* path );
141+
void setGoalPath( std::vector<Coord3D>* path );
142142
void addToGoalPath( const Coord3D *pathPoint );
143143
const Coord3D *getGoalPathPosition( Int i ) const; ///< return path position at index "i"
144144
Int getGoalPathSize() const { return m_goalPath.size(); }

Generals/Code/GameEngine/Include/GameLogic/Module/AIUpdate.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ class AIUpdateInterface : public UpdateModule, public AICommandInterface
244244
virtual void privateFollowWaypointPathAsTeam( const Waypoint *way, CommandSourceType cmdSource );///< start following the path from the given point
245245
virtual void privateFollowWaypointPathExact( const Waypoint *way, CommandSourceType cmdSource );///< start following the path from the given point
246246
virtual void privateFollowWaypointPathAsTeamExact( const Waypoint *way, CommandSourceType cmdSource );///< start following the path from the given point
247-
virtual void privateFollowPath( const std::vector<Coord3D>* path, Object *ignoreObject, CommandSourceType cmdSource, Bool exitProduction );///< follow the path defined by the given array of points
247+
virtual void privateFollowPath( std::vector<Coord3D>* path, Object *ignoreObject, CommandSourceType cmdSource, Bool exitProduction );///< follow the path defined by the given array of points
248248
virtual void privateFollowPathAppend( const Coord3D *pos, CommandSourceType cmdSource );
249249
virtual void privateAttackObject( Object *victim, Int maxShotsToFire, CommandSourceType cmdSource ); ///< attack given object
250250
virtual void privateForceAttackObject( Object *victim, Int maxShotsToFire, CommandSourceType cmdSource ); ///< attack given object
@@ -338,7 +338,7 @@ class AIUpdateInterface : public UpdateModule, public AICommandInterface
338338
virtual Bool isBusy() const;
339339

340340
virtual void onObjectCreated();
341-
virtual void doQuickExit( const std::vector<Coord3D>* path ); ///< get out of this Object
341+
virtual void doQuickExit( std::vector<Coord3D>* path ); ///< get out of this Object
342342

343343
virtual void aiDoCommand(const AICommandParms* parms);
344344

Generals/Code/GameEngine/Include/GameLogic/Module/JetAIUpdate.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ class JetAIUpdate : public AIUpdateInterface
104104
Real friend_getMinHeight() const { return getJetAIUpdateModuleData()->m_minHeight; }
105105
Real friend_getParkingOffset() const { return getJetAIUpdateModuleData()->m_parkingOffset; }
106106
UnsignedInt friend_getTakeoffPause() const { return getJetAIUpdateModuleData()->m_takeoffPause; }
107-
void friend_setGoalPath( const std::vector<Coord3D>* path ) { getStateMachine()->setGoalPath(path); }
107+
void friend_setGoalPath( std::vector<Coord3D>* path ) { getStateMachine()->setGoalPath(path); }
108108
void friend_setTakeoffInProgress(Bool v) { setFlag(TAKEOFF_IN_PROGRESS, v); }
109109
void friend_setLandingInProgress(Bool v) { setFlag(LANDING_IN_PROGRESS, v); }
110110
void friend_setTaxiInProgress(Bool v) { setFlag(TAXI_IN_PROGRESS, v); }
@@ -122,7 +122,7 @@ class JetAIUpdate : public AIUpdateInterface
122122

123123
virtual AIStateMachine* makeStateMachine();
124124

125-
virtual void privateFollowPath( const std::vector<Coord3D>* path, Object *ignoreObject, CommandSourceType cmdSource, Bool exitProduction );///< follow the path defined by the given array of points
125+
virtual void privateFollowPath( std::vector<Coord3D>* path, Object *ignoreObject, CommandSourceType cmdSource, Bool exitProduction );///< follow the path defined by the given array of points
126126
virtual void privateFollowPathAppend( const Coord3D *pos, CommandSourceType cmdSource );
127127
virtual void privateEnter( Object *obj, CommandSourceType cmdSource ); ///< enter the given object
128128
virtual void privateGetRepaired( Object *repairDepot, CommandSourceType cmdSource );///< get repaired at repair depot

Generals/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -816,9 +816,9 @@ void AIStateMachine::loadPostProcess( void )
816816
/**
817817
* Define a simple path
818818
*/
819-
void AIStateMachine::setGoalPath( const std::vector<Coord3D>* path )
819+
void AIStateMachine::setGoalPath( std::vector<Coord3D>* path )
820820
{
821-
m_goalPath = *path;
821+
stl::move_or_swap(m_goalPath, *path);
822822
}
823823

824824
#ifdef STATE_MACHINE_DEBUG

Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2619,14 +2619,20 @@ void AIUpdateInterface::aiDoCommand(const AICommandParms* parms)
26192619
privateFollowWaypointPathAsTeamExact(parms->m_waypoint, parms->m_cmdSource);
26202620
break;
26212621
case AICMD_FOLLOW_PATH:
2622-
privateFollowPath(&parms->m_coords, parms->m_obj, parms->m_cmdSource, FALSE);
2622+
{
2623+
std::vector<Coord3D> coords = parms->m_coords;
2624+
privateFollowPath(&coords, parms->m_obj, parms->m_cmdSource, FALSE);
26232625
break;
2626+
}
26242627
case AICMD_FOLLOW_PATH_APPEND:
26252628
privateFollowPathAppend(&parms->m_pos, parms->m_cmdSource);
26262629
break;
26272630
case AICMD_FOLLOW_EXITPRODUCTION_PATH:
2628-
privateFollowPath(&parms->m_coords, parms->m_obj, parms->m_cmdSource, TRUE);
2631+
{
2632+
std::vector<Coord3D> coords = parms->m_coords;
2633+
privateFollowPath(&coords, parms->m_obj, parms->m_cmdSource, TRUE);
26292634
break;
2635+
}
26302636
case AICMD_ATTACK_OBJECT:
26312637
privateAttackObject(parms->m_obj, parms->m_intValue, parms->m_cmdSource);
26322638
break;
@@ -3240,7 +3246,7 @@ void AIUpdateInterface::privateFollowPathAppend( const Coord3D *pos, CommandSour
32403246
/**
32413247
* Follow the path defined by the given array of points
32423248
*/
3243-
void AIUpdateInterface::privateFollowPath( const std::vector<Coord3D>* path, Object *ignoreObject, CommandSourceType cmdSource, Bool exitProduction )
3249+
void AIUpdateInterface::privateFollowPath( std::vector<Coord3D>* path, Object *ignoreObject, CommandSourceType cmdSource, Bool exitProduction )
32443250
{
32453251
if (getObject()->isMobile() == FALSE)
32463252
return;
@@ -3681,7 +3687,7 @@ void AIUpdateInterface::privateExit( Object *objectToExit, CommandSourceType cmd
36813687
/**
36823688
* Get out of whatever it is inside of
36833689
*/
3684-
void AIUpdateInterface::doQuickExit( const std::vector<Coord3D>* path )
3690+
void AIUpdateInterface::doQuickExit( std::vector<Coord3D>* path )
36853691
{
36863692

36873693
Bool locked = getStateMachine()->isLocked();

Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2172,7 +2172,7 @@ Bool JetAIUpdate::getTreatAsAircraftForLocoDistToGoal() const
21722172
/**
21732173
* Follow the path defined by the given array of points
21742174
*/
2175-
void JetAIUpdate::privateFollowPath( const std::vector<Coord3D>* path, Object *ignoreObject, CommandSourceType cmdSource, Bool exitProduction )
2175+
void JetAIUpdate::privateFollowPath( std::vector<Coord3D>* path, Object *ignoreObject, CommandSourceType cmdSource, Bool exitProduction )
21762176
{
21772177
if (exitProduction)
21782178
{

GeneralsMD/Code/GameEngine/Include/GameLogic/AI.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -550,18 +550,18 @@ class AICommandInterface
550550
aiDoCommand(&parms);
551551
}
552552

553-
void aiFollowExitProductionPath( const std::vector<Coord3D>* path, Object *ignoreObject, CommandSourceType cmdSource )
553+
void aiFollowExitProductionPath( std::vector<Coord3D>* path, Object *ignoreObject, CommandSourceType cmdSource )
554554
{
555555
AICommandParms parms(AICMD_FOLLOW_EXITPRODUCTION_PATH, cmdSource);
556-
parms.m_coords = *path;
556+
stl::move_or_swap(parms.m_coords, *path);
557557
parms.m_obj = ignoreObject;
558558
aiDoCommand(&parms);
559559
}
560560

561-
void aiFollowPath( const std::vector<Coord3D>* path, Object *ignoreObject, CommandSourceType cmdSource )
561+
void aiFollowPath( std::vector<Coord3D>* path, Object *ignoreObject, CommandSourceType cmdSource )
562562
{
563563
AICommandParms parms(AICMD_FOLLOW_PATH, cmdSource);
564-
parms.m_coords = *path;
564+
stl::move_or_swap(parms.m_coords, *path);
565565
parms.m_obj = ignoreObject;
566566
aiDoCommand(&parms);
567567
}

GeneralsMD/Code/GameEngine/Include/GameLogic/AIStateMachine.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ class AIStateMachine : public StateMachine
141141
virtual StateReturnType setState( StateID newStateID );
142142

143143
/// @todo Rethink state parameter passing. Continuing in this fashion will have a pile of params in the machine (MSB)
144-
void setGoalPath( const std::vector<Coord3D>* path );
144+
void setGoalPath( std::vector<Coord3D>* path );
145145
void addToGoalPath( const Coord3D *pathPoint );
146146
const Coord3D *getGoalPathPosition( Int i ) const; ///< return path position at index "i"
147147
Int getGoalPathSize() const { return m_goalPath.size(); }

0 commit comments

Comments
 (0)