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;
}
}
}