X10D/X10D.Unity/src/Singleton.cs

61 lines
1.6 KiB
C#
Raw Normal View History

2022-05-13 07:54:00 +00:00
using UnityEngine;
namespace X10D.Unity;
/// <summary>
/// Represents a class which implements the singleton pattern for a specific <see cref="MonoBehaviour" />. This class is not
/// thread-safe.
/// </summary>
/// <typeparam name="T">The type of the singleton.</typeparam>
public abstract class Singleton<T> : MonoBehaviour
where T : Singleton<T>
{
private static Lazy<T> s_instanceLazy = new(CreateLazyInstanceInternal, false);
2022-12-31 14:49:32 +00:00
private static T? s_instance;
2022-05-13 07:54:00 +00:00
/// <summary>
/// Gets the instance of the singleton.
/// </summary>
/// <value>The singleton instance.</value>
#pragma warning disable CA1000
2022-05-13 07:54:00 +00:00
public static T Instance
#pragma warning restore CA1000
2022-05-13 07:54:00 +00:00
{
2022-12-31 14:49:32 +00:00
get => s_instance ? s_instance! : s_instanceLazy.Value;
}
/// <summary>
/// Called when the script instance is being loaded.
/// </summary>
protected virtual void Awake()
{
s_instance = (T?)this;
2022-05-13 07:54:00 +00:00
}
/// <summary>
/// Called when the object is destroyed.
/// </summary>
protected virtual void OnDestroy()
{
2022-12-31 14:49:32 +00:00
s_instance = null;
2022-05-13 07:54:00 +00:00
s_instanceLazy = new Lazy<T>(CreateLazyInstanceInternal, false);
}
private static T CreateLazyInstanceInternal()
{
2022-12-31 14:49:32 +00:00
if (s_instance)
{
return s_instance!;
}
2022-05-13 07:54:00 +00:00
if (FindObjectOfType<T>() is { } instance)
{
2022-12-31 14:49:32 +00:00
s_instance = instance;
2022-05-13 07:54:00 +00:00
return instance;
}
var gameObject = new GameObject {name = typeof(T).Name};
2022-12-31 14:49:32 +00:00
return s_instance = gameObject.AddComponent<T>();
2022-05-13 07:54:00 +00:00
}
}