/****************************************************************************
* Copyright 2019 Nreal Techonology Limited. All rights reserved.
*
* This file is part of NRSDK.
*
* https://www.nreal.ai/
*
*****************************************************************************/
using UnityEngine;
namespace NRKernal
{
/// A single ton.
/// Generic type parameter.
public class SingleTon where T : new()
{
private static T instane = default(T);
public static void CreateInstance()
{
if(instane == null)
{
instane = new T();
}
}
/// Gets the instance.
/// The instance.
public static T Instance
{
get
{
if(instane == null)
{
CreateInstance();
}
return instane;
}
}
}
/// A singleton behaviour.
/// Generic type parameter.
public class SingletonBehaviour : MonoBehaviour where T : SingletonBehaviour
{
/// The instance.
private static T instance;
///
/// Returns the Singleton instance of the classes type. If no instance is found, then we search
/// for an instance in the scene. If more than one instance is found, we throw an error and no
/// instance is returned.
/// The instance.
protected static T Instance
{
get
{
if (instance == null && searchForInstance)
{
searchForInstance = false;
T[] objects = FindObjectsOfType();
if (objects.Length == 1)
{
instance = objects[0];
}
else if (objects.Length > 1)
{
Debug.LogErrorFormat("Expected exactly 1 {0} but found {1}.", typeof(T).ToString(), objects.Length);
}
}
return instance;
}
}
/// True to search for instance.
private static bool searchForInstance = true;
/// Assert is initialized.
public static void AssertIsInitialized()
{
Debug.Assert(IsInitialized, string.Format("The {0} singleton has not been initialized.", typeof(T).Name));
}
/// Returns whether the instance has been initialized or not.
/// True if this object is initialized, false if not.
public static bool IsInitialized
{
get
{
return instance != null;
}
}
/// True if is dirty, false if not.
protected bool isDirty = false;
///
/// Base Awake method that sets the Singleton's unique instance. Called by Unity when
/// initializing a MonoBehaviour. Scripts that extend Singleton should be sure to call
/// base.Awake() to ensure the static Instance reference is properly created.
protected virtual void Awake()
{
if (IsInitialized && instance != this)
{
isDirty = true;
DestroyImmediate(gameObject);
NRDebugger.Info("Trying to instantiate a second instance of singleton class {0}. Additional Instance was destroyed", GetType().Name);
}
else if (!IsInitialized)
{
instance = (T)this;
DontDestroyOnLoad(gameObject);
}
}
///
/// Base OnDestroy method that destroys the Singleton's unique instance. Called by Unity when
/// destroying a MonoBehaviour. Scripts that extend Singleton should be sure to call
/// base.OnDestroy() to ensure the underlying static Instance reference is properly cleaned up.
protected virtual void OnDestroy()
{
if (instance == this)
{
instance = null;
searchForInstance = true;
}
}
}
}