// Animancer // Copyright 2020 Kybernetik // //#define ANIMANCER_LOG_OBJECT_POOLING using System.Collections.Generic; using UnityEngine; namespace Animancer { /// Convenience methods for accessing . public static class ObjectPool { /************************************************************************************************************************/ /// /// Calls to get a spare item if there are any, or create a new one. /// public static T Acquire() where T : class, new() { return ObjectPool.Acquire(); } /// /// Calls to get a spare item if there are any, or create a new one. /// public static void Acquire(out T item) where T : class, new() { item = ObjectPool.Acquire(); } /************************************************************************************************************************/ /// /// Calls to add the `item` to the list of spares so it can be reused. /// public static void Release(T item) where T : class, new() { ObjectPool.Release(item); } /// /// Calls to add the `item` to the list of spares so it can be reused. /// public static void Release(ref T item) where T : class, new() { if (item != null) { ObjectPool.Release(item); item = null; } } /************************************************************************************************************************/ /// /// Calls to get a spare if /// there are any or create a new one. /// public static List AcquireList() { var list = ObjectPool>.Acquire(); Debug.Assert(list.Count == 0, "A pooled collection is not empty. Collections must not be modified after being released to the pool."); return list; } /// /// Calls to clear the `list` and mark it as a spare /// so it can be later returned by . /// public static void Release(List list) { list.Clear(); ObjectPool>.Release(list); } /************************************************************************************************************************/ /// /// Calls to get a spare if /// there are any or create a new one. /// public static HashSet AcquireSet() { var set = ObjectPool>.Acquire(); Debug.Assert(set.Count == 0, "A pooled collection is not empty. Collections must not be modified after being released to the pool."); return set; } /// /// Calls to clear the `set` and mark it as a spare /// so it can be later returned by . /// public static void Release(HashSet set) { set.Clear(); ObjectPool>.Release(set); } /************************************************************************************************************************/ } /// A simple object pooling system. public static class ObjectPool where T : class, new() { /************************************************************************************************************************/ private static readonly List Items = new List(); /************************************************************************************************************************/ /// The number of spare items currently in the pool. public static int Count { get { return Items.Count; } } /************************************************************************************************************************/ /// The of the internal list of spare items. public static int Capacity { get { return Items.Capacity; } set { if (Items.Count > value) Items.RemoveRange(value, Items.Count - value); Items.Capacity = value; } } /************************************************************************************************************************/ /// Returns a spare item if there are any, or creates a new one. public static T Acquire() { var count = Items.Count; if (count == 0) { return new T(); } else { count--; var item = Items[count]; Items.RemoveAt(count); return item; } } /************************************************************************************************************************/ /// Adds the `item` to the list of spares so it can be reused. public static void Release(T item) { Items.Add(item); } /************************************************************************************************************************/ } }