mirror of
https://gitea.wildfiregames.com/0ad/0ad
synced 2026-06-16 13:23:56 -07:00
Const-Correct the long range pathfinder
Debug variables are kept mutable as one otherwise has to use a complex system and this is really not worth it. Reviewed By: vladislavbelov Differential Revision: https://code.wildfiregames.com/D1491 This was SVN commit r22219.
This commit is contained in:
parent
d3de36527d
commit
fa726867f1
2 changed files with 38 additions and 29 deletions
|
|
@ -388,7 +388,7 @@ LongPathfinder::~LongPathfinder()
|
|||
|
||||
// Calculate heuristic cost from tile i,j to goal
|
||||
// (This ought to be an underestimate for correctness)
|
||||
PathCost LongPathfinder::CalculateHeuristic(int i, int j, int iGoal, int jGoal)
|
||||
PathCost LongPathfinder::CalculateHeuristic(int i, int j, int iGoal, int jGoal) const
|
||||
{
|
||||
int di = abs(i - iGoal);
|
||||
int dj = abs(j - jGoal);
|
||||
|
|
@ -397,7 +397,7 @@ PathCost LongPathfinder::CalculateHeuristic(int i, int j, int iGoal, int jGoal)
|
|||
}
|
||||
|
||||
// Do the A* processing for a neighbour tile i,j.
|
||||
void LongPathfinder::ProcessNeighbour(int pi, int pj, int i, int j, PathCost pg, PathfinderState& state)
|
||||
void LongPathfinder::ProcessNeighbour(int pi, int pj, int i, int j, PathCost pg, PathfinderState& state) const
|
||||
{
|
||||
// Reject impassable tiles
|
||||
if (!PASSABLE(i, j))
|
||||
|
|
@ -501,7 +501,7 @@ inline bool OnTheWay(int i, int j, int di, int dj, int iGoal, int jGoal)
|
|||
}
|
||||
|
||||
|
||||
void LongPathfinder::AddJumpedHoriz(int i, int j, int di, PathCost g, PathfinderState& state, bool detectGoal)
|
||||
void LongPathfinder::AddJumpedHoriz(int i, int j, int di, PathCost g, PathfinderState& state, bool detectGoal) const
|
||||
{
|
||||
if (m_UseJPSCache)
|
||||
{
|
||||
|
|
@ -543,7 +543,7 @@ void LongPathfinder::AddJumpedHoriz(int i, int j, int di, PathCost g, Pathfinder
|
|||
}
|
||||
|
||||
// Returns the i-coordinate of the jump point if it exists, else returns i
|
||||
int LongPathfinder::HasJumpedHoriz(int i, int j, int di, PathfinderState& state, bool detectGoal)
|
||||
int LongPathfinder::HasJumpedHoriz(int i, int j, int di, PathfinderState& state, bool detectGoal) const
|
||||
{
|
||||
if (m_UseJPSCache)
|
||||
{
|
||||
|
|
@ -579,7 +579,7 @@ int LongPathfinder::HasJumpedHoriz(int i, int j, int di, PathfinderState& state,
|
|||
}
|
||||
}
|
||||
|
||||
void LongPathfinder::AddJumpedVert(int i, int j, int dj, PathCost g, PathfinderState& state, bool detectGoal)
|
||||
void LongPathfinder::AddJumpedVert(int i, int j, int dj, PathCost g, PathfinderState& state, bool detectGoal) const
|
||||
{
|
||||
if (m_UseJPSCache)
|
||||
{
|
||||
|
|
@ -621,7 +621,7 @@ void LongPathfinder::AddJumpedVert(int i, int j, int dj, PathCost g, PathfinderS
|
|||
}
|
||||
|
||||
// Returns the j-coordinate of the jump point if it exists, else returns j
|
||||
int LongPathfinder::HasJumpedVert(int i, int j, int dj, PathfinderState& state, bool detectGoal)
|
||||
int LongPathfinder::HasJumpedVert(int i, int j, int dj, PathfinderState& state, bool detectGoal) const
|
||||
{
|
||||
if (m_UseJPSCache)
|
||||
{
|
||||
|
|
@ -661,7 +661,7 @@ int LongPathfinder::HasJumpedVert(int i, int j, int dj, PathfinderState& state,
|
|||
* We never cache diagonal jump points - they're usually so frequent that
|
||||
* a linear search is about as cheap and avoids the setup cost and memory cost.
|
||||
*/
|
||||
void LongPathfinder::AddJumpedDiag(int i, int j, int di, int dj, PathCost g, PathfinderState& state)
|
||||
void LongPathfinder::AddJumpedDiag(int i, int j, int di, int dj, PathCost g, PathfinderState& state) const
|
||||
{
|
||||
// ProcessNeighbour(i, j, i + di, j + dj, g, state);
|
||||
// return;
|
||||
|
|
@ -712,13 +712,16 @@ void LongPathfinder::AddJumpedDiag(int i, int j, int di, int dj, PathCost g, Pat
|
|||
}
|
||||
}
|
||||
|
||||
void LongPathfinder::ComputeJPSPath(entity_pos_t x0, entity_pos_t z0, const PathGoal& origGoal, pass_class_t passClass, WaypointPath& path)
|
||||
void LongPathfinder::ComputeJPSPath(entity_pos_t x0, entity_pos_t z0, const PathGoal& origGoal, pass_class_t passClass, WaypointPath& path) const
|
||||
{
|
||||
PROFILE("ComputePathJPS");
|
||||
PROFILE2_IFSPIKE("ComputePathJPS", 0.0002);
|
||||
PathfinderState state = { 0 };
|
||||
|
||||
state.jpc = m_JumpPointCache[passClass].get();
|
||||
auto it = m_JumpPointCache.find(passClass);
|
||||
ENSURE(it != m_JumpPointCache.end());
|
||||
state.jpc = it->second.get();
|
||||
|
||||
if (m_UseJPSCache && !state.jpc)
|
||||
{
|
||||
state.jpc = new JumpPointCache;
|
||||
|
|
@ -905,7 +908,7 @@ void LongPathfinder::ComputeJPSPath(entity_pos_t x0, entity_pos_t z0, const Path
|
|||
|
||||
#undef PASSABLE
|
||||
|
||||
void LongPathfinder::ImprovePathWaypoints(WaypointPath& path, pass_class_t passClass, entity_pos_t maxDist, entity_pos_t x0, entity_pos_t z0)
|
||||
void LongPathfinder::ImprovePathWaypoints(WaypointPath& path, pass_class_t passClass, entity_pos_t maxDist, entity_pos_t x0, entity_pos_t z0) const
|
||||
{
|
||||
if (path.m_Waypoints.empty())
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -217,7 +217,7 @@ public:
|
|||
* along the path.
|
||||
*/
|
||||
void ComputePath(entity_pos_t x0, entity_pos_t z0, const PathGoal& origGoal,
|
||||
pass_class_t passClass, WaypointPath& path)
|
||||
pass_class_t passClass, WaypointPath& path) const
|
||||
{
|
||||
if (!m_Grid)
|
||||
{
|
||||
|
|
@ -250,34 +250,36 @@ public:
|
|||
Grid<NavcellData>* m_Grid;
|
||||
u16 m_GridSize;
|
||||
|
||||
// Debugging - output from last pathfind operation:
|
||||
LongOverlay* m_DebugOverlay;
|
||||
PathfindTileGrid* m_DebugGrid;
|
||||
u32 m_DebugSteps;
|
||||
double m_DebugTime;
|
||||
PathGoal m_DebugGoal;
|
||||
WaypointPath* m_DebugPath;
|
||||
pass_class_t m_DebugPassClass;
|
||||
// Debugging - output from last pathfind operation.
|
||||
// mutable as making these const would require a lot of boilerplate code
|
||||
// and they do not change the behavioural const-ness of the pathfinder.
|
||||
mutable LongOverlay* m_DebugOverlay;
|
||||
mutable PathfindTileGrid* m_DebugGrid;
|
||||
mutable u32 m_DebugSteps;
|
||||
mutable double m_DebugTime;
|
||||
mutable PathGoal m_DebugGoal;
|
||||
mutable WaypointPath* m_DebugPath;
|
||||
mutable pass_class_t m_DebugPassClass;
|
||||
|
||||
private:
|
||||
PathCost CalculateHeuristic(int i, int j, int iGoal, int jGoal);
|
||||
void ProcessNeighbour(int pi, int pj, int i, int j, PathCost pg, PathfinderState& state);
|
||||
PathCost CalculateHeuristic(int i, int j, int iGoal, int jGoal) const;
|
||||
void ProcessNeighbour(int pi, int pj, int i, int j, PathCost pg, PathfinderState& state) const;
|
||||
|
||||
/**
|
||||
* JPS algorithm helper functions
|
||||
* @param detectGoal is not used if m_UseJPSCache is true
|
||||
*/
|
||||
void AddJumpedHoriz(int i, int j, int di, PathCost g, PathfinderState& state, bool detectGoal);
|
||||
int HasJumpedHoriz(int i, int j, int di, PathfinderState& state, bool detectGoal);
|
||||
void AddJumpedVert(int i, int j, int dj, PathCost g, PathfinderState& state, bool detectGoal);
|
||||
int HasJumpedVert(int i, int j, int dj, PathfinderState& state, bool detectGoal);
|
||||
void AddJumpedDiag(int i, int j, int di, int dj, PathCost g, PathfinderState& state);
|
||||
void AddJumpedHoriz(int i, int j, int di, PathCost g, PathfinderState& state, bool detectGoal) const;
|
||||
int HasJumpedHoriz(int i, int j, int di, PathfinderState& state, bool detectGoal) const;
|
||||
void AddJumpedVert(int i, int j, int dj, PathCost g, PathfinderState& state, bool detectGoal) const;
|
||||
int HasJumpedVert(int i, int j, int dj, PathfinderState& state, bool detectGoal) const;
|
||||
void AddJumpedDiag(int i, int j, int di, int dj, PathCost g, PathfinderState& state) const;
|
||||
|
||||
/**
|
||||
* See LongPathfinder.cpp for implementation details
|
||||
* TODO: cleanup documentation
|
||||
*/
|
||||
void ComputeJPSPath(entity_pos_t x0, entity_pos_t z0, const PathGoal& origGoal, pass_class_t passClass, WaypointPath& path);
|
||||
void ComputeJPSPath(entity_pos_t x0, entity_pos_t z0, const PathGoal& origGoal, pass_class_t passClass, WaypointPath& path) const;
|
||||
void GetDebugDataJPS(u32& steps, double& time, Grid<u8>& grid) const;
|
||||
|
||||
// Helper functions for ComputePath
|
||||
|
|
@ -290,7 +292,7 @@ private:
|
|||
* If @param maxDist is non-zero, path waypoints will be espaced by at most @param maxDist.
|
||||
* In that case the distance between (x0, z0) and the first waypoint will also be made less than maxDist.
|
||||
*/
|
||||
void ImprovePathWaypoints(WaypointPath& path, pass_class_t passClass, entity_pos_t maxDist, entity_pos_t x0, entity_pos_t z0);
|
||||
void ImprovePathWaypoints(WaypointPath& path, pass_class_t passClass, entity_pos_t maxDist, entity_pos_t x0, entity_pos_t z0) const;
|
||||
|
||||
/**
|
||||
* Generate a passability map, stored in the 16th bit of navcells, based on passClass,
|
||||
|
|
@ -299,7 +301,11 @@ private:
|
|||
void GenerateSpecialMap(pass_class_t passClass, std::vector<CircularRegion> excludedRegions);
|
||||
|
||||
bool m_UseJPSCache;
|
||||
std::map<pass_class_t, shared_ptr<JumpPointCache> > m_JumpPointCache;
|
||||
// Mutable may be used here as caching does not change the external const-ness of the Long Range pathfinder.
|
||||
// This is thread-safe as it is order independent (no change in the output of the function for a given set of params).
|
||||
// Obviously, this means that the cache should actually be a cache and not return different results
|
||||
// from what would happen if things hadn't been cached.
|
||||
mutable std::map<pass_class_t, shared_ptr<JumpPointCache> > m_JumpPointCache;
|
||||
|
||||
HierarchicalPathfinder m_PathfinderHier;
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue