//#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
}
}
}