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