From 1104e2276e3c6aeb90b74016c5c0c46f4a938dc3 Mon Sep 17 00:00:00 2001 From: ikpil Date: Sat, 5 Aug 2023 10:27:10 +0900 Subject: [PATCH] add RcImmutableArray for unity3d --- src/DotRecast.Core/DotRecast.Core.csproj | 1 - .../RcImmutableArray.Enumerable.cs | 83 +++++++++++++++++++ .../RcImmutableArray.Listable.cs | 69 +++++++++++++++ .../RcImmutableArray.Minimal.cs | 19 +++++ src/DotRecast.Core/RcImmutableArray.cs | 48 +++++++++++ src/DotRecast.Detour.Dynamic/DynamicTile.cs | 12 ++- src/DotRecast.Detour/DtNavMeshQuery.cs | 4 +- src/DotRecast.Recast.Demo/Draw/DrawMode.cs | 3 +- .../Builder/SampleAreaModifications.cs | 4 +- .../Builder/SoloNavMeshBuilder.cs | 4 +- .../Geom/DemoInputGeomProvider.cs | 3 +- .../Tools/CrowdToolMode.cs | 4 +- .../Tools/DynamicUpdateToolMode.cs | 4 +- .../Tools/TestNavmeshToolMode.cs | 4 +- .../Tools/TileToolImpl.cs | 4 +- .../Geom/SimpleInputGeomProvider.cs | 3 +- .../Geom/SingleTrimeshInputGeomProvider.cs | 5 +- 17 files changed, 246 insertions(+), 28 deletions(-) create mode 100644 src/DotRecast.Core/RcImmutableArray.Enumerable.cs create mode 100644 src/DotRecast.Core/RcImmutableArray.Listable.cs create mode 100644 src/DotRecast.Core/RcImmutableArray.Minimal.cs create mode 100644 src/DotRecast.Core/RcImmutableArray.cs diff --git a/src/DotRecast.Core/DotRecast.Core.csproj b/src/DotRecast.Core/DotRecast.Core.csproj index 149d35d..eff52c8 100644 --- a/src/DotRecast.Core/DotRecast.Core.csproj +++ b/src/DotRecast.Core/DotRecast.Core.csproj @@ -5,7 +5,6 @@ - diff --git a/src/DotRecast.Core/RcImmutableArray.Enumerable.cs b/src/DotRecast.Core/RcImmutableArray.Enumerable.cs new file mode 100644 index 0000000..e3b4769 --- /dev/null +++ b/src/DotRecast.Core/RcImmutableArray.Enumerable.cs @@ -0,0 +1,83 @@ +using System; +using System.Collections; +using System.Collections.Generic; + +namespace DotRecast.Core +{ + public readonly partial struct RcImmutableArray + { + public IEnumerator GetEnumerator() + { + return EnumeratorObject.Create(_array); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return EnumeratorObject.Create(_array); + } + + private sealed class EnumeratorObject : IEnumerator + { + private static readonly IEnumerator EmptyEnumerator = Create(Empty._array!); + private readonly T[] _array; + private int _index; + + internal static IEnumerator Create(T[] array) + { + if (array.Length != 0) + { + return new EnumeratorObject(array); + } + else + { + return EmptyEnumerator; + } + } + + + private EnumeratorObject(T[] array) + { + _index = -1; + _array = array; + } + + public T Current + { + get + { + if (unchecked((uint)_index) < (uint)_array.Length) + { + return _array[_index]; + } + + throw new InvalidOperationException(); + } + } + + object IEnumerator.Current => this.Current; + + public void Dispose() + { + } + + public bool MoveNext() + { + int newIndex = _index + 1; + int length = _array.Length; + + if ((uint)newIndex <= (uint)length) + { + _index = newIndex; + return (uint)newIndex < (uint)length; + } + + return false; + } + + void IEnumerator.Reset() + { + _index = -1; + } + } + } +} \ No newline at end of file diff --git a/src/DotRecast.Core/RcImmutableArray.Listable.cs b/src/DotRecast.Core/RcImmutableArray.Listable.cs new file mode 100644 index 0000000..b485193 --- /dev/null +++ b/src/DotRecast.Core/RcImmutableArray.Listable.cs @@ -0,0 +1,69 @@ +using System; +using System.Collections.Generic; + +namespace DotRecast.Core +{ + public readonly partial struct RcImmutableArray : IList + { + public int Count => Length; + public bool IsReadOnly => true; + + T IList.this[int index] + { + get + { + var self = this; + return self[index]; + } + set => throw new NotSupportedException(); + } + + + public int IndexOf(T item) + { + for (int i = 0; i < Count; ++i) + { + if (_array![i].Equals(item)) + return i; + } + + return -1; + } + + public bool Contains(T item) + { + return IndexOf(item) >= 0; + } + + public void CopyTo(T[] array, int arrayIndex) + { + var self = this; + Array.Copy(self._array!, 0, array, arrayIndex, self.Length); + } + + public void Add(T item) + { + throw new NotSupportedException(); + } + + public void Clear() + { + throw new NotSupportedException(); + } + + public bool Remove(T item) + { + throw new NotSupportedException(); + } + + public void Insert(int index, T item) + { + throw new NotSupportedException(); + } + + public void RemoveAt(int index) + { + throw new NotSupportedException(); + } + } +} \ No newline at end of file diff --git a/src/DotRecast.Core/RcImmutableArray.Minimal.cs b/src/DotRecast.Core/RcImmutableArray.Minimal.cs new file mode 100644 index 0000000..4306936 --- /dev/null +++ b/src/DotRecast.Core/RcImmutableArray.Minimal.cs @@ -0,0 +1,19 @@ +namespace DotRecast.Core +{ + public readonly partial struct RcImmutableArray + { +#pragma warning disable CA1825 + public static readonly RcImmutableArray Empty = new RcImmutableArray(new T[0]); +#pragma warning restore CA1825 + + private readonly T[] _array; + + internal RcImmutableArray(T[] items) + { + _array = items; + } + + public T this[int index] => _array![index]; + public int Length => _array!.Length; + } +} \ No newline at end of file diff --git a/src/DotRecast.Core/RcImmutableArray.cs b/src/DotRecast.Core/RcImmutableArray.cs new file mode 100644 index 0000000..f6c1bc6 --- /dev/null +++ b/src/DotRecast.Core/RcImmutableArray.cs @@ -0,0 +1,48 @@ +using System; + +namespace DotRecast.Core +{ + public static class RcImmutableArray + { + public static RcImmutableArray Create() + { + return RcImmutableArray.Empty; + } + + public static RcImmutableArray Create(T item1) + { + T[] array = new[] { item1 }; + return new RcImmutableArray(array); + } + + public static RcImmutableArray Create(T item1, T item2) + { + T[] array = new[] { item1, item2 }; + return new RcImmutableArray(array); + } + + public static RcImmutableArray Create(T item1, T item2, T item3) + { + T[] array = new[] { item1, item2, item3 }; + return new RcImmutableArray(array); + } + + public static RcImmutableArray Create(T item1, T item2, T item3, T item4) + { + T[] array = new[] { item1, item2, item3, item4 }; + return new RcImmutableArray(array); + } + + public static RcImmutableArray Create(params T[] items) + { + if (items == null || items.Length == 0) + { + return RcImmutableArray.Empty; + } + + var tmp = new T[items.Length]; + Array.Copy(items, tmp, items.Length); + return new RcImmutableArray(tmp); + } + } +} \ No newline at end of file diff --git a/src/DotRecast.Detour.Dynamic/DynamicTile.cs b/src/DotRecast.Detour.Dynamic/DynamicTile.cs index 8ad460e..f315027 100644 --- a/src/DotRecast.Detour.Dynamic/DynamicTile.cs +++ b/src/DotRecast.Detour.Dynamic/DynamicTile.cs @@ -19,7 +19,7 @@ freely, subject to the following restrictions: using System; using System.Collections.Concurrent; using System.Collections.Generic; -using System.Collections.Immutable; +using System.Collections.ObjectModel; using System.Linq; using DotRecast.Core; using DotRecast.Detour.Dynamic.Colliders; @@ -60,8 +60,14 @@ namespace DotRecast.Detour.Dynamic private RcHeightfield BuildHeightfield(DynamicNavMeshConfig config, RcTelemetry telemetry) { - ICollection rasterizedColliders = checkpoint != null ? checkpoint.colliders : ImmutableHashSet.Empty; - RcHeightfield heightfield = checkpoint != null ? checkpoint.heightfield : voxelTile.Heightfield(); + ICollection rasterizedColliders = checkpoint != null + ? checkpoint.colliders as ICollection + : RcImmutableArray.Empty; + + RcHeightfield heightfield = checkpoint != null + ? checkpoint.heightfield + : voxelTile.Heightfield(); + foreach (var (cid, c) in colliders) { if (!rasterizedColliders.Contains(cid)) diff --git a/src/DotRecast.Detour/DtNavMeshQuery.cs b/src/DotRecast.Detour/DtNavMeshQuery.cs index 9f3f9d7..dc27feb 100644 --- a/src/DotRecast.Detour/DtNavMeshQuery.cs +++ b/src/DotRecast.Detour/DtNavMeshQuery.cs @@ -20,8 +20,6 @@ freely, subject to the following restrictions: using System; using System.Collections.Generic; -using System.Collections.Immutable; -using System.Numerics; using DotRecast.Core; namespace DotRecast.Detour @@ -725,7 +723,7 @@ namespace DotRecast.Detour { if (!RcVec3f.IsFinite(center) || !RcVec3f.IsFinite(halfExtents)) { - return ImmutableArray.Empty; + return RcImmutableArray.Empty; } RcVec3f bmin = center.Subtract(halfExtents); diff --git a/src/DotRecast.Recast.Demo/Draw/DrawMode.cs b/src/DotRecast.Recast.Demo/Draw/DrawMode.cs index c75a0a2..8e5aba5 100644 --- a/src/DotRecast.Recast.Demo/Draw/DrawMode.cs +++ b/src/DotRecast.Recast.Demo/Draw/DrawMode.cs @@ -19,6 +19,7 @@ freely, subject to the following restrictions: */ using System.Collections.Immutable; +using DotRecast.Core; namespace DotRecast.Recast.Demo.Draw; @@ -43,7 +44,7 @@ public class DrawMode public static readonly DrawMode DRAWMODE_POLYMESH = new(16, "Poly Mesh"); public static readonly DrawMode DRAWMODE_POLYMESH_DETAIL = new(17, "Poly Mesh Detils"); - public static readonly ImmutableArray Values = ImmutableArray.Create( + public static readonly RcImmutableArray Values = RcImmutableArray.Create( DRAWMODE_MESH, DRAWMODE_NAVMESH, DRAWMODE_NAVMESH_INVIS, diff --git a/src/DotRecast.Recast.Toolset/Builder/SampleAreaModifications.cs b/src/DotRecast.Recast.Toolset/Builder/SampleAreaModifications.cs index 6fa28d6..b754ee1 100644 --- a/src/DotRecast.Recast.Toolset/Builder/SampleAreaModifications.cs +++ b/src/DotRecast.Recast.Toolset/Builder/SampleAreaModifications.cs @@ -18,8 +18,8 @@ freely, subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ -using System.Collections.Immutable; using System.Linq; +using DotRecast.Core; namespace DotRecast.Recast.Toolset.Builder { @@ -49,7 +49,7 @@ namespace DotRecast.Recast.Toolset.Builder public static readonly RcAreaModification SAMPLE_AREAMOD_DOOR = new RcAreaModification(SAMPLE_POLYAREA_TYPE_DOOR); public static readonly RcAreaModification SAMPLE_AREAMOD_JUMP = new RcAreaModification(SAMPLE_POLYAREA_TYPE_JUMP); - public static readonly ImmutableArray Values = ImmutableArray.Create( + public static readonly RcImmutableArray Values = RcImmutableArray.Create( SAMPLE_AREAMOD_WALKABLE, SAMPLE_AREAMOD_GROUND, SAMPLE_AREAMOD_WATER, diff --git a/src/DotRecast.Recast.Toolset/Builder/SoloNavMeshBuilder.cs b/src/DotRecast.Recast.Toolset/Builder/SoloNavMeshBuilder.cs index 497491d..3295f3f 100644 --- a/src/DotRecast.Recast.Toolset/Builder/SoloNavMeshBuilder.cs +++ b/src/DotRecast.Recast.Toolset/Builder/SoloNavMeshBuilder.cs @@ -18,7 +18,7 @@ freely, subject to the following restrictions: using System; using System.Collections.Generic; -using System.Collections.Immutable; +using DotRecast.Core; using DotRecast.Detour; using DotRecast.Recast.Toolset.Geom; @@ -55,7 +55,7 @@ namespace DotRecast.Recast.Toolset.Builder } var navMesh = BuildNavMesh(meshData, vertsPerPoly); - return new NavMeshBuildResult(ImmutableArray.Create(rcResult), navMesh); + return new NavMeshBuildResult(RcImmutableArray.Create(rcResult), navMesh); } private DtNavMesh BuildNavMesh(DtMeshData meshData, int vertsPerPoly) diff --git a/src/DotRecast.Recast.Toolset/Geom/DemoInputGeomProvider.cs b/src/DotRecast.Recast.Toolset/Geom/DemoInputGeomProvider.cs index f6f440d..a25aae8 100644 --- a/src/DotRecast.Recast.Toolset/Geom/DemoInputGeomProvider.cs +++ b/src/DotRecast.Recast.Toolset/Geom/DemoInputGeomProvider.cs @@ -20,7 +20,6 @@ freely, subject to the following restrictions: using System; using System.Collections.Generic; -using System.Collections.Immutable; using DotRecast.Core; using DotRecast.Recast.Geom; @@ -107,7 +106,7 @@ namespace DotRecast.Recast.Toolset.Geom public IEnumerable Meshes() { - return ImmutableArray.Create(_mesh); + return RcImmutableArray.Create(_mesh); } public List GetOffMeshConnections() diff --git a/src/DotRecast.Recast.Toolset/Tools/CrowdToolMode.cs b/src/DotRecast.Recast.Toolset/Tools/CrowdToolMode.cs index ac5549a..f5bd0b8 100644 --- a/src/DotRecast.Recast.Toolset/Tools/CrowdToolMode.cs +++ b/src/DotRecast.Recast.Toolset/Tools/CrowdToolMode.cs @@ -1,4 +1,4 @@ -using System.Collections.Immutable; +using DotRecast.Core; namespace DotRecast.Recast.Toolset.Tools { @@ -10,7 +10,7 @@ namespace DotRecast.Recast.Toolset.Tools public static readonly CrowdToolMode TOGGLE_POLYS = new CrowdToolMode(3, "Toggle Polys"); public static readonly CrowdToolMode PROFILING = new CrowdToolMode(4, "Profiling"); - public static readonly ImmutableArray Values = ImmutableArray.Create( + public static readonly RcImmutableArray Values = RcImmutableArray.Create( CREATE, MOVE_TARGET, SELECT, diff --git a/src/DotRecast.Recast.Toolset/Tools/DynamicUpdateToolMode.cs b/src/DotRecast.Recast.Toolset/Tools/DynamicUpdateToolMode.cs index 2bccd99..95b0a92 100644 --- a/src/DotRecast.Recast.Toolset/Tools/DynamicUpdateToolMode.cs +++ b/src/DotRecast.Recast.Toolset/Tools/DynamicUpdateToolMode.cs @@ -1,4 +1,4 @@ -using System.Collections.Immutable; +using DotRecast.Core; namespace DotRecast.Recast.Toolset.Tools { @@ -8,7 +8,7 @@ namespace DotRecast.Recast.Toolset.Tools public static readonly DynamicUpdateToolMode COLLIDERS = new DynamicUpdateToolMode(1, "Colliders"); public static readonly DynamicUpdateToolMode RAYCAST = new DynamicUpdateToolMode(2, "Raycast"); - public static readonly ImmutableArray Values = ImmutableArray.Create( + public static readonly RcImmutableArray Values = RcImmutableArray.Create( BUILD, COLLIDERS, RAYCAST ); diff --git a/src/DotRecast.Recast.Toolset/Tools/TestNavmeshToolMode.cs b/src/DotRecast.Recast.Toolset/Tools/TestNavmeshToolMode.cs index cfe7dd8..57cc8eb 100644 --- a/src/DotRecast.Recast.Toolset/Tools/TestNavmeshToolMode.cs +++ b/src/DotRecast.Recast.Toolset/Tools/TestNavmeshToolMode.cs @@ -1,4 +1,4 @@ -using System.Collections.Immutable; +using DotRecast.Core; namespace DotRecast.Recast.Toolset.Tools { @@ -14,7 +14,7 @@ namespace DotRecast.Recast.Toolset.Tools public static readonly TestNavmeshToolMode FIND_LOCAL_NEIGHBOURHOOD = new TestNavmeshToolMode(7, "Find Local Neighbourhood"); public static readonly TestNavmeshToolMode RANDOM_POINTS_IN_CIRCLE = new TestNavmeshToolMode(8, "Random Points in Circle"); - public static readonly ImmutableArray Values = ImmutableArray.Create( + public static readonly RcImmutableArray Values = RcImmutableArray.Create( PATHFIND_FOLLOW, PATHFIND_STRAIGHT, PATHFIND_SLICED, diff --git a/src/DotRecast.Recast.Toolset/Tools/TileToolImpl.cs b/src/DotRecast.Recast.Toolset/Tools/TileToolImpl.cs index eb6e165..d28d613 100644 --- a/src/DotRecast.Recast.Toolset/Tools/TileToolImpl.cs +++ b/src/DotRecast.Recast.Toolset/Tools/TileToolImpl.cs @@ -1,5 +1,4 @@ using System.Linq; -using System.Collections.Immutable; using DotRecast.Core; using DotRecast.Recast.Toolset.Builder; @@ -130,8 +129,7 @@ namespace DotRecast.Recast.Toolset.Tools var tb = new TileNavMeshBuilder(); var meshData = tb.BuildMeshData(geom, - settings.cellSize, settings.cellHeight, settings.agentHeight, settings.agentRadius, settings.agentMaxClimb, - ImmutableArray.Create(result) + settings.cellSize, settings.cellHeight, settings.agentHeight, settings.agentRadius, settings.agentMaxClimb, RcImmutableArray.Create(result) ).FirstOrDefault(); if (null == meshData) diff --git a/src/DotRecast.Recast/Geom/SimpleInputGeomProvider.cs b/src/DotRecast.Recast/Geom/SimpleInputGeomProvider.cs index c2f06c2..0590827 100644 --- a/src/DotRecast.Recast/Geom/SimpleInputGeomProvider.cs +++ b/src/DotRecast.Recast/Geom/SimpleInputGeomProvider.cs @@ -20,7 +20,6 @@ freely, subject to the following restrictions: using System; using System.Collections.Generic; -using System.Collections.Immutable; using DotRecast.Core; namespace DotRecast.Recast.Geom @@ -108,7 +107,7 @@ namespace DotRecast.Recast.Geom public IEnumerable Meshes() { - return ImmutableArray.Create(_mesh); + return RcImmutableArray.Create(_mesh); } public void CalculateNormals() diff --git a/src/DotRecast.Recast/Geom/SingleTrimeshInputGeomProvider.cs b/src/DotRecast.Recast/Geom/SingleTrimeshInputGeomProvider.cs index b703aba..f5e3284 100644 --- a/src/DotRecast.Recast/Geom/SingleTrimeshInputGeomProvider.cs +++ b/src/DotRecast.Recast/Geom/SingleTrimeshInputGeomProvider.cs @@ -18,7 +18,6 @@ freely, subject to the following restrictions: using System; using System.Collections.Generic; -using System.Collections.Immutable; using DotRecast.Core; namespace DotRecast.Recast.Geom @@ -56,12 +55,12 @@ namespace DotRecast.Recast.Geom public IEnumerable Meshes() { - return ImmutableArray.Create(_mesh); + return RcImmutableArray.Create(_mesh); } public IList ConvexVolumes() { - return ImmutableArray.Empty; + return RcImmutableArray.Empty; } } } \ No newline at end of file