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
### Added
- Added DtNodePool.GetNode, FindNode, FindNodes tests
### Fixed
- Fixed SOH issue in dtNavMeshQuery.Raycast
- Fixed SOH issue in DtProximityGrid.QueryItems
### Changed

View File

@ -3400,15 +3400,18 @@ namespace DotRecast.Detour
return m_nav;
}
/**
* Gets a path from the explored nodes in the previous search.
*
* @param endRef
* The reference id of the end polygon.
* @returns An ordered list of polygon references representing the path. (Start to end.)
* @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.
*/
/// 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.)
/// [(polyRef) * @p pathCount]
/// @param[out] pathCount The number of polygons returned in the @p path array.
/// @param[in] maxPath The maximum number of polygons the @p path array can hold. [Limit: >= 0]
/// @returns The status flags. Returns DT_FAILURE | DT_INVALID_PARAM if any parameter is wrong, or if
/// @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)
{
if (!m_nav.IsValidPolyRef(endRef) || null == path)
@ -3418,18 +3421,14 @@ namespace DotRecast.Detour
path.Clear();
List<DtNode> nodes = m_nodePool.FindNodes(endRef);
if (nodes.Count != 1)
{
return DtStatus.DT_FAILURE | DtStatus.DT_INVALID_PARAM;
}
DtNode endNode = nodes[0];
if ((endNode.flags & DtNodeFlags.DT_NODE_CLOSED) == 0)
if (m_nodePool.FindNodes(endRef, out var endNodes) != 1
|| (endNodes[0].flags & DtNodeFlags.DT_NODE_CLOSED) == 0)
{
return DtStatus.DT_FAILURE | DtStatus.DT_INVALID_PARAM;
}
DtNode endNode = endNodes[0];
return GetPathToNode(endNode, ref path);
}
@ -3462,10 +3461,11 @@ namespace DotRecast.Detour
return DtStatus.DT_SUCCESS;
}
/**
* The closed list is the list of polygons that were fully evaluated during the last navigation graph search. (A* or
* Dijkstra)
*/
/// @par
///
/// 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)
{
if (m_nodePool == null)
@ -3473,9 +3473,10 @@ namespace DotRecast.Detour
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;
}

View File

@ -37,22 +37,20 @@ namespace DotRecast.Detour
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);
;
if (nodes == null)
var hasNode = m_map.TryGetValue(id, out nodes);
if (hasNode)
{
nodes = new List<DtNode>();
return nodes.Count;
}
return nodes;
return 0;
}
public DtNode FindNode(long id)
{
var hasNode = m_map.TryGetValue(id, out var nodes);
;
if (nodes != null && 0 != nodes.Count)
{
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);
}
}
}