From 8722a9920c1f6119bf6e769cba270e63097f8e25 Mon Sep 17 00:00:00 2001
From: chai <215380520@qq.com>
Date: Thu, 23 May 2024 10:08:29 +0800
Subject: + astar project
---
.../Core/Pooling/ArrayPool.cs | 200 +++++++++++++++++++
.../Core/Pooling/ArrayPool.cs.meta | 12 ++
.../Core/Pooling/ListPool.cs | 211 +++++++++++++++++++++
.../Core/Pooling/ListPool.cs.meta | 7 +
.../Core/Pooling/ObjectPool.cs | 131 +++++++++++++
.../Core/Pooling/ObjectPool.cs.meta | 7 +
.../Core/Pooling/PathPool.cs | 88 +++++++++
.../Core/Pooling/PathPool.cs.meta | 7 +
.../Core/Pooling/StackPool.cs | 98 ++++++++++
.../Core/Pooling/StackPool.cs.meta | 7 +
10 files changed, 768 insertions(+)
create mode 100644 Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Core/Pooling/ArrayPool.cs
create mode 100644 Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Core/Pooling/ArrayPool.cs.meta
create mode 100644 Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Core/Pooling/ListPool.cs
create mode 100644 Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Core/Pooling/ListPool.cs.meta
create mode 100644 Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Core/Pooling/ObjectPool.cs
create mode 100644 Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Core/Pooling/ObjectPool.cs.meta
create mode 100644 Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Core/Pooling/PathPool.cs
create mode 100644 Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Core/Pooling/PathPool.cs.meta
create mode 100644 Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Core/Pooling/StackPool.cs
create mode 100644 Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Core/Pooling/StackPool.cs.meta
(limited to 'Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Core/Pooling')
diff --git a/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Core/Pooling/ArrayPool.cs b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Core/Pooling/ArrayPool.cs
new file mode 100644
index 0000000..f7b6300
--- /dev/null
+++ b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Core/Pooling/ArrayPool.cs
@@ -0,0 +1,200 @@
+#if !UNITY_EDITOR
+// Extra optimizations when not running in the editor, but less error checking
+#define ASTAR_OPTIMIZE_POOLING
+#endif
+
+using System;
+using System.Collections.Generic;
+
+namespace Pathfinding.Util {
+ ///
+ /// Lightweight Array Pool.
+ /// Handy class for pooling arrays of type T.
+ ///
+ /// Usage:
+ /// - Claim a new array using SomeClass[] foo = ArrayPool.Claim (capacity);
+ /// - Use it and do stuff with it
+ /// - Release it with ArrayPool.Release (ref foo);
+ ///
+ /// Warning: Arrays returned from the Claim method may contain arbitrary data.
+ /// You cannot rely on it being zeroed out.
+ ///
+ /// After you have released a array, you should never use it again, if you do use it
+ /// your code may modify it at the same time as some other code is using it which
+ /// will likely lead to bad results.
+ ///
+ /// Since: Version 3.8.6
+ /// See: Pathfinding.Util.ListPool
+ ///
+ public static class ArrayPool {
+#if !ASTAR_NO_POOLING
+ ///
+ /// Maximum length of an array pooled using ClaimWithExactLength.
+ /// Arrays with lengths longer than this will silently not be pooled.
+ ///
+ const int MaximumExactArrayLength = 256;
+
+ ///
+ /// Internal pool.
+ /// The arrays in each bucket have lengths of 2^i
+ ///
+ static readonly Stack[] pool = new Stack[31];
+ static readonly Stack[] exactPool = new Stack[MaximumExactArrayLength+1];
+#if !ASTAR_OPTIMIZE_POOLING
+ static readonly HashSet inPool = new HashSet();
+#endif
+#endif
+
+ ///
+ /// Returns an array with at least the specified length.
+ /// Warning: Returned arrays may contain arbitrary data.
+ /// You cannot rely on it being zeroed out.
+ ///
+ /// The returned array will always be a power of two, or zero.
+ ///
+ public static T[] Claim (int minimumLength) {
+ if (minimumLength <= 0) {
+ return ClaimWithExactLength(0);
+ }
+
+ int bucketIndex = 0;
+ while ((1 << bucketIndex) < minimumLength && bucketIndex < 30) {
+ bucketIndex++;
+ }
+
+ if (bucketIndex == 30)
+ throw new System.ArgumentException("Too high minimum length");
+
+#if !ASTAR_NO_POOLING
+ lock (pool) {
+ if (pool[bucketIndex] == null) {
+ pool[bucketIndex] = new Stack();
+ }
+
+ if (pool[bucketIndex].Count > 0) {
+ var array = pool[bucketIndex].Pop();
+#if !ASTAR_OPTIMIZE_POOLING
+ inPool.Remove(array);
+#endif
+ return array;
+ }
+ }
+#endif
+ return new T[1 << bucketIndex];
+ }
+
+ ///
+ /// Returns an array with the specified length.
+ /// Use with caution as pooling too many arrays with different lengths that
+ /// are rarely being reused will lead to an effective memory leak.
+ ///
+ /// Use if you just need an array that is at least as large as some value.
+ ///
+ /// Warning: Returned arrays may contain arbitrary data.
+ /// You cannot rely on it being zeroed out.
+ ///
+ public static T[] ClaimWithExactLength (int length) {
+#if !ASTAR_NO_POOLING
+ bool isPowerOfTwo = length != 0 && (length & (length - 1)) == 0;
+ if (isPowerOfTwo) {
+ // Will return the correct array length
+ return Claim(length);
+ }
+
+ if (length <= MaximumExactArrayLength) {
+ lock (pool) {
+ Stack stack = exactPool[length];
+ if (stack != null && stack.Count > 0) {
+ var array = stack.Pop();
+#if !ASTAR_OPTIMIZE_POOLING
+ inPool.Remove(array);
+#endif
+ return array;
+ }
+ }
+ }
+#endif
+ return new T[length];
+ }
+
+ ///
+ /// Pool an array.
+ /// If the array was got using the method then the allowNonPowerOfTwo parameter must be set to true.
+ /// The parameter exists to make sure that non power of two arrays are not pooled unintentionally which could lead to memory leaks.
+ ///
+ public static void Release (ref T[] array, bool allowNonPowerOfTwo = false) {
+ if (array == null) return;
+ if (array.GetType() != typeof(T[])) {
+ throw new System.ArgumentException("Expected array type " + typeof(T[]).Name + " but found " + array.GetType().Name + "\nAre you using the correct generic class?\n");
+ }
+
+#if !ASTAR_NO_POOLING
+ bool isPowerOfTwo = array.Length != 0 && (array.Length & (array.Length - 1)) == 0;
+ if (!isPowerOfTwo && !allowNonPowerOfTwo && array.Length != 0) throw new System.ArgumentException("Length is not a power of 2");
+
+ lock (pool) {
+#if !ASTAR_OPTIMIZE_POOLING
+ if (!inPool.Add(array)) {
+ throw new InvalidOperationException("You are trying to pool an array twice. Please make sure that you only pool it once.");
+ }
+#endif
+ if (isPowerOfTwo) {
+ int bucketIndex = 0;
+ while ((1 << bucketIndex) < array.Length && bucketIndex < 30) {
+ bucketIndex++;
+ }
+
+ if (pool[bucketIndex] == null) {
+ pool[bucketIndex] = new Stack();
+ }
+
+ pool[bucketIndex].Push(array);
+ } else if (array.Length <= MaximumExactArrayLength) {
+ Stack stack = exactPool[array.Length];
+ if (stack == null) stack = exactPool[array.Length] = new Stack();
+ stack.Push(array);
+ }
+ }
+#endif
+ array = null;
+ }
+ }
+
+ /// Extension methods for List
+ public static class ListExtensions {
+ ///
+ /// Identical to ToArray but it uses ArrayPool to avoid allocations if possible.
+ ///
+ /// Use with caution as pooling too many arrays with different lengths that
+ /// are rarely being reused will lead to an effective memory leak.
+ ///
+ public static T[] ToArrayFromPool(this List list) {
+ var arr = ArrayPool.ClaimWithExactLength(list.Count);
+
+ for (int i = 0; i < arr.Length; i++) {
+ arr[i] = list[i];
+ }
+ return arr;
+ }
+
+ ///
+ /// Clear a list faster than List.Clear.
+ /// It turns out that the List.Clear method will clear all elements in the underlaying array
+ /// not just the ones up to Count. If the list only has a few elements, but the capacity
+ /// is huge, this can cause performance problems. Using the RemoveRange method to remove
+ /// all elements in the list does not have this problem, however it is implemented in a
+ /// stupid way, so it will clear the elements twice (completely unnecessarily) so it will
+ /// only be faster than using the Clear method if the number of elements in the list is
+ /// less than half of the capacity of the list.
+ ///
+ /// Hopefully this method can be removed when Unity upgrades to a newer version of Mono.
+ ///
+ public static void ClearFast(this List list) {
+ if (list.Count*2 < list.Capacity) {
+ list.RemoveRange(0, list.Count);
+ } else {
+ list.Clear();
+ }
+ }
+ }
+}
diff --git a/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Core/Pooling/ArrayPool.cs.meta b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Core/Pooling/ArrayPool.cs.meta
new file mode 100644
index 0000000..25e0d39
--- /dev/null
+++ b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Core/Pooling/ArrayPool.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 787a564bf2d894ee09284b775074864c
+timeCreated: 1470483941
+licenseType: Store
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Core/Pooling/ListPool.cs b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Core/Pooling/ListPool.cs
new file mode 100644
index 0000000..22ff246
--- /dev/null
+++ b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Core/Pooling/ListPool.cs
@@ -0,0 +1,211 @@
+#if !UNITY_EDITOR
+// Extra optimizations when not running in the editor, but less error checking
+#define ASTAR_OPTIMIZE_POOLING
+#endif
+
+using System;
+using System.Collections.Generic;
+
+namespace Pathfinding.Util {
+ ///
+ /// Lightweight List Pool.
+ /// Handy class for pooling lists of type T.
+ ///
+ /// Usage:
+ /// - Claim a new list using List foo = ListPool.Claim ();
+ /// - Use it and do stuff with it
+ /// - Release it with ListPool.Release (foo);
+ ///
+ /// You do not need to clear the list before releasing it.
+ /// After you have released a list, you should never use it again, if you do use it, you will
+ /// mess things up quite badly in the worst case.
+ ///
+ /// Since: Version 3.2
+ /// See: Pathfinding.Util.StackPool
+ ///
+ public static class ListPool {
+ /// Internal pool
+ static readonly List > pool = new List >();
+
+#if !ASTAR_NO_POOLING
+ static readonly List > largePool = new List >();
+ static readonly HashSet > inPool = new HashSet >();
+#endif
+
+ ///
+ /// When requesting a list with a specified capacity, search max this many lists in the pool before giving up.
+ /// Must be greater or equal to one.
+ ///
+ const int MaxCapacitySearchLength = 8;
+ const int LargeThreshold = 5000;
+ const int MaxLargePoolSize = 8;
+
+ ///
+ /// Claim a list.
+ /// Returns a pooled list if any are in the pool.
+ /// Otherwise it creates a new one.
+ /// After usage, this list should be released using the Release function (though not strictly necessary).
+ ///
+ public static List Claim () {
+#if ASTAR_NO_POOLING
+ return new List();
+#else
+ lock (pool) {
+ if (pool.Count > 0) {
+ List ls = pool[pool.Count-1];
+ pool.RemoveAt(pool.Count-1);
+ inPool.Remove(ls);
+ return ls;
+ }
+
+ return new List();
+ }
+#endif
+ }
+
+ static int FindCandidate (List > pool, int capacity) {
+ // Loop through the last MaxCapacitySearchLength items
+ // and check if any item has a capacity greater or equal to the one that
+ // is desired. If so return it.
+ // Otherwise take the largest one or if there are no lists in the pool
+ // then allocate a new one with the desired capacity
+ List list = null;
+ int listIndex = -1;
+
+ for (int i = 0; i < pool.Count && i < MaxCapacitySearchLength; i++) {
+ // ith last item
+ var candidate = pool[pool.Count-1-i];
+
+ // Find the largest list that is not too large (arbitrary decision to try to prevent some memory bloat if the list was not just a temporary list).
+ if ((list == null || candidate.Capacity > list.Capacity) && candidate.Capacity < capacity*16) {
+ list = candidate;
+ listIndex = pool.Count-1-i;
+
+ if (list.Capacity >= capacity) {
+ return listIndex;
+ }
+ }
+ }
+
+ return listIndex;
+ }
+
+ ///
+ /// Claim a list with minimum capacity
+ /// Returns a pooled list if any are in the pool.
+ /// Otherwise it creates a new one.
+ /// After usage, this list should be released using the Release function (though not strictly necessary).
+ /// A subset of the pool will be searched for a list with a high enough capacity and one will be returned
+ /// if possible, otherwise the list with the largest capacity found will be returned.
+ ///
+ public static List Claim (int capacity) {
+#if ASTAR_NO_POOLING
+ return new List(capacity);
+#else
+ lock (pool) {
+ var currentPool = pool;
+ var listIndex = FindCandidate(pool, capacity);
+
+ if (capacity > LargeThreshold) {
+ var largeListIndex = FindCandidate(largePool, capacity);
+ if (largeListIndex != -1) {
+ currentPool = largePool;
+ listIndex = largeListIndex;
+ }
+ }
+
+ if (listIndex == -1) {
+ return new List(capacity);
+ } else {
+ var list = currentPool[listIndex];
+ // Swap current item and last item to enable a more efficient removal
+ inPool.Remove(list);
+ currentPool[listIndex] = currentPool[currentPool.Count-1];
+ currentPool.RemoveAt(currentPool.Count-1);
+ return list;
+ }
+ }
+#endif
+ }
+
+ ///
+ /// Makes sure the pool contains at least count pooled items with capacity size.
+ /// This is good if you want to do all allocations at start.
+ ///
+ public static void Warmup (int count, int size) {
+ lock (pool) {
+ var tmp = new List[count];
+ for (int i = 0; i < count; i++) tmp[i] = Claim(size);
+ for (int i = 0; i < count; i++) Release(tmp[i]);
+ }
+ }
+
+
+ ///
+ /// Releases a list and sets the variable to null.
+ /// After the list has been released it should not be used anymore.
+ ///
+ /// Throws: System.InvalidOperationException
+ /// Releasing a list when it has already been released will cause an exception to be thrown.
+ ///
+ /// See:
+ ///
+ public static void Release (ref List list) {
+ Release(list);
+ list = null;
+ }
+
+ ///
+ /// Releases a list.
+ /// After the list has been released it should not be used anymore.
+ ///
+ /// Throws: System.InvalidOperationException
+ /// Releasing a list when it has already been released will cause an exception to be thrown.
+ ///
+ /// See:
+ ///
+ public static void Release (List list) {
+#if !ASTAR_NO_POOLING
+ list.ClearFast();
+
+ lock (pool) {
+#if !ASTAR_OPTIMIZE_POOLING
+ if (!inPool.Add(list)) {
+ throw new InvalidOperationException("You are trying to pool a list twice. Please make sure that you only pool it once.");
+ }
+#endif
+ if (list.Capacity > LargeThreshold) {
+ largePool.Add(list);
+
+ // Remove the list which was used the longest time ago from the pool if it
+ // exceeds the maximum size as it probably just contributes to memory bloat
+ if (largePool.Count > MaxLargePoolSize) {
+ largePool.RemoveAt(0);
+ }
+ } else {
+ pool.Add(list);
+ }
+ }
+#endif
+ }
+
+ ///
+ /// Clears the pool for lists of this type.
+ /// This is an O(n) operation, where n is the number of pooled lists.
+ ///
+ public static void Clear () {
+ lock (pool) {
+#if !ASTAR_OPTIMIZE_POOLING && !ASTAR_NO_POOLING
+ inPool.Clear();
+#endif
+ pool.Clear();
+ }
+ }
+
+ /// Number of lists of this type in the pool
+ public static int GetSize () {
+ // No lock required since int writes are atomic
+ return pool.Count;
+ }
+ }
+}
diff --git a/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Core/Pooling/ListPool.cs.meta b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Core/Pooling/ListPool.cs.meta
new file mode 100644
index 0000000..92e0b9c
--- /dev/null
+++ b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Core/Pooling/ListPool.cs.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 2b76b7593907b44d9a6ef1b186fee0a7
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
diff --git a/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Core/Pooling/ObjectPool.cs b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Core/Pooling/ObjectPool.cs
new file mode 100644
index 0000000..262830c
--- /dev/null
+++ b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Core/Pooling/ObjectPool.cs
@@ -0,0 +1,131 @@
+#if !UNITY_EDITOR
+// Extra optimizations when not running in the editor, but less error checking
+#define ASTAR_OPTIMIZE_POOLING
+#endif
+
+using System;
+using System.Collections.Generic;
+
+namespace Pathfinding.Util {
+ public interface IAstarPooledObject {
+ void OnEnterPool();
+ }
+
+ ///
+ /// Lightweight object Pool for IAstarPooledObject.
+ /// Handy class for pooling objects of type T which implements the IAstarPooledObject interface.
+ ///
+ /// Usage:
+ /// - Claim a new object using SomeClass foo = ObjectPool.Claim ();
+ /// - Use it and do stuff with it
+ /// - Release it with ObjectPool.Release (foo);
+ ///
+ /// After you have released a object, you should never use it again.
+ ///
+ /// Since: Version 3.2
+ /// Version: Since 3.7.6 this class is thread safe
+ /// See: Pathfinding.Util.ListPool
+ /// See: ObjectPoolSimple
+ ///
+ public static class ObjectPool where T : class, IAstarPooledObject, new(){
+ public static T Claim () {
+ return ObjectPoolSimple.Claim();
+ }
+
+ public static void Release (ref T obj) {
+ obj.OnEnterPool();
+ ObjectPoolSimple.Release(ref obj);
+ }
+ }
+
+ ///
+ /// Lightweight object Pool.
+ /// Handy class for pooling objects of type T.
+ ///
+ /// Usage:
+ /// - Claim a new object using SomeClass foo = ObjectPool.Claim ();
+ /// - Use it and do stuff with it
+ /// - Release it with ObjectPool.Release (foo);
+ ///
+ /// After you have released a object, you should never use it again.
+ ///
+ /// Since: Version 3.2
+ /// Version: Since 3.7.6 this class is thread safe
+ /// See: Pathfinding.Util.ListPool
+ /// See: ObjectPool
+ ///
+ public static class ObjectPoolSimple where T : class, new(){
+ /// Internal pool
+ static List pool = new List();
+
+#if !ASTAR_NO_POOLING
+ static readonly HashSet inPool = new HashSet();
+#endif
+
+ ///
+ /// Claim a object.
+ /// Returns a pooled object if any are in the pool.
+ /// Otherwise it creates a new one.
+ /// After usage, this object should be released using the Release function (though not strictly necessary).
+ ///
+ public static T Claim () {
+#if ASTAR_NO_POOLING
+ return new T();
+#else
+ lock (pool) {
+ if (pool.Count > 0) {
+ T ls = pool[pool.Count-1];
+ pool.RemoveAt(pool.Count-1);
+ inPool.Remove(ls);
+ return ls;
+ } else {
+ return new T();
+ }
+ }
+#endif
+ }
+
+ ///
+ /// Releases an object.
+ /// After the object has been released it should not be used anymore.
+ /// The variable will be set to null to prevent silly mistakes.
+ ///
+ /// Throws: System.InvalidOperationException
+ /// Releasing an object when it has already been released will cause an exception to be thrown.
+ /// However enabling ASTAR_OPTIMIZE_POOLING will prevent this check.
+ ///
+ /// See: Claim
+ ///
+ public static void Release (ref T obj) {
+#if !ASTAR_NO_POOLING
+ lock (pool) {
+#if !ASTAR_OPTIMIZE_POOLING
+ if (!inPool.Add(obj)) {
+ throw new InvalidOperationException("You are trying to pool an object twice. Please make sure that you only pool it once.");
+ }
+#endif
+ pool.Add(obj);
+ }
+#endif
+ obj = null;
+ }
+
+ ///
+ /// Clears the pool for objects of this type.
+ /// This is an O(n) operation, where n is the number of pooled objects.
+ ///
+ public static void Clear () {
+ lock (pool) {
+#if !ASTAR_OPTIMIZE_POOLING && !ASTAR_NO_POOLING
+ inPool.Clear();
+#endif
+ pool.Clear();
+ }
+ }
+
+ /// Number of objects of this type in the pool
+ public static int GetSize () {
+ return pool.Count;
+ }
+ }
+}
diff --git a/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Core/Pooling/ObjectPool.cs.meta b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Core/Pooling/ObjectPool.cs.meta
new file mode 100644
index 0000000..6240b52
--- /dev/null
+++ b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Core/Pooling/ObjectPool.cs.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 10837c5b030bd47a2a0e6e213fea0868
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
diff --git a/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Core/Pooling/PathPool.cs b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Core/Pooling/PathPool.cs
new file mode 100644
index 0000000..9fa75d1
--- /dev/null
+++ b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Core/Pooling/PathPool.cs
@@ -0,0 +1,88 @@
+//#define ASTAR_NO_POOLING // Disable pooling for some reason. Maybe for debugging or just for measuring the difference.
+using System;
+using System.Collections.Generic;
+
+namespace Pathfinding {
+ /// Pools path objects to reduce load on the garbage collector
+ public static class PathPool {
+ static readonly Dictionary > pool = new Dictionary >();
+ static readonly Dictionary totalCreated = new Dictionary();
+
+ ///
+ /// Adds a path to the pool.
+ /// This function should not be used directly. Instead use the Path.Claim and Path.Release functions.
+ ///
+ public static void Pool (Path path) {
+#if !ASTAR_NO_POOLING
+ lock (pool) {
+ if (((IPathInternals)path).Pooled) {
+ throw new System.ArgumentException("The path is already pooled.");
+ }
+
+ Stack poolStack;
+ if (!pool.TryGetValue(path.GetType(), out poolStack)) {
+ poolStack = new Stack();
+ pool[path.GetType()] = poolStack;
+ }
+
+ ((IPathInternals)path).Pooled = true;
+ ((IPathInternals)path).OnEnterPool();
+ poolStack.Push(path);
+ }
+#endif
+ }
+
+ /// Total created instances of paths of the specified type
+ public static int GetTotalCreated (Type type) {
+ int created;
+
+ if (totalCreated.TryGetValue(type, out created)) {
+ return created;
+ } else {
+ return 0;
+ }
+ }
+
+ /// Number of pooled instances of a path of the specified type
+ public static int GetSize (Type type) {
+ Stack poolStack;
+
+ if (pool.TryGetValue(type, out poolStack)) {
+ return poolStack.Count;
+ } else {
+ return 0;
+ }
+ }
+
+ /// Get a path from the pool or create a new one if the pool is empty
+ public static T GetPath() where T : Path, new() {
+#if ASTAR_NO_POOLING
+ T result = new T();
+ ((IPathInternals)result).Reset();
+ return result;
+#else
+ lock (pool) {
+ T result;
+ Stack poolStack;
+ if (pool.TryGetValue(typeof(T), out poolStack) && poolStack.Count > 0) {
+ // Guaranteed to have the correct type
+ result = poolStack.Pop() as T;
+ } else {
+ result = new T();
+
+ // Make sure an entry for the path type exists
+ if (!totalCreated.ContainsKey(typeof(T))) {
+ totalCreated[typeof(T)] = 0;
+ }
+
+ totalCreated[typeof(T)]++;
+ }
+
+ ((IPathInternals)result).Pooled = false;
+ ((IPathInternals)result).Reset();
+ return result;
+ }
+#endif
+ }
+ }
+}
diff --git a/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Core/Pooling/PathPool.cs.meta b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Core/Pooling/PathPool.cs.meta
new file mode 100644
index 0000000..9ff4458
--- /dev/null
+++ b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Core/Pooling/PathPool.cs.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: cefe1014ab62848a89016fb97b1f8f7b
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
diff --git a/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Core/Pooling/StackPool.cs b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Core/Pooling/StackPool.cs
new file mode 100644
index 0000000..daf7a53
--- /dev/null
+++ b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Core/Pooling/StackPool.cs
@@ -0,0 +1,98 @@
+//#define ASTAR_NO_POOLING //@SHOWINEDITOR Disable pooling for some reason. Could be debugging or just for measuring the difference.
+
+using System.Collections.Generic;
+
+namespace Pathfinding.Util {
+ ///
+ /// Lightweight Stack Pool.
+ /// Handy class for pooling stacks of type T.
+ ///
+ /// Usage:
+ /// - Claim a new stack using Stack foo = StackPool.Claim ();
+ /// - Use it and do stuff with it
+ /// - Release it with StackPool.Release (foo);
+ ///
+ /// You do not need to clear the stack before releasing it.
+ /// After you have released a stack, you should never use it again.
+ ///
+ /// Warning: This class is not thread safe
+ ///
+ /// Since: Version 3.2
+ /// See: Pathfinding.Util.ListPool
+ ///
+ public static class StackPool {
+ /// Internal pool
+ static readonly List > pool;
+
+ /// Static constructor
+ static StackPool () {
+ pool = new List >();
+ }
+
+ ///
+ /// Claim a stack.
+ /// Returns a pooled stack if any are in the pool.
+ /// Otherwise it creates a new one.
+ /// After usage, this stack should be released using the Release function (though not strictly necessary).
+ ///
+ public static Stack Claim () {
+#if ASTAR_NO_POOLING
+ return new Stack();
+#else
+ lock (pool) {
+ if (pool.Count > 0) {
+ Stack ls = pool[pool.Count-1];
+ pool.RemoveAt(pool.Count-1);
+ return ls;
+ }
+ }
+
+ return new Stack();
+#endif
+ }
+
+ ///
+ /// Makes sure the pool contains at least count pooled items.
+ /// This is good if you want to do all allocations at start.
+ ///
+ public static void Warmup (int count) {
+ var tmp = new Stack[count];
+
+ for (int i = 0; i < count; i++) tmp[i] = Claim();
+ for (int i = 0; i < count; i++) Release(tmp[i]);
+ }
+
+ ///
+ /// Releases a stack.
+ /// After the stack has been released it should not be used anymore.
+ /// Releasing a stack twice will cause an error.
+ ///
+ public static void Release (Stack stack) {
+#if !ASTAR_NO_POOLING
+ stack.Clear();
+
+ lock (pool) {
+ for (int i = 0; i < pool.Count; i++)
+ if (pool[i] == stack) UnityEngine.Debug.LogError("The Stack is released even though it is inside the pool");
+
+ pool.Add(stack);
+ }
+#endif
+ }
+
+ ///
+ /// Clears all pooled stacks of this type.
+ /// This is an O(n) operation, where n is the number of pooled stacks
+ ///
+ public static void Clear () {
+ lock (pool) {
+ pool.Clear();
+ }
+ }
+
+ /// Number of stacks of this type in the pool
+ public static int GetSize () {
+ return pool.Count;
+ }
+ }
+}
diff --git a/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Core/Pooling/StackPool.cs.meta b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Core/Pooling/StackPool.cs.meta
new file mode 100644
index 0000000..1c8a3b5
--- /dev/null
+++ b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Core/Pooling/StackPool.cs.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: de467bbbb1ff84668ae8262caad00941
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
--
cgit v1.1-26-g67d0