Skip to content

Commit a478eda

Browse files
committed
perf(pathfinder): Extend putOnSortedOpenList() with conditional reverse insertion sorting
1 parent beca73c commit a478eda

2 files changed

Lines changed: 65 additions & 1 deletion

File tree

Core/GameEngine/Include/GameLogic/AIPathfind.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,9 @@ class PathfindCell
337337
// Forward insertion sort, in ascending cost order
338338
void forwardInsertionSort(PathfindCellList& list);
339339

340+
// Reverse insertion sort, in ascending cost order
341+
void reverseInsertionSort(PathfindCellList& list);
342+
340343
/// put self on "open" list in ascending cost order
341344
void putOnSortedOpenList( PathfindCellList &list );
342345

Core/GameEngine/Source/GameLogic/AI/AIPathfind.cpp

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1773,6 +1773,7 @@ void PathfindCell::forwardInsertionSort(PathfindCellList& list)
17731773
m_info->m_prevOpen = nullptr;
17741774
m_info->m_nextOpen = nullptr;
17751775
list.m_head = this;
1776+
list.m_tail = this;
17761777
return;
17771778
}
17781779

@@ -1796,10 +1797,60 @@ void PathfindCell::forwardInsertionSort(PathfindCellList& list)
17961797
if (current->m_info->m_nextOpen != nullptr) {
17971798
current->m_info->m_nextOpen->m_prevOpen = this->m_info;
17981799
}
1800+
else {
1801+
list.m_tail = this;
1802+
}
1803+
17991804
current->m_info->m_nextOpen = this->m_info;
18001805
m_info->m_prevOpen = current->m_info;
18011806
}
18021807

1808+
// Reverse insertion sort, returns early if the list is being initialised or we are appending the list
1809+
void PathfindCell::reverseInsertionSort(PathfindCellList& list)
1810+
{
1811+
DEBUG_ASSERTCRASH(m_info, ("Has to have info."));
1812+
DEBUG_ASSERTCRASH(m_info->m_closed == FALSE && m_info->m_open == FALSE, ("Serious error - Invalid flags. jba"));
1813+
1814+
// mark the new cell as being on the open list
1815+
m_info->m_open = true;
1816+
m_info->m_closed = false;
1817+
1818+
if (list.m_tail == nullptr) {
1819+
m_info->m_prevOpen = nullptr;
1820+
m_info->m_nextOpen = nullptr;
1821+
list.m_tail = this;
1822+
list.m_head = this;
1823+
return;
1824+
}
1825+
1826+
// If the node needs inserting after the current list tail
1827+
if (m_info->m_totalCost >= list.m_tail->m_info->m_totalCost) {
1828+
m_info->m_prevOpen = list.m_tail->m_info;
1829+
list.m_tail->m_info->m_nextOpen = this->m_info;
1830+
m_info->m_nextOpen = nullptr;
1831+
list.m_tail = this;
1832+
return;
1833+
}
1834+
1835+
// Traverse the list to find correct position
1836+
PathfindCell* current = list.m_tail;
1837+
while (current->m_info->m_prevOpen && current->m_info->m_prevOpen->m_totalCost > m_info->m_totalCost) {
1838+
current = current->getPrevOpen();
1839+
}
1840+
1841+
// Insert the new node in the correct position
1842+
m_info->m_prevOpen = current->m_info->m_prevOpen;
1843+
if (current->m_info->m_prevOpen != nullptr) {
1844+
current->m_info->m_prevOpen->m_nextOpen = this->m_info;
1845+
}
1846+
else {
1847+
list.m_head = this;
1848+
}
1849+
1850+
current->m_info->m_prevOpen = this->m_info;
1851+
m_info->m_nextOpen = current->m_info;
1852+
}
1853+
18031854
/// put self on "open" list in ascending cost order, return new list
18041855
void PathfindCell::putOnSortedOpenList( PathfindCellList &list )
18051856
{
@@ -1810,7 +1861,12 @@ void PathfindCell::putOnSortedOpenList( PathfindCellList &list )
18101861
}
18111862
#endif
18121863

1813-
forwardInsertionSort(list);
1864+
if (list.canReverseSort(*this)) {
1865+
reverseInsertionSort(list);
1866+
}
1867+
else {
1868+
forwardInsertionSort(list);
1869+
}
18141870
}
18151871

18161872
/// remove self from "open" list
@@ -1820,6 +1876,9 @@ void PathfindCell::removeFromOpenList( PathfindCellList &list )
18201876
DEBUG_ASSERTCRASH(m_info->m_closed==FALSE && m_info->m_open==TRUE, ("Serious error - Invalid flags. jba"));
18211877
if (m_info->m_nextOpen)
18221878
m_info->m_nextOpen->m_prevOpen = m_info->m_prevOpen;
1879+
else {
1880+
list.m_tail = getPrevOpen();
1881+
}
18231882

18241883
if (m_info->m_prevOpen)
18251884
m_info->m_prevOpen->m_nextOpen = m_info->m_nextOpen;
@@ -1858,6 +1917,7 @@ Int PathfindCell::releaseOpenList( PathfindCellList &list )
18581917
list.m_head = curInfo->m_nextOpen->m_cell;
18591918
} else {
18601919
list.m_head = nullptr;
1920+
list.m_tail = nullptr;
18611921
}
18621922
DEBUG_ASSERTCRASH(cur == curInfo->m_cell, ("Bad backpointer in PathfindCellInfo"));
18631923
curInfo->m_nextOpen = nullptr;
@@ -1893,6 +1953,7 @@ Int PathfindCell::releaseClosedList( PathfindCellList &list )
18931953
list.m_head = curInfo->m_nextOpen->m_cell;
18941954
} else {
18951955
list.m_head = nullptr;
1956+
list.m_tail = nullptr;
18961957
}
18971958
DEBUG_ASSERTCRASH(cur == curInfo->m_cell, ("Bad backpointer in PathfindCellInfo"));
18981959
curInfo->m_nextOpen = nullptr;

0 commit comments

Comments
 (0)