added DtNodePool.GetNode, FindNode, FindNodes tests

This commit is contained in:
ikpil 2024-02-02 00:29:24 +09:00
parent cc9adf7f53
commit bf83597c1e
4 changed files with 95 additions and 31 deletions

View File

@ -7,8 +7,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## [Unreleased] - yyyy-mm-dd ## [Unreleased] - yyyy-mm-dd
### Added ### Added
- Added DtNodePool.GetNode, FindNode, FindNodes tests
### Fixed ### Fixed
- Fixed SOH issue in dtNavMeshQuery.Raycast
- Fixed SOH issue in DtProximityGrid.QueryItems
### Changed ### Changed

View File

@ -3400,15 +3400,18 @@ namespace DotRecast.Detour
return m_nav; return m_nav;
} }
/** /// Gets a path from the explored nodes in the previous search.
* Gets a path from the explored nodes in the previous search. /// @param[in] endRef The reference id of the end polygon.
* /// @param[out] path An ordered list of polygon references representing the path. (Start to end.)
* @param endRef /// [(polyRef) * @p pathCount]
* The reference id of the end polygon. /// @param[out] pathCount The number of polygons returned in the @p path array.
* @returns An ordered list of polygon references representing the path. (Start to end.) /// @param[in] maxPath The maximum number of polygons the @p path array can hold. [Limit: >= 0]
* @remarks The result of this function depends on the state of the query object. For that reason it should only be /// @returns The status flags. Returns DT_FAILURE | DT_INVALID_PARAM if any parameter is wrong, or if
* used immediately after one of the two Dijkstra searches, findPolysAroundCircle or findPolysAroundShape. /// @p endRef was not explored in the previous search. Returns DT_SUCCESS | DT_BUFFER_TOO_SMALL
*/ /// if @p path cannot contain the entire path. In this case it is filled to capacity with a partial path.
/// Otherwise returns DT_SUCCESS.
/// @remarks The result of this function depends on the state of the query object. For that reason it should only
/// be used immediately after one of the two Dijkstra searches, findPolysAroundCircle or findPolysAroundShape.
public DtStatus GetPathFromDijkstraSearch(long endRef, ref List<long> path) public DtStatus GetPathFromDijkstraSearch(long endRef, ref List<long> path)
{ {
if (!m_nav.IsValidPolyRef(endRef) || null == path) if (!m_nav.IsValidPolyRef(endRef) || null == path)
@ -3418,18 +3421,14 @@ namespace DotRecast.Detour
path.Clear(); path.Clear();
List<DtNode> nodes = m_nodePool.FindNodes(endRef); if (m_nodePool.FindNodes(endRef, out var endNodes) != 1
if (nodes.Count != 1) || (endNodes[0].flags & DtNodeFlags.DT_NODE_CLOSED) == 0)
{
return DtStatus.DT_FAILURE | DtStatus.DT_INVALID_PARAM;
}
DtNode endNode = nodes[0];
if ((endNode.flags & DtNodeFlags.DT_NODE_CLOSED) == 0)
{ {
return DtStatus.DT_FAILURE | DtStatus.DT_INVALID_PARAM; return DtStatus.DT_FAILURE | DtStatus.DT_INVALID_PARAM;
} }
DtNode endNode = endNodes[0];
return GetPathToNode(endNode, ref path); return GetPathToNode(endNode, ref path);
} }
@ -3462,10 +3461,11 @@ namespace DotRecast.Detour
return DtStatus.DT_SUCCESS; return DtStatus.DT_SUCCESS;
} }
/** /// @par
* The closed list is the list of polygons that were fully evaluated during the last navigation graph search. (A* or ///
* Dijkstra) /// The closed list is the list of polygons that were fully evaluated during
*/ /// the last navigation graph search. (A* or Dijkstra)
///
public bool IsInClosedList(long refs) public bool IsInClosedList(long refs)
{ {
if (m_nodePool == null) if (m_nodePool == null)
@ -3473,9 +3473,10 @@ namespace DotRecast.Detour
return false; return false;
} }
foreach (DtNode n in m_nodePool.FindNodes(refs)) int n = m_nodePool.FindNodes(refs, out var nodes);
for (int i = 0; i < n; ++i)
{ {
if ((n.flags & DtNodeFlags.DT_NODE_CLOSED) != 0) if ((nodes[i].flags & DtNodeFlags.DT_NODE_CLOSED) != 0)
{ {
return true; return true;
} }

View File

@ -37,22 +37,20 @@ namespace DotRecast.Detour
m_map.Clear(); m_map.Clear();
} }
public List<DtNode> FindNodes(long id) public int FindNodes(long id, out List<DtNode> nodes)
{ {
var hasNode = m_map.TryGetValue(id, out var nodes); var hasNode = m_map.TryGetValue(id, out nodes);
; if (hasNode)
if (nodes == null)
{ {
nodes = new List<DtNode>(); return nodes.Count;
} }
return nodes; return 0;
} }
public DtNode FindNode(long id) public DtNode FindNode(long id)
{ {
var hasNode = m_map.TryGetValue(id, out var nodes); var hasNode = m_map.TryGetValue(id, out var nodes);
;
if (nodes != null && 0 != nodes.Count) if (nodes != null && 0 != nodes.Count)
{ {
return nodes[0]; return nodes[0];

View File

@ -0,0 +1,62 @@
using System.Collections.Immutable;
using NUnit.Framework;
namespace DotRecast.Detour.Test;
public class DtNodePoolTest
{
[Test]
public void TestGetNode()
{
var pool = new DtNodePool();
var node1St = pool.GetNode(0);
var node2St = pool.GetNode(0);
Assert.That(node1St, Is.SameAs(node2St));
node1St.state = 1;
var node3St = pool.GetNode(0);
Assert.That(node1St, Is.Not.SameAs(node3St));
}
[Test]
public void TestFindNode()
{
var pool = new DtNodePool();
var counts = ImmutableArray.Create(2, 3, 5);
// get and create
for (int i = 0; i < counts.Length; ++i)
{
var count = counts[i];
for (int ii = 0; ii < count; ++ii)
{
var node = pool.GetNode(i);
node.state = ii + 1;
}
}
// check count
for (int i = 0; i < counts.Length; ++i)
{
var count = counts[i];
var n = pool.FindNodes(i, out var nodes);
Assert.That(n, Is.EqualTo(count));
Assert.That(nodes, Has.Count.EqualTo(count));
var node = pool.FindNode(i);
Assert.That(nodes[0], Is.SameAs(node));
var node2 = pool.FindNode(i);
Assert.That(nodes[0], Is.SameAs(node2));
}
// check other count
{
var n = pool.FindNodes(4, out var nodes);
Assert.That(n, Is.EqualTo(0));
Assert.That(nodes, Is.Null);
}
}
}