81 lines
2.5 KiB
C#
81 lines
2.5 KiB
C#
#nullable enable
|
|
|
|
using System;
|
|
using System.Threading;
|
|
using ShrinkSDK.Runtime;
|
|
|
|
namespace ShrinkEventBus
|
|
{
|
|
public static class ShrinkEventBusRuntime
|
|
{
|
|
private static IShrinkMainThreadDispatcher _mainThreadDispatcher = CreateDefaultDispatcher();
|
|
|
|
public static IShrinkMainThreadDispatcher MainThreadDispatcher =>
|
|
Volatile.Read(ref _mainThreadDispatcher);
|
|
|
|
public static void ConfigureMainThreadDispatcher(IShrinkMainThreadDispatcher dispatcher)
|
|
{
|
|
if (dispatcher == null)
|
|
throw new ArgumentNullException(nameof(dispatcher));
|
|
Volatile.Write(ref _mainThreadDispatcher, dispatcher);
|
|
}
|
|
|
|
private static IShrinkMainThreadDispatcher CreateDefaultDispatcher()
|
|
{
|
|
#if UNITY_5_3_OR_NEWER
|
|
return new ShrinkUnityMainThreadDispatcher();
|
|
#else
|
|
return new ShrinkSynchronizationContextDispatcher(
|
|
SynchronizationContext.Current,
|
|
Thread.CurrentThread.ManagedThreadId);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
#if UNITY_5_3_OR_NEWER
|
|
internal sealed class ShrinkUnityMainThreadDispatcher : IShrinkMainThreadDispatcher
|
|
{
|
|
public bool IsMainThread => Cysharp.Threading.Tasks.PlayerLoopHelper.IsMainThread;
|
|
|
|
public bool TryPost(Action action)
|
|
{
|
|
if (action == null)
|
|
throw new ArgumentNullException(nameof(action));
|
|
Cysharp.Threading.Tasks.PlayerLoopHelper.AddContinuation(
|
|
Cysharp.Threading.Tasks.PlayerLoopTiming.Update,
|
|
action);
|
|
return true;
|
|
}
|
|
}
|
|
#else
|
|
internal sealed class ShrinkSynchronizationContextDispatcher : IShrinkMainThreadDispatcher
|
|
{
|
|
private readonly SynchronizationContext? _context;
|
|
private readonly int _threadId;
|
|
|
|
public ShrinkSynchronizationContextDispatcher(SynchronizationContext? context, int threadId)
|
|
{
|
|
_context = context;
|
|
_threadId = threadId;
|
|
}
|
|
|
|
public bool IsMainThread => Thread.CurrentThread.ManagedThreadId == _threadId;
|
|
|
|
public bool TryPost(Action action)
|
|
{
|
|
if (action == null)
|
|
throw new ArgumentNullException(nameof(action));
|
|
if (IsMainThread)
|
|
{
|
|
action();
|
|
return true;
|
|
}
|
|
if (_context == null)
|
|
return false;
|
|
_context.Post(static state => ((Action)state!).Invoke(), action);
|
|
return true;
|
|
}
|
|
}
|
|
#endif
|
|
}
|