using UnityEngine;
namespace IPA.Utilities
{
///
/// Generate a persistent singleton which can be destroyed.
///
///
public class ModSingleton : MonoBehaviour where T : MonoBehaviour
{
///
/// The stored reference for the instance
///
protected static T _instance;
///
/// The lock for the instance to prevent more than one being created.
///
protected static object _lock = new object();
///
/// Checks to see if the singleton if the singleton can be accessed
///
public static bool IsSingletonAvailable => _instance != null;
///
/// Noncapitalized version which points to the actual property.
///
public static T instance => Instance;
///
/// Creates and or returns the singleton
///
public static T Instance
{
get
{
T result;
object @lock = _lock;
lock (@lock)
{
if (_instance == null)
{
_instance = (T)((object)FindObjectOfType(typeof(T)));
if (FindObjectsOfType(typeof(T)).Length > 1)
{
IPA.Logging.Logger.log.Warn($"[Singleton] Something went really wrong - there should never be more than one singleton of {nameof(T)}");
return _instance;
}
if (_instance == null)
{
GameObject gameObject = new GameObject();
_instance = gameObject.AddComponent();
gameObject.name = $"{nameof(T)} Singleton";
DontDestroyOnLoad(gameObject);
}
}
result = _instance;
}
return result;
}
}
///
/// Called when the singleton is enabled to prevent the singleton from being destroyed naturally
///
private void OnEnabled()
{
DontDestroyOnLoad(this);
}
///
/// Destroys the singleton.
///
public static void Destroy()
{
if (_instance != null)
{
_lock = new object();
Destroy(_instance);
}
}
///
/// Touches the instance to easily create it without having to assign it.
///
public static void TouchInstance()
{
_ = Instance == null;
}
}
}