feat: add shared runtime and codegen support
This commit is contained in:
@@ -189,7 +189,11 @@ namespace ShrinkEventBus
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
#if UNITY_5_3_OR_NEWER
|
||||
UnityEngine.Debug.LogException(exception);
|
||||
#else
|
||||
System.Diagnostics.Trace.TraceError(exception.ToString());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,9 @@ using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Diagnostics;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using ShrinkSDK.Runtime;
|
||||
|
||||
namespace ShrinkEventBus
|
||||
{
|
||||
@@ -206,15 +208,17 @@ namespace ShrinkEventBus
|
||||
internal sealed class ShrinkMainThreadScheduler : IShrinkBusScheduler
|
||||
{
|
||||
private readonly ShrinkSchedulerQueue _queue;
|
||||
private readonly IShrinkMainThreadDispatcher _dispatcher;
|
||||
private int _pumpScheduled;
|
||||
private int _disposed;
|
||||
|
||||
public ShrinkMainThreadScheduler(string name, ShrinkBusOptions options)
|
||||
{
|
||||
_queue = new ShrinkSchedulerQueue(name, options);
|
||||
_dispatcher = ShrinkEventBusRuntime.MainThreadDispatcher;
|
||||
}
|
||||
|
||||
public bool IsOnSchedulerThread => PlayerLoopHelper.IsMainThread;
|
||||
public bool IsOnSchedulerThread => _dispatcher.IsMainThread;
|
||||
|
||||
public bool TryPost(Action action)
|
||||
{
|
||||
@@ -276,12 +280,15 @@ namespace ShrinkEventBus
|
||||
{
|
||||
if (Interlocked.Exchange(ref _pumpScheduled, 1) != 0)
|
||||
return;
|
||||
UniTask.Void(PumpAsync);
|
||||
if (_dispatcher.TryPost(() => PumpAsync().Forget()))
|
||||
return;
|
||||
Interlocked.Exchange(ref _pumpScheduled, 0);
|
||||
ShrinkEventDiagnostics.LogException(new InvalidOperationException(
|
||||
"The configured main-thread dispatcher rejected an EventBus pump."));
|
||||
}
|
||||
|
||||
private async UniTaskVoid PumpAsync()
|
||||
private async UniTask PumpAsync()
|
||||
{
|
||||
await UniTask.SwitchToMainThread();
|
||||
try
|
||||
{
|
||||
while (_queue.TryDequeue(out var item))
|
||||
@@ -453,7 +460,8 @@ namespace ShrinkEventBus
|
||||
var waitMs = timeout == Timeout.InfiniteTimeSpan
|
||||
? Timeout.Infinite
|
||||
: Math.Max(0, (int)Math.Min(int.MaxValue, timeout.TotalMilliseconds));
|
||||
var stopped = await UniTask.RunOnThreadPool(() => _stopped.Wait(waitMs));
|
||||
var stopped = await Task.Run(() => _stopped.Wait(waitMs))
|
||||
.AsUniTask(useCurrentSynchronizationContext: false);
|
||||
if (!stopped)
|
||||
{
|
||||
_queue.DropPending();
|
||||
@@ -538,7 +546,7 @@ namespace ShrinkEventBus
|
||||
queue.DropPending();
|
||||
return;
|
||||
}
|
||||
await UniTask.Delay(1, ignoreTimeScale: true);
|
||||
await Task.Delay(1).AsUniTask(useCurrentSynchronizationContext: false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,11 +2,12 @@
|
||||
"name": "ShrinkEventBus.Runtime",
|
||||
"rootNamespace": "ShrinkEventBus",
|
||||
"references": [
|
||||
"UniTask"
|
||||
"UniTask",
|
||||
"ShrinkRuntime.Abstractions"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"autoReferenced": true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
#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
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3badb120248f61b4e9af7b571431a681
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user