OldBlueWater/BlueWater/Assets/Doozy/Runtime/Common/Models/SingletonBehaviour.cs

82 lines
3.0 KiB
C#

// Copyright (c) 2015 - 2023 Doozy Entertainment. All Rights Reserved.
// This code can only be used under the standard Unity Asset Store End User License Agreement
// A Copy of the EULA APPENDIX 1 is available at http://unity3d.com/company/legal/as_terms
using Doozy.Runtime.Common.Attributes;
using UnityEngine;
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable CheckNamespace
namespace Doozy.Runtime.Common
{
/// <summary> Base MonoBehaviour clas that implements the singleton pattern </summary>
/// <typeparam name="T"> Class type </typeparam>
public abstract class SingletonBehaviour<T> : MonoBehaviour where T : MonoBehaviour
{
/// <summary> Flag that returns TRUE if the application is quitting </summary>
[ClearOnReload(false)]
// ReSharper disable once StaticMemberInGenericType
public static bool IsQuitting;
/// <summary> Lock object used to make the singleton thread safe </summary>
[ClearOnReload(false)]
// ReSharper disable once StaticMemberInGenericType
private static readonly object Lock = new object();
[ClearOnReload]
private static T s_instance;
/// <summary> Get singleton instance </summary>
public static T instance
{
get
{
if (IsQuitting) return null;
lock (Lock)
{
if (s_instance != null) return s_instance;
#if UNITY_2023_1_OR_NEWER
T[] instances = FindObjectsByType<T>(FindObjectsSortMode.None);
#else
T[] instances = FindObjectsOfType<T>();
#endif
int count = instances.Length;
if (count == 1) return s_instance = instances[0];
if (count > 0)
{
Debug.LogWarning($"There are {count} instances of the singleton behaviour of type {typeof(T).Name}. There should only be one. Keeping the first one and destroying the rest.");
for (int i = 1; i < count; i++) Destroy(instances[i]);
return s_instance = instances[0];
}
s_instance = new GameObject(typeof(T).Name).AddComponent<T>();
return s_instance;
}
}
}
protected virtual void Awake()
{
if (s_instance != null && s_instance != this)
{
Debug.Log($"There cannot be two '{typeof(T).Name}' active at the same time. Destroying the '{gameObject.name}' GameObject!");
Destroy(gameObject);
return;
}
s_instance = GetComponent<T>();
DontDestroyOnLoad(gameObject);
}
protected virtual void OnDestroy()
{
if (s_instance == this)
s_instance = null;
}
private void OnApplicationQuit()
{
IsQuitting = true;
}
}
}