1
0
mirror of https://github.com/oliverbooth/X10D synced 2024-11-10 03:25:41 +00:00

Cache Singleton<T> instance on Awake

This commit is contained in:
Oliver Booth 2022-12-31 14:49:32 +00:00
parent 35591b05e2
commit ea51adc632
No known key found for this signature in database
GPG Key ID: 32A00B35503AF634
2 changed files with 19 additions and 5 deletions

View File

@ -111,7 +111,7 @@
### Changed ### Changed
- X10D: `TimeSpanParser.TryParse` now accepts a nullable string, and returns false if this input is null or empty - X10D: `TimeSpanParser.TryParse` now accepts a nullable string, and returns false if this input is null or empty
- X10D.Unity: Obsolesced `Singleton<T>` - X10D.Unity: `Singleton<T>` now caches instance where possible
## [3.1.0] ## [3.1.0]
### Added ### Added

View File

@ -7,12 +7,11 @@ namespace X10D.Unity;
/// thread-safe. /// thread-safe.
/// </summary> /// </summary>
/// <typeparam name="T">The type of the singleton.</typeparam> /// <typeparam name="T">The type of the singleton.</typeparam>
[Obsolete("This implementation of the singleton pattern is discouraged, and this class will be removed in future. " +
"DO NOT USE THIS TYPE IN PRODUCTION.")]
public abstract class Singleton<T> : MonoBehaviour public abstract class Singleton<T> : MonoBehaviour
where T : Singleton<T> where T : Singleton<T>
{ {
private static Lazy<T> s_instanceLazy = new(CreateLazyInstanceInternal, false); private static Lazy<T> s_instanceLazy = new(CreateLazyInstanceInternal, false);
private static T? s_instance;
/// <summary> /// <summary>
/// Gets the instance of the singleton. /// Gets the instance of the singleton.
@ -20,7 +19,15 @@ public abstract class Singleton<T> : MonoBehaviour
/// <value>The singleton instance.</value> /// <value>The singleton instance.</value>
public static T Instance public static T Instance
{ {
get => s_instanceLazy.Value; 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;
} }
/// <summary> /// <summary>
@ -28,17 +35,24 @@ public abstract class Singleton<T> : MonoBehaviour
/// </summary> /// </summary>
protected virtual void OnDestroy() protected virtual void OnDestroy()
{ {
s_instance = null;
s_instanceLazy = new Lazy<T>(CreateLazyInstanceInternal, false); s_instanceLazy = new Lazy<T>(CreateLazyInstanceInternal, false);
} }
private static T CreateLazyInstanceInternal() private static T CreateLazyInstanceInternal()
{ {
if (s_instance)
{
return s_instance!;
}
if (FindObjectOfType<T>() is { } instance) if (FindObjectOfType<T>() is { } instance)
{ {
s_instance = instance;
return instance; return instance;
} }
var gameObject = new GameObject {name = typeof(T).Name}; var gameObject = new GameObject {name = typeof(T).Name};
return gameObject.AddComponent<T>(); return s_instance = gameObject.AddComponent<T>();
} }
} }