StackPool.cs 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. //#define ASTAR_NO_POOLING //@SHOWINEDITOR Disable pooling for some reason. Could be debugging or just for measuring the difference.
  2. using System.Collections.Generic;
  3. namespace Pathfinding.Util {
  4. /// <summary>
  5. /// Lightweight Stack Pool.
  6. /// Handy class for pooling stacks of type T.
  7. ///
  8. /// Usage:
  9. /// - Claim a new stack using <code> Stack<SomeClass> foo = StackPool<SomeClass>.Claim (); </code>
  10. /// - Use it and do stuff with it
  11. /// - Release it with <code> StackPool<SomeClass>.Release (foo); </code>
  12. ///
  13. /// You do not need to clear the stack before releasing it.
  14. /// After you have released a stack, you should never use it again.
  15. ///
  16. /// Warning: This class is not thread safe
  17. ///
  18. /// Since: Version 3.2
  19. /// See: Pathfinding.Util.ListPool
  20. /// </summary>
  21. public static class StackPool<T> {
  22. /// <summary>Internal pool</summary>
  23. static readonly List<Stack<T> > pool;
  24. /// <summary>Static constructor</summary>
  25. static StackPool () {
  26. pool = new List<Stack<T> >();
  27. }
  28. /// <summary>
  29. /// Claim a stack.
  30. /// Returns a pooled stack if any are in the pool.
  31. /// Otherwise it creates a new one.
  32. /// After usage, this stack should be released using the Release function (though not strictly necessary).
  33. /// </summary>
  34. public static Stack<T> Claim () {
  35. #if ASTAR_NO_POOLING
  36. return new Stack<T>();
  37. #else
  38. lock (pool) {
  39. if (pool.Count > 0) {
  40. Stack<T> ls = pool[pool.Count-1];
  41. pool.RemoveAt(pool.Count-1);
  42. return ls;
  43. }
  44. }
  45. return new Stack<T>();
  46. #endif
  47. }
  48. /// <summary>
  49. /// Makes sure the pool contains at least count pooled items.
  50. /// This is good if you want to do all allocations at start.
  51. /// </summary>
  52. public static void Warmup (int count) {
  53. var tmp = new Stack<T>[count];
  54. for (int i = 0; i < count; i++) tmp[i] = Claim();
  55. for (int i = 0; i < count; i++) Release(tmp[i]);
  56. }
  57. /// <summary>
  58. /// Releases a stack.
  59. /// After the stack has been released it should not be used anymore.
  60. /// Releasing a stack twice will cause an error.
  61. /// </summary>
  62. public static void Release (Stack<T> stack) {
  63. #if !ASTAR_NO_POOLING
  64. stack.Clear();
  65. lock (pool) {
  66. for (int i = 0; i < pool.Count; i++)
  67. if (pool[i] == stack) UnityEngine.Debug.LogError("The Stack is released even though it is inside the pool");
  68. pool.Add(stack);
  69. }
  70. #endif
  71. }
  72. /// <summary>
  73. /// Clears all pooled stacks of this type.
  74. /// This is an O(n) operation, where n is the number of pooled stacks
  75. /// </summary>
  76. public static void Clear () {
  77. lock (pool) {
  78. pool.Clear();
  79. }
  80. }
  81. /// <summary>Number of stacks of this type in the pool</summary>
  82. public static int GetSize () {
  83. return pool.Count;
  84. }
  85. }
  86. }