added DtNodeQueue unittest

This commit is contained in:
ikpil 2024-02-09 17:56:16 +09:00
parent 4320019b02
commit a65e5a3125
6 changed files with 117 additions and 17 deletions

View File

@ -9,12 +9,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Added ### Added
- Added DtNodeQueue UnitTest [@ikpil](https://github.com/ikpil) - Added DtNodeQueue UnitTest [@ikpil](https://github.com/ikpil)
- Added RcSortedQueue UnitTest [@ikpil](https://github.com/ikpil) - Added RcSortedQueue UnitTest [@ikpil](https://github.com/ikpil)
- Added IComparable interface to RcAtomicLong [@ikpil](https://github.com/ikpil)
### Fixed ### Fixed
### Changed ### Changed
- Update Microsoft.NET.Test.Sdk 17.8.0 to 17.9.0 - Update Microsoft.NET.Test.Sdk 17.8.0 to 17.9.0
- Enhanced ToString method of DtNode to provide more detailed information.
### Removed ### Removed
### Special Thanks ### Special Thanks

View File

@ -75,12 +75,18 @@ namespace DotRecast.Core.Collections
public void Enqueue(T item) public void Enqueue(T item)
{ {
if (null == item)
return;
_items.Add(item); _items.Add(item);
_dirty = true; _dirty = true;
} }
public bool Remove(T item) public bool Remove(T item)
{ {
if (null == item)
return false;
//int idx = _items.BinarySearch(item, _comparer); // don't use this! Because reference types can be reused externally. //int idx = _items.BinarySearch(item, _comparer); // don't use this! Because reference types can be reused externally.
int idx = _items.FindLastIndex(x => item.Equals(x)); int idx = _items.FindLastIndex(x => item.Equals(x));
if (0 > idx) if (0 > idx)

View File

@ -1,8 +1,9 @@
using System.Threading; using System;
using System.Threading;
namespace DotRecast.Core namespace DotRecast.Core
{ {
public class RcAtomicLong public class RcAtomicLong : IComparable<RcAtomicLong>
{ {
private long _location; private long _location;
@ -15,6 +16,11 @@ namespace DotRecast.Core
_location = location; _location = location;
} }
public int CompareTo(RcAtomicLong other)
{
return Read().CompareTo(other.Read());
}
public long IncrementAndGet() public long IncrementAndGet()
{ {
return Interlocked.Increment(ref _location); return Interlocked.Increment(ref _location);

View File

@ -40,10 +40,19 @@ namespace DotRecast.Detour
{ {
this.index = index; this.index = index;
} }
public static int ComparisonNodeTotal(DtNode a, DtNode b)
{
int compare = a.total.CompareTo(b.total);
if (0 != compare)
return compare;
return a.index.CompareTo(b.index);
}
public override string ToString() public override string ToString()
{ {
return "Node [id=" + id + "]"; return $"Node [index={index} id={id} cost={cost} total={total}]";
} }
} }
} }

View File

@ -28,7 +28,7 @@ namespace DotRecast.Detour
public DtNodeQueue() public DtNodeQueue()
{ {
m_heap = new RcSortedQueue<DtNode>((n1, n2) => n1.total.CompareTo(n2.total)); m_heap = new RcSortedQueue<DtNode>(DtNode.ComparisonNodeTotal);
} }
public int Count() public int Count()
@ -64,7 +64,7 @@ namespace DotRecast.Detour
public bool IsEmpty() public bool IsEmpty()
{ {
return 0 == m_heap.Count(); return m_heap.IsEmpty();
} }
} }
} }

View File

@ -1,5 +1,5 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using DotRecast.Core;
using DotRecast.Core.Collections; using DotRecast.Core.Collections;
using NUnit.Framework; using NUnit.Framework;
@ -7,15 +7,8 @@ namespace DotRecast.Detour.Test;
public class DtNodeQueueTest public class DtNodeQueueTest
{ {
[Test] private static List<DtNode> ShuffledNodes(int count)
public void TestDtNodeQueue()
{ {
var queue = new DtNodeQueue();
// check count
Assert.That(queue.Count(), Is.EqualTo(0));
const int count = 1000;
var nodes = new List<DtNode>(); var nodes = new List<DtNode>();
for (int i = 0; i < count; ++i) for (int i = 0; i < count; ++i)
{ {
@ -23,13 +16,97 @@ public class DtNodeQueueTest
node.total = i; node.total = i;
nodes.Add(node); nodes.Add(node);
} }
nodes.Shuffle();
foreach (var node in nodes) nodes.Shuffle();
return nodes;
}
[Test]
public void TestPushAndPop()
{
var queue = new DtNodeQueue();
// check count
Assert.That(queue.Count(), Is.EqualTo(0));
// null push
queue.Push(null);
Assert.That(queue.Count(), Is.EqualTo(0));
// test push
const int count = 1000;
var expectedNodes = ShuffledNodes(count);
foreach (var node in expectedNodes)
{ {
queue.Push(node); queue.Push(node);
} }
Assert.That(queue.Count(), Is.EqualTo(count)); Assert.That(queue.Count(), Is.EqualTo(count));
// test pop
expectedNodes.Sort(DtNode.ComparisonNodeTotal);
foreach (var node in expectedNodes)
{
Assert.That(queue.Peek(), Is.SameAs(node));
Assert.That(queue.Pop(), Is.SameAs(node));
}
Assert.That(queue.Count(), Is.EqualTo(0));
} }
[Test]
public void TestClear()
{
var queue = new DtNodeQueue();
const int count = 555;
var expectedNodes = ShuffledNodes(count);
foreach (var node in expectedNodes)
{
queue.Push(node);
}
Assert.That(queue.Count(), Is.EqualTo(count));
queue.Clear();
Assert.That(queue.Count(), Is.EqualTo(0));
Assert.That(queue.IsEmpty(), Is.True);
}
[Test]
public void TestModify()
{
var queue = new DtNodeQueue();
const int count = 5000;
var expectedNodes = ShuffledNodes(count);
foreach (var node in expectedNodes)
{
queue.Push(node);
}
// check modify
queue.Modify(null);
// change total
var r = new RcRand();
foreach (var node in expectedNodes)
{
node.total = r.NextInt32() % (count / 50); // duplication for test
}
// test modify
foreach (var node in expectedNodes)
{
queue.Modify(node);
}
// check
expectedNodes.Sort(DtNode.ComparisonNodeTotal);
foreach (var node in expectedNodes)
{
Assert.That(queue.Pop(), Is.SameAs(node));
}
}
} }