using System; using System.Collections.Generic; using UnityEngine.Events; namespace UnityEngine.Rendering { public class ObjectPool where T : new() { readonly Stack m_Stack = new Stack(); readonly UnityAction m_ActionOnGet; readonly UnityAction m_ActionOnRelease; public int countAll { get; private set; } public int countActive { get { return countAll - countInactive; } } public int countInactive { get { return m_Stack.Count; } } public ObjectPool(UnityAction actionOnGet, UnityAction actionOnRelease) { m_ActionOnGet = actionOnGet; m_ActionOnRelease = actionOnRelease; } public T Get() { T element; if (m_Stack.Count == 0) { element = new T(); countAll++; } else { element = m_Stack.Pop(); } if (m_ActionOnGet != null) m_ActionOnGet(element); return element; } public struct PooledObject : IDisposable { readonly T m_ToReturn; readonly ObjectPool m_Pool; internal PooledObject(T value, ObjectPool pool) { m_ToReturn = value; m_Pool = pool; } void IDisposable.Dispose() => m_Pool.Release(m_ToReturn); } public PooledObject Get(out T v) => new PooledObject(v = Get(), this); public void Release(T element) { if (m_Stack.Count > 0 && ReferenceEquals(m_Stack.Peek(), element)) Debug.LogError("Internal error. Trying to destroy object that is already released to pool."); if (m_ActionOnRelease != null) m_ActionOnRelease(element); m_Stack.Push(element); } } public static class GenericPool where T : new() { // Object pool to avoid allocations. static readonly ObjectPool s_Pool = new ObjectPool(null, null); public static T Get() => s_Pool.Get(); public static ObjectPool.PooledObject Get(out T value) => s_Pool.Get(out value); public static void Release(T toRelease) => s_Pool.Release(toRelease); } public static class ListPool { // Object pool to avoid allocations. static readonly ObjectPool> s_Pool = new ObjectPool>(null, l => l.Clear()); public static List Get() => s_Pool.Get(); public static ObjectPool>.PooledObject Get(out List value) => s_Pool.Get(out value); public static void Release(List toRelease) => s_Pool.Release(toRelease); } public static class HashSetPool { // Object pool to avoid allocations. static readonly ObjectPool> s_Pool = new ObjectPool>(null, l => l.Clear()); public static HashSet Get() => s_Pool.Get(); public static ObjectPool>.PooledObject Get(out HashSet value) => s_Pool.Get(out value); public static void Release(HashSet toRelease) => s_Pool.Release(toRelease); } public static class DictionaryPool { // Object pool to avoid allocations. static readonly ObjectPool> s_Pool = new ObjectPool>(null, l => l.Clear()); public static Dictionary Get() => s_Pool.Get(); public static ObjectPool>.PooledObject Get(out Dictionary value) => s_Pool.Get(out value); public static void Release(Dictionary toRelease) => s_Pool.Release(toRelease); } }