|
- using System;
- using UnityEngine;
- using UnityEngine.SceneManagement;
-
- namespace SUISS.Core
- {
- public class SingletonMonobehaviour<T> : MonoBehaviour where T : SingletonMonobehaviour<T>
- {
- protected virtual void Awake()
- {
- SingletonMonobehaviour<T>.applicationIsQuitting = false;
- SingletonMonobehaviour<T>.quitWarningShown = false;
- if (SingletonMonobehaviour<T>._instance == this)
- {
- UnityEngine.Debug.Log(string.Format("[Singleton] I'm {0}, already the instance. Not executing Awake again.", base.name));
- return;
- }
- if (SingletonMonobehaviour<T>._instance != null)
- {
- if (!this._overrideOldInstance)
- {
- this._isValidNewInstance = false;
- this.DestroyInstanceObject((T)((object)this));
- UnityEngine.Debug.LogWarning(string.Format("[Singleton] There already exists a {0} singleton. Instance will be kept with old, be carefull that enherited classes might reset other values in Awake or it's constructor. Instance on object {1} is removed.", typeof(T), base.gameObject.name));
- return;
- }
- SingletonMonobehaviour<T>._instance._isValidNewInstance = false;
- bool flag = this.DestroyInstanceObject(SingletonMonobehaviour<T>._instance);
- UnityEngine.Debug.LogWarning(string.Format("[Singleton] There already exists a {0} singleton. New instance is used because it has been flagged as ForceUse. {1}", typeof(T), (!flag) ? string.Empty : " Old gameobject has been destroyed."));
- }
- SingletonMonobehaviour<T>._instance = (T)((object)this);
- if (PersistentManager.HasAttribute(typeof(T)))
- {
- if (base.transform.parent != null)
- {
- UnityEngine.Debug.LogWarning("Please don't parent any singletons with marked as DontDestroyOnLoad, as we can't promise the DontDestroyOnLoad functionality then.");
- }
- UnityEngine.Object.DontDestroyOnLoad(this);
- }
- }
-
- public static T InstanceIfAvailable
- {
- get
- {
- return (!SingletonMonobehaviour<T>.IsAvailable) ? ((T)((object)null)) : SingletonMonobehaviour<T>.Instance;
- }
- }
-
- public static T Instance
- {
- get
- {
- if (!object.ReferenceEquals(SingletonMonobehaviour<T>._instance, null))
- {
- return SingletonMonobehaviour<T>._instance;
- }
- if (SingletonMonobehaviour<T>.applicationIsQuitting)
- {
- if (!SingletonMonobehaviour<T>.quitWarningShown)
- {
- UnityEngine.Debug.LogWarning(string.Format("[Singleton] Instance '{0}' already destroyed on application quit. Won't create again - returning null.", typeof(T)));
- SingletonMonobehaviour<T>.quitWarningShown = true;
- }
- return (T)((object)null);
- }
- object @lock = SingletonMonobehaviour<T>._lock;
- T instance;
- lock (@lock)
- {
- if (SingletonMonobehaviour<T>._instance == null)
- {
- SingletonMonobehaviour<T>._instance = (T)((object)UnityEngine.Object.FindObjectOfType(typeof(T)));
- if (UnityEngine.Object.FindObjectsOfType(typeof(T)).Length > 1)
- {
- UnityEngine.Debug.LogError("[Singleton] Something went really wrong - there should never be more than 1 singleton! Reopenning the scene might fix it.");
- return SingletonMonobehaviour<T>._instance;
- }
- if (PersistentManager.HasAttribute(typeof(T)))
- {
- if (PersistentManager.SceneWasLoaded)
- {
- UnityEngine.Debug.LogWarning("[Singleton] PersistentManagers scene was already loaded.");
- }
- else
- {
- bool flag = true;
- if (SceneManager.GetSceneByName("PersistentManagers").IsValid())
- {
- SceneManager.LoadScene("PersistentManagers", LoadSceneMode.Additive);
- }
- else
- {
- UnityEngine.Debug.LogWarning(typeof(T).ToString() + "'s attribute [PersistentManager] wants a PersistentManagers scene, but its not in the build settings! Will create a DontDestroyOnLoad object now. Please remove the attribute or implement it correctly (PersistentManager scene)");
- flag = false;
- }
- PersistentManager.SceneWasLoaded = true;
- SingletonMonobehaviour<T>._instance = (T)((object)UnityEngine.Object.FindObjectOfType(typeof(T)));
- if (SingletonMonobehaviour<T>._instance == null && flag)
- {
- UnityEngine.Debug.LogWarning(string.Format("[Singleton] Loading of PersistentManagers scene did not create instance of {0}.", typeof(T)));
- }
- }
- }
- if (SingletonMonobehaviour<T>._instance == null)
- {
- GameObject gameObject = new GameObject();
- SingletonMonobehaviour<T>._instance = gameObject.AddComponent<T>();
- gameObject.name = string.Format("(singleton) {0}", typeof(T).ToString());
- if (PersistentManager.HasAttribute(typeof(T)))
- {
- UnityEngine.Object.DontDestroyOnLoad(gameObject);
- }
- if (!PersistentManager.IsLoadAtRuntime(typeof(T)))
- {
- UnityEngine.Debug.LogError(string.Format("[Singleton] An instance of {0} is needed in the scene, so '{1}' was created{2}.", typeof(T), gameObject, (!PersistentManager.HasAttribute(typeof(T))) ? string.Empty : " with DontDestroyOnLoad"));
- }
- }
- else
- {
- UnityEngine.Debug.Log(string.Format("[Singleton] Using instance already created: {0}", SingletonMonobehaviour<T>._instance.gameObject.name));
- }
- }
- instance = SingletonMonobehaviour<T>._instance;
- }
- return instance;
- }
- }
-
- [Obsolete("Instead of using this, call Instance on the type you want.")]
- public static S InstanceAs<S>() where S : T
- {
- T instance = SingletonMonobehaviour<T>.Instance;
- if (instance is S)
- {
- return instance as S;
- }
- UnityEngine.Debug.LogError(string.Format("[Singleton] Instance of type {0} is not assignable to type {1}", (!(instance == null)) ? instance.GetType().Name : "null", typeof(S)));
- return (S)((object)null);
- }
-
- public static bool IsAvailable
- {
- get
- {
- return SingletonMonobehaviour<T>._instance != null;
- }
- }
-
- protected virtual void OnApplicationQuit()
- {
- SingletonMonobehaviour<T>.applicationIsQuitting = true;
- SingletonMonobehaviour<T>.quitWarningShown = false;
- }
-
- protected virtual void OnDestroy()
- {
- if (!this._isValidNewInstance)
- {
- return;
- }
- if (SingletonMonobehaviour<T>._instance == null)
- {
- UnityEngine.Debug.LogWarning(string.Format("[Singleton] instance of {0} singleton already is null in OnDestroy", typeof(T)));
- }
- SingletonMonobehaviour<T>._instance = (T)((object)null);
- }
-
- private bool DestroyInstanceObject(T instance)
- {
- GameObject gameObject = instance.gameObject;
- UnityEngine.Object.Destroy(instance);
- bool result = false;
- if (gameObject.transform.childCount == 0 && gameObject.GetComponents<Component>().Length <= 2)
- {
- UnityEngine.Object.Destroy(gameObject);
- result = true;
- }
- return result;
- }
-
- private static T _instance = (T)((object)null);
-
- private static object _lock = new object();
-
- private static bool quitWarningShown = false;
-
- [SerializeField]
- [Tooltip("Use this instance for the entire game cycle, even when someone with the same flag wants to become the instance")]
- protected bool _overrideOldInstance;
-
- protected bool _isValidNewInstance = true;
-
- private static bool applicationIsQuitting = false;
- }
- }
|