3template <
typename PathStateType>
10template <
typename PathStateType>
14 out_pPathState =
nullptr;
15 plUInt32 iBestInQueue = 0;
17 for (plUInt32 i = 0; i < m_StateQueue.GetCount(); ++i)
19 const plInt64 iNodeIndex = m_StateQueue[i];
21 PathStateType* pState = &m_PathStates[iNodeIndex];
23 if (pState->m_fEstimatedCostToTarget < fLowestEstimation)
25 fLowestEstimation = pState->m_fEstimatedCostToTarget;
26 out_pPathState = pState;
31 PL_ASSERT_DEV(out_pPathState !=
nullptr,
"Implementation Error");
33 const plInt64 iBestNodeIndex = m_StateQueue[iBestInQueue];
34 m_StateQueue.RemoveAtAndSwap(iBestInQueue);
36 return iBestNodeIndex;
39template <
typename PathStateType>
46 const PathStateType* pCurState = &m_PathStates[iEndNodeIndex];
49 r.m_iNodeIndex = iEndNodeIndex;
50 r.m_pPathState = pCurState;
54 if (iEndNodeIndex == pCurState->m_iReachedThroughNode)
57 iEndNodeIndex = pCurState->m_iReachedThroughNode;
61template <
typename PathStateType>
64 PL_ASSERT_DEV(NewState.m_fCostToNode > m_CurState.m_fCostToNode,
65 "The costs must grow from one node to the next.\nStart Node Costs: {0}\nAdjacent Node Costs: {1}",
plArgF(m_CurState.m_fCostToNode, 2),
66 plArgF(NewState.m_fCostToNode, 2));
70 PL_ASSERT_DEV(NewState.m_fEstimatedCostToTarget >= NewState.m_fCostToNode,
"Unrealistic expectations will get you nowhere.");
72 PathStateType* pExistingState;
74 if (m_PathStates.TryGetValue(iNodeIndex, pExistingState))
77 if (pExistingState->m_fCostToNode <= NewState.m_fCostToNode)
81 *pExistingState = NewState;
82 pExistingState->m_iReachedThroughNode = m_iCurNodeIndex;
87 pExistingState = &m_PathStates[iNodeIndex];
89 *pExistingState = NewState;
90 pExistingState->m_iReachedThroughNode = m_iCurNodeIndex;
93 m_StateQueue.PushBack(iNodeIndex);
96template <
typename PathStateType>
100 PL_ASSERT_DEV(m_pStateGenerator !=
nullptr,
"No Path State Generator is set.");
104 if (iStartNodeIndex == iTargetNodeIndex)
106 m_PathStates.Reserve(1);
108 m_PathStates[iTargetNodeIndex] = StartState;
120 m_PathStates.Reserve(10000);
122 PathStateType& FirstState = m_PathStates[iStartNodeIndex];
124 m_pStateGenerator->StartSearch(iStartNodeIndex, &FirstState, iTargetNodeIndex);
127 FirstState = StartState;
128 FirstState.m_iReachedThroughNode = iStartNodeIndex;
131 m_StateQueue.PushBack(iStartNodeIndex);
134 while (!m_StateQueue.IsEmpty())
136 PathStateType* pCurState;
137 m_iCurNodeIndex = FindBestNodeToExpand(pCurState);
140 if (m_iCurNodeIndex == iTargetNodeIndex)
142 FillOutPathResult(m_iCurNodeIndex, out_Path);
143 m_pStateGenerator->SearchFinished(PL_SUCCESS);
150 if (pCurState->m_fCostToNode >= fMaxPathCost)
152 m_pStateGenerator->SearchFinished(PL_FAILURE);
156 m_CurState = *pCurState;
159 m_pStateGenerator->GenerateAdjacentStates(m_iCurNodeIndex, m_CurState,
this);
162 m_pStateGenerator->SearchFinished(PL_FAILURE);
167template <
typename PathStateType>
171 PL_ASSERT_DEV(m_pStateGenerator !=
nullptr,
"No Path State Generator is set.");
175 m_PathStates.Reserve(10000);
177 PathStateType& FirstState = m_PathStates[iStartNodeIndex];
179 m_pStateGenerator->StartSearchForClosest(iStartNodeIndex, &FirstState);
182 FirstState = StartState;
183 FirstState.m_iReachedThroughNode = iStartNodeIndex;
186 m_StateQueue.PushBack(iStartNodeIndex);
189 while (!m_StateQueue.IsEmpty())
191 PathStateType* pCurState;
192 m_iCurNodeIndex = FindBestNodeToExpand(pCurState);
195 if (Callback(m_iCurNodeIndex, *pCurState))
197 FillOutPathResult(m_iCurNodeIndex, out_Path);
198 m_pStateGenerator->SearchFinished(PL_SUCCESS);
205 if (pCurState->m_fCostToNode >= fMaxPathCost)
207 m_pStateGenerator->SearchFinished(PL_FAILURE);
211 m_CurState = *pCurState;
214 m_pStateGenerator->GenerateAdjacentStates(m_iCurNodeIndex, m_CurState,
this);
217 m_pStateGenerator->SearchFinished(PL_FAILURE);
void Clear()
Destructs all elements and sets the count to zero. Does not deallocate any data.
Definition Deque_inl.h:130
void PushFront(const T &element)
Adds one element to the front of the deque.
Definition Deque_inl.h:542
void PushBack()
Adds one default constructed element to the back of the deque.
Definition Deque_inl.h:489
Implements a directed breadth-first search through a graph (A*).
Definition GraphSearch.h:16
plResult FindPath(plInt64 iStartNodeIndex, const PathStateType &StartState, plInt64 iTargetNodeIndex, plDeque< PathResultData > &out_Path, float fMaxPathCost=plMath::Infinity< float >())
Searches for a path that starts at the graph node iStartNodeIndex with the start state StartState and...
Definition GraphSearch_inl.h:97
void AddPathNode(plInt64 iNodeIndex, const PathStateType &NewState)
Needs to be called by the used plPathStateGenerator to add nodes to evaluate.
Definition GraphSearch_inl.h:62
bool(*)(plInt64 iStartNodeIndex, const PathStateType &StartState) IsSearchedObjectCallback
Used by FindClosest() to query whether the currently visited node fulfills the termination criteria.
Definition GraphSearch.h:19
plResult FindClosest(plInt64 iStartNodeIndex, const PathStateType &StartState, IsSearchedObjectCallback Callback, plDeque< PathResultData > &out_Path, float fMaxPathCost=plMath::Infinity< float >())
Searches for a path that starts at the graph node iStartNodeIndex with the start state StartState and...
Definition GraphSearch_inl.h:168
constexpr TYPE Infinity()
Returns the value for Infinity as the template type. Returns zero, if the type does not support Infin...
Definition Constants_inl.h:110
Definition FormatStringArgs.h:48
FindPath() and FindClosest() return an array of these objects as the path result.
Definition GraphSearch.h:23
plInt64 m_iNodeIndex
The index of the node that was visited.
Definition GraphSearch.h:27
const PathStateType * m_pPathState
Pointer to the path state that was active at that step along the path.
Definition GraphSearch.h:30
Default enum for returning failure or success, instead of using a bool.
Definition Types.h:54