using System.Collections.Generic; namespace Cryville.Common.Buffers { /// /// A set of resource pools categorized by a category type. /// /// The category type. /// The type of the objects in the pool. public abstract class CategorizedPool where TObject : class { /// /// The set of underlying pools. /// /// /// The and method select an underlying pool directly from this set with the category as the key. When overridden, this set must be available since construction. /// protected abstract IReadOnlyDictionary> Buckets { get; } /// /// The count of objects rented from the set of pools. /// public int RentedCount { get; private set; } /// /// Rents an object from the pool. /// /// The category. /// The rented object. public TObject Rent(TCategory category) { var obj = Buckets[category].Rent(); RentedCount++; return obj; } /// /// Returns a rented object to the pool. /// /// The category. /// The object to return. public void Return(TCategory category, TObject obj) { Buckets[category].Return(obj); --RentedCount; } } /// /// A utility to access a categorized pool, representing a single unit that uses a shared categorized pool. /// /// The category type. /// The type of the objects in the pool. public class CategorizedPoolAccessor where TObject : class { readonly CategorizedPool _pool; static readonly SimpleObjectPool> _dictPool = new SimpleObjectPool>(1024); Dictionary _rented; /// /// Creates an instance of the class. /// /// The categorized pool. public CategorizedPoolAccessor(CategorizedPool pool) { _pool = pool; } /// /// Rents an object from the pool. /// /// The category. /// The rented object. public TObject Rent(TCategory category) { var obj = _pool.Rent(category); if (_rented == null) _rented = _dictPool.Rent(); _rented.Add(obj, category); return obj; } /// /// Returns a rented object to the pool. /// /// The object to return. public void Return(TObject obj) { _pool.Return(_rented[obj], obj); _rented.Remove(obj); } /// /// Returns all objects rented by this accessor to the pool. /// public void ReturnAll() { if (_rented == null) return; foreach (var obj in _rented) { _pool.Return(obj.Value, obj.Key); } _rented.Clear(); _dictPool.Return(_rented); _rented = null; } } }