com.alicizax.kybernetik.ani.../Runtime/Data Types/Static.cs
陈思海 3e7c253249 init
2025-01-08 15:26:57 +08:00

76 lines
3.1 KiB
C#

// Animancer // https://kybernetik.com.au/animancer // Copyright 2018-2024 Kybernetik //
using System;
using UnityEngine;
using Object = UnityEngine.Object;
namespace Animancer
{
/// <summary>
/// Holds an instance of <typeparamref name="T"/> which is automatically created
/// using its parameterless constructor when first accessed.
/// </summary>
/// <remarks>
/// Don't use classes that inherit from <see cref="Object"/> as <typeparamref name="T"/>.
/// <para></para>
/// This is close to the "Singleton Programming Pattern", except it can't prevent additional instances of
/// <typeparamref name="T"/> from being created elsewhere.
/// </remarks>
/// https://kybernetik.com.au/animancer/api/Animancer/Static_1
public static class Static<T>
where T : class, new()
{
/************************************************************************************************************************/
/// <summary>
/// An instance of <typeparamref name="T"/> which is automatically created
/// using its parameterless constructor when first accessed.
/// </summary>
public static readonly T Instance = new();
/************************************************************************************************************************/
/// <summary>Ensures that the <see cref="Instance"/> has been created without immediately using it.</summary>
public static void Initialize() { }
/************************************************************************************************************************/
#if UNITY_ASSERTIONS
static Static()
{
if (Instance is Object)
{
Debug.LogError(
$"{typeof(Static<T>).GetNameCS()} type is invalid:" +
$" {nameof(UnityEngine)}.{nameof(Object)} types require special memory management by Unity" +
$" which may cause problems when used with this system.",
Instance as Object);
}
}
#endif
/************************************************************************************************************************/
/// <summary>[Assert-Conditional]
/// Call this in the constructor of <typeparamref name="T"/> to make sure there is only one instance.
/// </summary>
[System.Diagnostics.Conditional(Strings.Assertions)]
public static void AssertSingularity()
{
#if UNITY_ASSERTIONS
// If the static instance has already been set, then this is not the first one to be created.
if (Instance != null)
{
var name = typeof(T).GetNameCS();
throw new InvalidOperationException(
$"Multiple {name} objects have been created." +
$"\nUse Static<{name}>.Instance instead of creating your own instances.");
}
#endif
}
/************************************************************************************************************************/
}
}