/******************************************************************************
* 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);
}
}
}