1
0
mirror of https://github.com/oliverbooth/X10D synced 2024-11-14 04:15:41 +00:00

Add Singleton<T> class

This commit is contained in:
Oliver Booth 2022-05-13 08:54:00 +01:00
parent 23e07b65b8
commit 048e0a22f7
No known key found for this signature in database
GPG Key ID: 32A00B35503AF634
6 changed files with 104 additions and 0 deletions

View File

@ -28,6 +28,7 @@
- X10D: Added `Vector4.WithY()` - X10D: Added `Vector4.WithY()`
- X10D: Added `Vector4.WithZ()` - X10D: Added `Vector4.WithZ()`
- X10D: Added `Vector4.WithW()` - X10D: Added `Vector4.WithW()`
- X10D.Unity: Added `Singleton<T>` class
- X10D.Unity: Added `Color.Inverted()` - X10D.Unity: Added `Color.Inverted()`
- X10D.Unity: Added `Color.WithA()` - X10D.Unity: Added `Color.WithA()`
- X10D.Unity: Added `Color.WithB()` - X10D.Unity: Added `Color.WithB()`

View File

@ -0,0 +1,45 @@
using System.Collections;
using NUnit.Framework;
using UnityEngine;
using UnityEngine.TestTools;
namespace X10D.Unity.Tests
{
public class SingletonTests
{
[UnityTest]
public IEnumerator Singleton_ShouldReturnNewInstance_WhenNoInstanceExists()
{
TestBehaviour instance = Singleton<TestBehaviour>.Instance;
Assert.IsTrue(instance);
Assert.IsTrue(instance.Flag);
yield break;
}
[UnityTest]
public IEnumerator Singleton_ShouldReturnSameInstance_WhenAccessedTwice()
{
TestBehaviour instance = Singleton<TestBehaviour>.Instance;
Assert.IsTrue(instance);
Assert.AreEqual(instance, Singleton<TestBehaviour>.Instance);
yield break;
}
[UnityTest]
public IEnumerator Singleton_ShouldReturnNewInstance_WhenDestroyed()
{
TestBehaviour instance = Singleton<TestBehaviour>.Instance;
Assert.IsTrue(instance);
Object.Destroy(instance);
yield return null;
Assert.IsFalse(instance);
// ReSharper disable once HeuristicUnreachableCode
instance = Singleton<TestBehaviour>.Instance;
Assert.IsNotNull(instance);
Assert.IsTrue(instance.Flag);
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 5c51198d124f40859bd9298d3241d5a6
timeCreated: 1652428949

View File

@ -0,0 +1,10 @@
namespace X10D.Unity.Tests
{
internal sealed class TestBehaviour : Singleton<TestBehaviour>
{
public bool Flag
{
get => true;
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: df932718d20948ecbe9b0de8aa7bbaf4
timeCreated: 1652428898

View File

@ -0,0 +1,42 @@
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);
/// <summary>
/// Gets the instance of the singleton.
/// </summary>
/// <value>The singleton instance.</value>
public static T Instance
{
get => s_instanceLazy.Value;
}
/// <summary>
/// Called when the object is destroyed.
/// </summary>
protected virtual void OnDestroy()
{
s_instanceLazy = new Lazy<T>(CreateLazyInstanceInternal, false);
}
private static T CreateLazyInstanceInternal()
{
if (FindObjectOfType<T>() is { } instance)
{
return instance;
}
var gameObject = new GameObject {name = typeof(T).Name};
return gameObject.AddComponent<T>();
}
}