From 6896842618d8de042bc0336453ae2d2a728f2625 Mon Sep 17 00:00:00 2001 From: wrenge Date: Mon, 11 Nov 2024 14:19:43 +0300 Subject: [PATCH] Replaced arrays with spans in query. Replaced array allocation with buffer rent in query. comment --- src/DotRecast.Core/Buffers/RcRentedArray.cs | 6 ++++++ src/DotRecast.Detour/DtCallbackPolyQuery.cs | 2 +- src/DotRecast.Detour/DtCollectPolysQuery.cs | 2 +- src/DotRecast.Detour/DtFindNearestPolyQuery.cs | 2 +- src/DotRecast.Detour/DtNavMeshQuery.cs | 16 ++++++++-------- src/DotRecast.Detour/DtPathUtils.cs | 10 +++++----- src/DotRecast.Detour/IDtPolyQuery.cs | 2 +- 7 files changed, 23 insertions(+), 17 deletions(-) diff --git a/src/DotRecast.Core/Buffers/RcRentedArray.cs b/src/DotRecast.Core/Buffers/RcRentedArray.cs index 957fcf78..5ffdbb73 100644 --- a/src/DotRecast.Core/Buffers/RcRentedArray.cs +++ b/src/DotRecast.Core/Buffers/RcRentedArray.cs @@ -67,6 +67,12 @@ public ref T this[int index] } } + [Obsolete("This method is risky, and we are considering alternative approaches.")] + public T[] AsArray() + { + return _items; + } + public Span AsSpan() { if (_disposed) diff --git a/src/DotRecast.Detour/DtCallbackPolyQuery.cs b/src/DotRecast.Detour/DtCallbackPolyQuery.cs index 045da0b6..d5325ad9 100644 --- a/src/DotRecast.Detour/DtCallbackPolyQuery.cs +++ b/src/DotRecast.Detour/DtCallbackPolyQuery.cs @@ -11,7 +11,7 @@ public DtCallbackPolyQuery(Action callback) _callback = callback; } - public void Process(DtMeshTile tile, DtPoly[] poly, Span refs, int count) + public void Process(DtMeshTile tile, Span poly, Span refs, int count) { for (int i = 0; i < count; ++i) { diff --git a/src/DotRecast.Detour/DtCollectPolysQuery.cs b/src/DotRecast.Detour/DtCollectPolysQuery.cs index e98daa74..29710d4f 100644 --- a/src/DotRecast.Detour/DtCollectPolysQuery.cs +++ b/src/DotRecast.Detour/DtCollectPolysQuery.cs @@ -26,7 +26,7 @@ public bool Overflowed() return m_overflow; } - public void Process(DtMeshTile tile, DtPoly[] poly, Span refs, int count) + public void Process(DtMeshTile tile, Span poly, Span refs, int count) { int numLeft = m_maxPolys - m_numCollected; int toCopy = count; diff --git a/src/DotRecast.Detour/DtFindNearestPolyQuery.cs b/src/DotRecast.Detour/DtFindNearestPolyQuery.cs index 597caf9b..56ac604f 100644 --- a/src/DotRecast.Detour/DtFindNearestPolyQuery.cs +++ b/src/DotRecast.Detour/DtFindNearestPolyQuery.cs @@ -23,7 +23,7 @@ public DtFindNearestPolyQuery(DtNavMeshQuery query, RcVec3f center) _overPoly = default; } - public void Process(DtMeshTile tile, DtPoly[] poly, Span refs, int count) + public void Process(DtMeshTile tile, Span poly, Span refs, int count) { for (int i = 0; i < count; ++i) { diff --git a/src/DotRecast.Detour/DtNavMeshQuery.cs b/src/DotRecast.Detour/DtNavMeshQuery.cs index 0ebaeb68..e459a3ae 100644 --- a/src/DotRecast.Detour/DtNavMeshQuery.cs +++ b/src/DotRecast.Detour/DtNavMeshQuery.cs @@ -267,9 +267,9 @@ public DtStatus FindRandomPointAroundCircle(long startRef, RcVec3f centerPos, fl float radiusSqr = maxRadius * maxRadius; float areaSum = 0.0f; - using RcRentedArray polyVertsBuffer = RcRentedArray.Rent(MAX_VERT_BUFFER_SIZE); - using RcRentedArray randomPolyVertsBuffer = RcRentedArray.Rent(MAX_VERT_BUFFER_SIZE); - using RcRentedArray constrainedVertsBuffer = RcRentedArray.Rent(MAX_VERT_BUFFER_SIZE); + using RcRentedArray polyVertsBuffer = RcRentedArray.Shared.Rent(MAX_VERT_BUFFER_SIZE); + using RcRentedArray randomPolyVertsBuffer = RcRentedArray.Shared.Rent(MAX_VERT_BUFFER_SIZE); + using RcRentedArray constrainedVertsBuffer = RcRentedArray.Shared.Rent(MAX_VERT_BUFFER_SIZE); DtPoly randomPoly = null; long randomPolyRef = 0; @@ -608,7 +608,7 @@ protected void QueryPolygonsInTile(DtMeshTile tile, RcVec3f qmin, RcVec3 { const int batchSize = 32; Span polyRefs = stackalloc long[batchSize]; - using RcRentedArray polysRent = RcRentedArray.Rent(batchSize); + using RcRentedArray polysRent = RcRentedArray.Shared.Rent(batchSize); Span polys = polysRent.AsSpan(); int n = 0; @@ -799,7 +799,7 @@ public DtStatus QueryPolygons(RcVec3f center, RcVec3f halfExtents, IDtQu m_nav.CalcTileLoc(bmax, out var maxx, out var maxy); const int MAX_NEIS = 32; - using RcRentedArray neisRent = RcRentedArray.Rent(MAX_NEIS); + using RcRentedArray neisRent = RcRentedArray.Shared.Rent(MAX_NEIS); Span neis = neisRent.AsSpan(); for (int y = miny; y <= maxy; ++y) @@ -891,7 +891,7 @@ public DtStatus FindPath(long startRef, long endRef, RcVec3f startPos, RcVec3f e float lastBestNodeCost = startNode.total; DtRaycastHit rayHit = new DtRaycastHit(); - using var pathRent = RcRentedArray.Rent(MAX_PATH_LENGTH); + using var pathRent = RcRentedArray.Shared.Rent(MAX_PATH_LENGTH); rayHit.path = pathRent.AsArray(); while (!m_openList.IsEmpty()) { @@ -1181,7 +1181,7 @@ public virtual DtStatus UpdateSlicedFindPath(int maxIter, out int doneIters) } var rayHit = new DtRaycastHit(); - using var pathRent = RcRentedArray.Rent(MAX_PATH_LENGTH); + using var pathRent = RcRentedArray.Shared.Rent(MAX_PATH_LENGTH); rayHit.path = pathRent.AsArray(); int iter = 0; @@ -2274,7 +2274,7 @@ public DtStatus Raycast(long startRef, RcVec3f startPos, RcVec3f endPos, out float t, out RcVec3f hitNormal, ref List path) { DtRaycastHit hit = new DtRaycastHit(); - using var pathRent = RcRentedArray.Rent(MAX_PATH_LENGTH); + using var pathRent = RcRentedArray.Shared.Rent(MAX_PATH_LENGTH); hit.path = pathRent.AsArray(); DtStatus status = Raycast(startRef, startPos, endPos, filter, 0, ref hit, 0); diff --git a/src/DotRecast.Detour/DtPathUtils.cs b/src/DotRecast.Detour/DtPathUtils.cs index 254b4392..616a1988 100644 --- a/src/DotRecast.Detour/DtPathUtils.cs +++ b/src/DotRecast.Detour/DtPathUtils.cs @@ -186,12 +186,12 @@ public static int MergeCorridorStartMoved(List path, int npath, int maxPat var endIndex = nvisited - 1; var length1 = endIndex - furthestVisited; var length2 = npath - furthestPath; - using var result = RcRentedArray.Rent(length1 + length2); + using var result = RcRentedArray.Shared.Rent(length1 + length2); // Adjust beginning of the buffer to include the visited. // Store visited - for (int i = 0; i < length1; ++i) + for (int i = 0; i < length1; ++i) result[i] = visited[endIndex - i]; - + path.CopyTo(furthestPath, result.AsArray(), length1, length2); path.Clear(); @@ -233,7 +233,7 @@ public static int MergeCorridorEndMoved(List path, int npath, int maxPath, // Concatenate paths. var length1 = furthestPath; var length2 = nvisited - furthestVisited; - using var result = RcRentedArray.Rent(length1 + length2); + using var result = RcRentedArray.Shared.Rent(length1 + length2); path.CopyTo(0, result.AsArray(), 0, length1); visited.Slice(furthestVisited, nvisited - furthestVisited).CopyTo(result.AsSpan().Slice(length1, length2)); @@ -278,7 +278,7 @@ public static int MergeCorridorStartShortcut(List path, int npath, int max // Adjust beginning of the buffer to include the visited. var length1 = furthestVisited; var length2 = npath - furthestPath; - using var result = RcRentedArray.Rent(length1 + length2); + using var result = RcRentedArray.Shared.Rent(length1 + length2); visited.CopyTo(0, result.AsArray(), 0, length1); path.CopyTo(furthestPath, result.AsArray(), length1, length2); diff --git a/src/DotRecast.Detour/IDtPolyQuery.cs b/src/DotRecast.Detour/IDtPolyQuery.cs index 890d171b..5a6db49f 100644 --- a/src/DotRecast.Detour/IDtPolyQuery.cs +++ b/src/DotRecast.Detour/IDtPolyQuery.cs @@ -9,6 +9,6 @@ public interface IDtPolyQuery { /// Called for each batch of unique polygons touched by the search area in dtNavMeshQuery::queryPolygons. /// This can be called multiple times for a single query. - void Process(DtMeshTile tile, DtPoly[] poly, Span refs, int count); + void Process(DtMeshTile tile, Span poly, Span refs, int count); } } \ No newline at end of file