perf(eventbus): remove inline allocations and expose binding snapshots
This commit is contained in:
@@ -143,6 +143,14 @@ namespace ShrinkEventBus
|
||||
return generated.AttachGenerated(Resolver, defaultBus ?? ShrinkBusKey.Game);
|
||||
}
|
||||
|
||||
public static IReadOnlyList<(Type EventType, System.Reflection.MethodInfo Handler)> CaptureBindings(IShrinkEventBus bus)
|
||||
{
|
||||
if (bus is ShrinkEventBusInstance instance) return instance.CaptureBindings();
|
||||
throw new NotSupportedException("This event bus does not expose binding diagnostics.");
|
||||
}
|
||||
|
||||
public static IReadOnlyList<IShrinkEventBus> CaptureNamedBuses() => new List<IShrinkEventBus>(Buses.Values);
|
||||
|
||||
internal static IReadOnlyList<(ShrinkBusKey Key, ShrinkBusOptions Options, int Subscribers)> Snapshot()
|
||||
{
|
||||
var snapshot = new List<(ShrinkBusKey, ShrinkBusOptions, int)>(Buses.Count);
|
||||
|
||||
@@ -14,6 +14,7 @@ namespace ShrinkEventBus
|
||||
internal interface IShrinkEventChannel
|
||||
{
|
||||
int Count { get; }
|
||||
void CaptureBindings(List<(Type EventType, System.Reflection.MethodInfo Handler)> bindings);
|
||||
bool RemoveSubscription(long subscriptionId);
|
||||
void Clear();
|
||||
void DetachSlot(int slot);
|
||||
@@ -87,6 +88,15 @@ namespace ShrinkEventBus
|
||||
private Action<TEvent>? _syncDispatcher;
|
||||
|
||||
public int Count => _snapshot.Length;
|
||||
public void CaptureBindings(List<(Type EventType, System.Reflection.MethodInfo Handler)> bindings)
|
||||
{
|
||||
var snapshot = _snapshot;
|
||||
foreach (var entry in snapshot)
|
||||
{
|
||||
var method = entry.SyncHandler?.Method ?? entry.AsyncHandler?.Method;
|
||||
if (method != null) bindings.Add((typeof(TEvent), method));
|
||||
}
|
||||
}
|
||||
|
||||
public void Add(long subscriptionId, long registrationOrder, Action<TEvent> handler,
|
||||
ShrinkSubscribeDescriptor descriptor)
|
||||
|
||||
@@ -75,7 +75,7 @@ namespace ShrinkEventBus
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public virtual ShrinkPostResult Post<TEvent>(in TEvent eventData) where TEvent : IShrinkEvent
|
||||
{
|
||||
if (eventData is null)
|
||||
if (!typeof(TEvent).IsValueType && eventData is null)
|
||||
throw new ArgumentNullException(nameof(eventData));
|
||||
if (Volatile.Read(ref _disposed) != 0)
|
||||
return TraceWithoutDispatch(in eventData,
|
||||
@@ -84,6 +84,11 @@ namespace ShrinkEventBus
|
||||
if (_isInline || _scheduler.IsOnSchedulerThread)
|
||||
return Dispatch(in eventData);
|
||||
|
||||
return PostScheduled(in eventData);
|
||||
}
|
||||
|
||||
private ShrinkPostResult PostScheduled<TEvent>(in TEvent eventData) where TEvent : IShrinkEvent
|
||||
{
|
||||
var queuedEvent = eventData;
|
||||
if (_scheduler.TryPost(() => Dispatch(in queuedEvent)))
|
||||
return new ShrinkPostResult(true, false, false);
|
||||
@@ -94,7 +99,7 @@ namespace ShrinkEventBus
|
||||
public virtual UniTask<ShrinkPostResult> PostAsync<TEvent>(TEvent eventData,
|
||||
CancellationToken cancellationToken = default) where TEvent : IShrinkEvent
|
||||
{
|
||||
if (eventData is null)
|
||||
if (!typeof(TEvent).IsValueType && eventData is null)
|
||||
throw new ArgumentNullException(nameof(eventData));
|
||||
if (Volatile.Read(ref _disposed) != 0)
|
||||
return UniTask.FromResult(TraceWithoutDispatch(in eventData,
|
||||
@@ -168,6 +173,13 @@ namespace ShrinkEventBus
|
||||
return new EventSubscription(this, subscriptionId);
|
||||
}
|
||||
|
||||
internal IReadOnlyList<(Type EventType, System.Reflection.MethodInfo Handler)> CaptureBindings()
|
||||
{
|
||||
var bindings = new List<(Type, System.Reflection.MethodInfo)>();
|
||||
lock (_channelGate) foreach (var channel in _channels.Values) channel.CaptureBindings(bindings);
|
||||
return bindings;
|
||||
}
|
||||
|
||||
internal int SubscriberCount
|
||||
{
|
||||
get
|
||||
@@ -367,7 +379,7 @@ namespace ShrinkEventBus
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public override ShrinkPostResult Post<TEvent>(in TEvent eventData)
|
||||
{
|
||||
if (eventData is null)
|
||||
if (!typeof(TEvent).IsValueType && eventData is null)
|
||||
throw new ArgumentNullException(nameof(eventData));
|
||||
if (IsDisposed)
|
||||
return TraceWithoutDispatch(in eventData,
|
||||
@@ -378,7 +390,7 @@ namespace ShrinkEventBus
|
||||
public override UniTask<ShrinkPostResult> PostAsync<TEvent>(TEvent eventData,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (eventData is null)
|
||||
if (!typeof(TEvent).IsValueType && eventData is null)
|
||||
throw new ArgumentNullException(nameof(eventData));
|
||||
if (IsDisposed)
|
||||
return UniTask.FromResult(TraceWithoutDispatch(in eventData,
|
||||
|
||||
Reference in New Issue
Block a user