From c15c14e39483aaa238824dd54a231c0f2fc4ab39 Mon Sep 17 00:00:00 2001 From: cneicy Date: Mon, 9 Mar 2026 17:42:06 +0800 Subject: [PATCH] perf: no wrapper --- Runtime/EventBus.cs | 54 +++++++++++-------------------- Runtime/EventBusRegHelper.cs | 63 +++--------------------------------- Runtime/EventHandlerInfo.cs | 26 +++++---------- Runtime/EventPool.cs | 3 +- 4 files changed, 33 insertions(+), 113 deletions(-) diff --git a/Runtime/EventBus.cs b/Runtime/EventBus.cs index 2e0103e..36ed365 100644 --- a/Runtime/EventBus.cs +++ b/Runtime/EventBus.cs @@ -26,16 +26,6 @@ namespace ShrinkEventBus [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void EnsureAutoManagerInitialized() => EventAutoRegHelper.EnsureInitialized(); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void RegisterEvent(Action handler, string methodName, Type declaringType, - EventPriority priority = EventPriority.NORMAL, bool receiveCanceled = false) where TEvent : EventBase - { - var methodInfo = declaringType.GetMethod(methodName, - BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static); - RegisterEventInternal(typeof(TEvent), handler, priority, 0, receiveCanceled, - $"Manual Sync Handler (Priority: {priority})", methodInfo); - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void RegisterEvent(Func handler, int priority = 0) where TEvent : EventBase @@ -184,11 +174,21 @@ namespace ShrinkEventBus } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static bool TryPrepareHandler(TEvent eventArgs, EventHandlerInfo handlerInfo) + where TEvent : EventBase + { + eventArgs.CurrentHandler = handlerInfo; + eventArgs.SetPhase(handlerInfo.Priority); + if (eventArgs.IsCancelable && eventArgs.IsCanceled && !handlerInfo.ReceiveCanceled) + return false; + return true; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static async UniTask TriggerEventAsync(TEvent eventArgs) where TEvent : EventBase { EnsureAutoManagerInitialized(); - var collection = EventCache.List; if (collection == null) return false; @@ -202,10 +202,7 @@ namespace ShrinkEventBus for (var i = 0; i < handlers.Length; i++) { var handlerInfo = handlers[i]; - eventArgs.CurrentHandler = handlerInfo; - eventArgs.SetPhase(handlerInfo.Priority); - - if (eventArgs is { IsCancelable: true, IsCanceled: true } && !handlerInfo.ReceiveCanceled) continue; + if (!TryPrepareHandler(eventArgs, handlerInfo)) continue; try { @@ -223,8 +220,7 @@ namespace ShrinkEventBus catch (Exception ex) { Debug.LogException(ex); - Debug.LogError( - $"[EventBus] {typeof(TEvent).Name} Async Handler {handlerInfo.DisplayDeclaringType.Name}.{handlerInfo.DisplayMethodName} Exception: {ex.Message}"); + Debug.LogError($"[EventBus] Async Handler Exception: {ex.Message}"); } } @@ -236,7 +232,6 @@ namespace ShrinkEventBus public static bool TriggerEvent(TEvent eventArgs) where TEvent : EventBase { EnsureAutoManagerInitialized(); - var collection = EventCache.List; if (collection == null) return false; @@ -250,10 +245,7 @@ namespace ShrinkEventBus for (var i = 0; i < handlers.Length; i++) { var handlerInfo = handlers[i]; - eventArgs.CurrentHandler = handlerInfo; - eventArgs.SetPhase(handlerInfo.Priority); - - if (eventArgs is { IsCancelable: true, IsCanceled: true } && !handlerInfo.ReceiveCanceled) continue; + if (!TryPrepareHandler(eventArgs, handlerInfo)) continue; try { @@ -272,8 +264,7 @@ namespace ShrinkEventBus catch (Exception ex) { Debug.LogException(ex); - Debug.LogError( - $"[EventBus] {typeof(TEvent).Name} Sync Handler {handlerInfo.DisplayDeclaringType.Name}.{handlerInfo.DisplayMethodName} Exception: {ex.Message}"); + Debug.LogError($"[EventBus] Sync Handler Exception: {ex.Message}"); } } @@ -311,19 +302,13 @@ namespace ShrinkEventBus { var method = trace.GetFrame(i)?.GetMethod(); var declaringType = method?.DeclaringType; - if (declaringType == null) continue; - if (declaringType == typeof(EventBus) || - declaringType.DeclaringType == typeof(EventBus)) continue; + if (declaringType == typeof(EventBus) || declaringType.DeclaringType == typeof(EventBus)) continue; var ns = declaringType.Namespace ?? ""; - if (ns.StartsWith("System") || ns.StartsWith("Cysharp") || ns.StartsWith("UnityEngine")) - continue; - + if (ns.StartsWith("System") || ns.StartsWith("Cysharp") || ns.StartsWith("UnityEngine")) continue; var className = declaringType.Name; var methodName = method.Name; - - if (declaringType.DeclaringType != null && className.StartsWith("<") && - className.Contains(">")) + if (declaringType.DeclaringType != null && className.StartsWith("<") && className.Contains(">")) { className = declaringType.DeclaringType.Name; var startIndex = declaringType.Name.IndexOf('<') + 1; @@ -337,7 +322,6 @@ namespace ShrinkEventBus } catch { - // ignored } return senderInfo; @@ -370,9 +354,7 @@ namespace ShrinkEventBus { if (target == null) return; if (IsInstanceRegistered(target)) return; - EventBusRegHelper.RegisterEventHandlers(target); - lock (InstanceLock) { if (!RegisteredInstances.Add(target)) return; diff --git a/Runtime/EventBusRegHelper.cs b/Runtime/EventBusRegHelper.cs index a826d76..e231f06 100644 --- a/Runtime/EventBusRegHelper.cs +++ b/Runtime/EventBusRegHelper.cs @@ -1,7 +1,6 @@ using System; using System.Reflection; using System.Runtime.CompilerServices; -using System.Threading.Tasks; using Cysharp.Threading.Tasks; using UnityEngine; @@ -54,17 +53,13 @@ namespace ShrinkEventBus foreach (var method in methods) { if (target != null && method.IsStatic) continue; - var attributes = method.GetCustomAttributes(typeof(EventSubscribeAttribute), false); if (attributes.Length == 0) continue; - var subscribeAttr = (EventSubscribeAttribute)attributes[0]; var parameters = method.GetParameters(); - if (parameters.Length != 1) continue; var parameterType = parameters[0].ParameterType; if (!typeof(EventBase).IsAssignableFrom(parameterType)) continue; - ProcessMethodRegistration(target, method, subscribeAttr, parameterType); } } @@ -87,17 +82,6 @@ namespace ShrinkEventBus subscribeAttr.NumericPriority, subscribeAttr.ReceiveCanceled, $"{scope} {typeName}.{method.Name} (UniTask)", method); } - else if (method.ReturnType == typeof(Task)) - { - var funcType = typeof(Func<,>).MakeGenericType(parameterType, typeof(Task)); - var handlerDelegate = target == null - ? Delegate.CreateDelegate(funcType, method) - : Delegate.CreateDelegate(funcType, target, method); - var wrappedHandler = WrapTaskHandlerWithMethodInfo(parameterType, handlerDelegate, method); - EventBus.RegisterEventInternal(parameterType, wrappedHandler, subscribeAttr.Priority, - subscribeAttr.NumericPriority, subscribeAttr.ReceiveCanceled, - $"{scope} {typeName}.{method.Name} (Task->UniTask)", method); - } else if (method.ReturnType == typeof(void)) { var actionType = typeof(Action<>).MakeGenericType(parameterType); @@ -108,6 +92,11 @@ namespace ShrinkEventBus subscribeAttr.NumericPriority, subscribeAttr.ReceiveCanceled, $"{scope} {typeName}.{method.Name} (Sync)", method); } + else + { + Debug.LogWarning( + $"[EventBus] Registration failed: {typeName}.{method.Name} return type must be void or UniTask."); + } } catch (Exception ex) { @@ -116,47 +105,5 @@ namespace ShrinkEventBus #endif } } - - private static Delegate WrapTaskHandlerWithMethodInfo(Type eventType, Delegate taskHandler, - MethodInfo originalMethod) - { - var method = typeof(EventBusRegHelper) - .GetMethod(nameof(WrapTaskActionWithMethodInfo), BindingFlags.NonPublic | BindingFlags.Static) - ?.MakeGenericMethod(eventType); - return (Delegate)method.Invoke(null, new object[] { taskHandler, originalMethod })!; - } - - private static Func WrapTaskActionWithMethodInfo(Delegate actionDelegate, - MethodInfo originalMethod) - { - var typedAction = (Func)actionDelegate; - var wrapper = new MethodInfoPreservingTaskWrapper(typedAction, originalMethod); - return wrapper.ExecuteAsync; - } - - private class MethodInfoPreservingTaskWrapper - { - private readonly Func _originalAction; - public readonly MethodInfo OriginalMethod; - - public MethodInfoPreservingTaskWrapper(Func originalAction, MethodInfo originalMethod) - { - _originalAction = originalAction; - OriginalMethod = originalMethod; - } - - public async UniTask ExecuteAsync(T arg) - { - try - { - await _originalAction(arg); - } - catch (Exception ex) - { - Debug.LogException(ex); - Debug.LogError($"[EventBus] Task {OriginalMethod.Name}: {ex.Message}"); - } - } - } } } \ No newline at end of file diff --git a/Runtime/EventHandlerInfo.cs b/Runtime/EventHandlerInfo.cs index 280e1b0..0628008 100644 --- a/Runtime/EventHandlerInfo.cs +++ b/Runtime/EventHandlerInfo.cs @@ -1,10 +1,15 @@ using System; using System.Reflection; - #pragma warning disable CS8632 // 只能在 "#nullable" 注释上下文内的代码中使用可为 null 的引用类型的注释。 + namespace ShrinkEventBus { + public interface IMethodWrapper + { + MethodInfo OriginalMethod { get; } + } + public class EventHandlerInfo { public Delegate Handler { get; } @@ -49,24 +54,9 @@ namespace ShrinkEventBus private static MethodInfo? ExtractOriginalMethodFromWrapper(Delegate handler) { - if (handler.Target == null) return null; - - var targetType = handler.Target.GetType(); - if (!targetType.Name.Contains("MethodInfoPreserving")) return null; - - try + if (handler.Target is IMethodWrapper wrapper) { - var field = targetType.GetField("OriginalMethod", - BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); - if (field != null) return field.GetValue(handler.Target) as MethodInfo; - - var prop = targetType.GetProperty("OriginalMethod", - BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); - if (prop != null) return prop.GetValue(handler.Target) as MethodInfo; - } - catch - { - // ignored + return wrapper.OriginalMethod; } return null; diff --git a/Runtime/EventPool.cs b/Runtime/EventPool.cs index 0689053..8f8eed2 100644 --- a/Runtime/EventPool.cs +++ b/Runtime/EventPool.cs @@ -7,6 +7,7 @@ namespace ShrinkEventBus { private static readonly Stack Pool = new(32); private static readonly object Lock = new(); + private static readonly Action CachedReleaseAction = e => Release((T)e); public static T Get() { @@ -21,7 +22,7 @@ namespace ShrinkEventBus } var newEvt = new T(); - newEvt.ReleaseAction = e => Release((T)e); + newEvt.ReleaseAction = CachedReleaseAction; return newEvt; }