76 lines
3.1 KiB
C#
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
|
||
|
}
|
||
|
|
||
|
/************************************************************************************************************************/
|
||
|
}
|
||
|
}
|
||
|
|