using System;
using System.Collections.Generic;
namespace Coffee.UIParticleInternal
{
///
/// Object pool.
///
internal class ObjectPool
{
private readonly Func _onCreate; // Delegate for creating instances
private readonly Action _onReturn; // Delegate for returning instances to the pool
private readonly Predicate _onValid; // Delegate for checking if instances are valid
private readonly Stack _pool = new Stack(32); // Object pool
private int _count; // Total count of created instances
public ObjectPool(Func onCreate, Predicate onValid, Action onReturn)
{
_onCreate = onCreate;
_onValid = onValid;
_onReturn = onReturn;
}
///
/// Rent an instance from the pool.
/// When you no longer need it, return it with .
///
public T Rent()
{
while (0 < _pool.Count)
{
var instance = _pool.Pop();
if (_onValid(instance))
{
return instance;
}
}
// If there are no instances in the pool, create a new one.
Logging.Log(this, $"A new instance is created (pooled: {_pool.Count}, created: {++_count}).");
return _onCreate();
}
///
/// Return an instance to the pool and assign null.
/// Be sure to return the instance obtained with with this method.
///
public void Return(ref T instance)
{
if (instance == null || _pool.Contains(instance)) return; // Ignore if already pooled or null.
_onReturn(instance); // Return the instance to the pool.
_pool.Push(instance);
Logging.Log(this, $"An instance is released (pooled: {_pool.Count}, created: {_count}).");
instance = default; // Set the reference to null.
}
}
///
/// Object pool for .
///
internal static class ListPool
{
private static readonly ObjectPool> s_ListPool =
new ObjectPool>(() => new List(), _ => true, x => x.Clear());
///
/// Rent an instance from the pool.
/// When you no longer need it, return it with .
///
public static List Rent()
{
return s_ListPool.Rent();
}
///
/// Return an instance to the pool and assign null.
/// Be sure to return the instance obtained with with this method.
///
public static void Return(ref List toRelease)
{
s_ListPool.Return(ref toRelease);
}
}
}