using System; using System.Collections.Concurrent; using System.Collections.Generic; using SlatedGameToolkit.Framework.Exceptions; namespace SlatedGameToolkit.Framework.Utilities.Collections.Pooling { public class ObjectPool where Poolable : IPoolable { public int Size { get; private set; } public int Count { get { return pool.Count; } } private Func creator; private ConcurrentBag pool; public ObjectPool(Func creator, int size = 0, int initialCount = 0) { this.creator = creator ?? throw new ArgumentNullException("creator"); this.pool = new ConcurrentBag(); this.Size = size; CreateAmount(initialCount); } public void CreateAmount(int amount) { if (Size >= 0 && Count + amount >= Size) throw new FrameworkUsageException(string.Format("Object pool surpassed set size of {0}", Size)); for (int i = 0; i < amount; i++) { pool.Add(creator()); } } public Poolable Retrieve() { if (pool.Count == 0) { CreateAmount(1); } Poolable result; pool.TryTake(out result); return result; } public void Release(Poolable poolable) { if (Size >= 0 && Count + 1 >= Size) throw new FrameworkUsageException(string.Format("Object pool surpassed set size of {0}", Size)); poolable.Reset(); pool.Add(poolable); } } }