PathPool.cs 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. //#define ASTAR_NO_POOLING // Disable pooling for some reason. Maybe for debugging or just for measuring the difference.
  2. using System;
  3. using System.Collections.Generic;
  4. namespace Pathfinding {
  5. /// <summary>Pools path objects to reduce load on the garbage collector</summary>
  6. public static class PathPool {
  7. static readonly Dictionary<Type, Stack<Path> > pool = new Dictionary<Type, Stack<Path> >();
  8. static readonly Dictionary<Type, int> totalCreated = new Dictionary<Type, int>();
  9. /// <summary>
  10. /// Adds a path to the pool.
  11. /// This function should not be used directly. Instead use the Path.Claim and Path.Release functions.
  12. /// </summary>
  13. public static void Pool (Path path) {
  14. #if !ASTAR_NO_POOLING
  15. lock (pool) {
  16. if (((IPathInternals)path).Pooled) {
  17. throw new System.ArgumentException("The path is already pooled.");
  18. }
  19. Stack<Path> poolStack;
  20. if (!pool.TryGetValue(path.GetType(), out poolStack)) {
  21. poolStack = new Stack<Path>();
  22. pool[path.GetType()] = poolStack;
  23. }
  24. ((IPathInternals)path).Pooled = true;
  25. ((IPathInternals)path).OnEnterPool();
  26. poolStack.Push(path);
  27. }
  28. #endif
  29. }
  30. /// <summary>Total created instances of paths of the specified type</summary>
  31. public static int GetTotalCreated (Type type) {
  32. int created;
  33. if (totalCreated.TryGetValue(type, out created)) {
  34. return created;
  35. } else {
  36. return 0;
  37. }
  38. }
  39. /// <summary>Number of pooled instances of a path of the specified type</summary>
  40. public static int GetSize (Type type) {
  41. Stack<Path> poolStack;
  42. if (pool.TryGetValue(type, out poolStack)) {
  43. return poolStack.Count;
  44. } else {
  45. return 0;
  46. }
  47. }
  48. /// <summary>Get a path from the pool or create a new one if the pool is empty</summary>
  49. public static T GetPath<T>() where T : Path, new() {
  50. #if ASTAR_NO_POOLING
  51. T result = new T();
  52. ((IPathInternals)result).Reset();
  53. return result;
  54. #else
  55. lock (pool) {
  56. T result;
  57. Stack<Path> poolStack;
  58. if (pool.TryGetValue(typeof(T), out poolStack) && poolStack.Count > 0) {
  59. // Guaranteed to have the correct type
  60. result = poolStack.Pop() as T;
  61. } else {
  62. result = new T();
  63. // Make sure an entry for the path type exists
  64. if (!totalCreated.ContainsKey(typeof(T))) {
  65. totalCreated[typeof(T)] = 0;
  66. }
  67. totalCreated[typeof(T)]++;
  68. }
  69. ((IPathInternals)result).Pooled = false;
  70. ((IPathInternals)result).Reset();
  71. return result;
  72. }
  73. #endif
  74. }
  75. }
  76. }