using UOP1.Factory; using System.Collections.Generic; using UnityEngine; namespace UOP1.Pool { /// /// A generic pool that generates members of type T on-demand via a factory. /// /// Specifies the type of elements to pool. public abstract class PoolSO : ScriptableObject, IPool { protected readonly Stack Available = new Stack(); /// /// The factory which will be used to create on demand. /// public abstract IFactory Factory { get; set; } protected bool HasBeenPrewarmed { get; set; } protected virtual T Create() { return Factory.Create(); } /// /// Prewarms the pool with a of . /// /// The number of members to create as a part of this pool. /// NOTE: This method can be called at any time, but only once for the lifetime of the pool. public virtual void Prewarm(int num) { if (HasBeenPrewarmed) { Debug.LogWarning($"Pool {name} has already been prewarmed."); return; } for (int i = 0; i < num; i++) { Available.Push(Create()); } HasBeenPrewarmed = true; } /// /// Requests a from this pool. /// /// The requested . public virtual T Request() { return Available.Count > 0 ? Available.Pop() : Create(); } /// /// Batch requests a collection from this pool. /// /// A collection. public virtual IEnumerable Request(int num = 1) { List members = new List(num); for (int i = 0; i < num; i++) { members.Add(Request()); } return members; } /// /// Returns a to the pool. /// /// The to return. public virtual void Return(T member) { Available.Push(member); } /// /// Returns a collection to the pool. /// /// The collection to return. public virtual void Return(IEnumerable members) { foreach (T member in members) { Return(member); } } public virtual void OnDisable() { Available.Clear(); HasBeenPrewarmed = false; } } }