/****************************************************************************** * Copyright (C) Ultraleap, Inc. 2011-2021. * * * * Use subject to the terms of the Apache License 2.0 available at * * http://www.apache.org/licenses/LICENSE-2.0, or another agreement * * between Ultraleap and you, your company or other organization. * ******************************************************************************/ using System; using System.Collections.Generic; using UnityEngine; namespace Leap.Unity { /// /// Implement this interface to recieve a callback whenever your object is /// spawned from a pool. /// public interface IPoolable { void OnSpawn(); void OnRecycle(); } /// /// A very lightweight pool implementation. When you call Spawn, an object /// of type T will be returned. If the pool was not empty, the T will be /// taken from the pool. If the pool was empty, a new T will be constructed /// and returned instead. Calling recycle will return a T to the pool. /// /// It is not required to implement the IPoolable interface to use the Pool /// class, which allows you to pool types such as List or Dictionary, types /// which you have no control over. But make sure that you clean up these /// objects before you recycle them! /// /// /// Example workflow for types you DO NOT have control over: /// /// // .Spawn(); /// obj.Init(stuff); /// /// //Do something with obj /// /// obj.Clear(); /// Pool.Recycle(obj); /// /// // "]]> // (Close XML fix for Visual Studio) /// /// /// /// Example workflow for types you DO have control over: /// /// // .Spawn(); /// obj.Init(stuff); /// /// // Do something with obj /// /// obj.Dispose(); // e.g. call Recycle(this) in the Dispose() implementation /// /// // "]]> // (Close XML fix for Visual Studio) /// /// public static class Pool where T : new() { [ThreadStatic] private static Stack _pool = new Stack(); public static T Spawn() { if (_pool == null) _pool = new Stack(); T value; if (_pool.Count > 0) { value = _pool.Pop(); } else { value = new T(); } if (value is IPoolable) { (value as IPoolable).OnSpawn(); } return value; } public static void Recycle(T t) { if (t == null) { Debug.LogError("Cannot recycle a null object."); return; } if (t is IPoolable) { (t as IPoolable).OnRecycle(); } _pool.Push(t); } /// Calls Recycle for each argument. public static void Recycle(T t0, T t1) { Recycle(t0); Recycle(t1); } /// Calls Recycle for each argument. public static void Recycle(T t0, T t1, T t2) { Recycle(t0); Recycle(t1); Recycle(t2); } /// Calls Recycle for each argument. public static void Recycle(T t0, T t1, T t2, T t3) { Recycle(t0); Recycle(t1); Recycle(t2); Recycle(t3); } } }