using System;
using System.Runtime.CompilerServices;
using UnityEngine;
namespace Nullframes.Threading
{
public sealed partial class Dispatcher
{
///
/// Get the current instance of . If no instance can be found a new object is created.
/// This property is only allowed to be accessed from the main thread!
///
public static Dispatcher Current => GetOrCreateDispatcherInstance();
///
/// Promises to return a valid dispatcher instance.
///
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static Dispatcher GetOrCreateDispatcherInstance()
{
if (current != null)
{
return current;
}
GuardAgainstIsNotMainThread(nameof(Current));
#if UNITY_EDITOR
if (!Application.isPlaying)
{
current = FindObjectOfType() ?? new GameObject(nameof(Dispatcher)).AddComponent();
return current;
}
#endif
current = new GameObject(nameof(Dispatcher)).AddComponent();
return current;
}
private static Dispatcher current;
///
/// flag to determine if an invalid operation exception should be thrown when destroying the GameObject.
///
private bool _throw = true;
private void Awake()
{
if (this == null)
{
return;
}
if (current != null && current != this)
{
Debug.LogWarning($"Multiple Dispatcher detected! Destroying {gameObject.name} Please ensure that there is only one Dispatcher in your scene!");
_throw = false;
Destroy(gameObject);
return;
}
current = this;
DontDestroyOnLoad(gameObject);
gameObject.hideFlags = runtimeHideFlags;
}
private void OnDestroy()
{
if (Current != this)
{
return;
}
current = null;
if (_throw && gameObject.scene.isLoaded)
{
Validate();
throw new InvalidOperationException(
$"{nameof(Dispatcher)} was destroyed during playmode. Please ensure that the {nameof(Dispatcher)} is not destroyed during playmode!");
}
}
}
}