diff --git a/src/DotRecast.Core/Buffers/RcObjectPool.cs b/src/DotRecast.Core/Buffers/RcObjectPool.cs new file mode 100644 index 0000000..c37cf60 --- /dev/null +++ b/src/DotRecast.Core/Buffers/RcObjectPool.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; + +namespace DotRecast.Core.Buffers +{ + // This implementation is thread unsafe + public class RcObjectPool where T : class + { + private readonly Queue _items = new Queue(); + private readonly Func _createFunc; + + public RcObjectPool(Func createFunc) + { + _createFunc = createFunc; + } + + public T Get() + { + if (_items.TryDequeue(out var result)) + return result; + + return _createFunc(); + } + + public void Return(T obj) + { + _items.Enqueue(obj); + } + } +} \ No newline at end of file diff --git a/src/DotRecast.Detour/DtNodePool.cs b/src/DotRecast.Detour/DtNodePool.cs index c94b460..3929b3a 100644 --- a/src/DotRecast.Detour/DtNodePool.cs +++ b/src/DotRecast.Detour/DtNodePool.cs @@ -21,6 +21,7 @@ freely, subject to the following restrictions: using System; using System.Collections.Generic; using System.Linq; +using DotRecast.Core.Buffers; namespace DotRecast.Detour { @@ -31,10 +32,12 @@ namespace DotRecast.Detour private int m_usedNodesCount; private List m_buckets; private readonly int m_initialBufferCapacityBase; + private readonly RcObjectPool> m_listPool; public DtNodePool(int initialBufferCapacityBase = 6) // initial size 64 { m_map = new Dictionary>(); + m_listPool = new RcObjectPool>(() => new List()); m_buckets = new List(); m_initialBufferCapacityBase = initialBufferCapacityBase; } @@ -78,6 +81,9 @@ namespace DotRecast.Detour public void Clear() { + foreach (var pair in m_map) + m_listPool.Return(pair.Value); + m_map.Clear(); m_usedNodesCount = 0; } @@ -124,7 +130,8 @@ namespace DotRecast.Detour } else { - nodes = new List(); + nodes = m_listPool.Get(); + nodes.Clear(); m_map.Add(id, nodes); }