Files
ShrinkEventBus/Runtime/EventBusRegHelper.cs
T
2026-03-09 17:42:06 +08:00

109 lines
4.7 KiB
C#

using System;
using System.Reflection;
using System.Runtime.CompilerServices;
using Cysharp.Threading.Tasks;
using UnityEngine;
namespace ShrinkEventBus
{
public static class EventBusRegHelper
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void RegStaticEventHandler() => RegisterEventHandlersInternal(null);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void RegisterEventHandlers(object target) => RegisterEventHandlersInternal(target);
private static void RegisterEventHandlersInternal(object target)
{
var isStatic = target == null;
if (isStatic)
{
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
foreach (var assembly in assemblies)
{
try
{
foreach (var type in assembly.GetTypes())
{
if (type.GetCustomAttributes(typeof(EventBusSubscriberAttribute), false).Length == 0)
continue;
ScanMethodsAndRegister(null,
type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic));
}
}
catch
{
// ignored
}
}
}
else
{
var type = target.GetType();
if (type.GetCustomAttributes(typeof(EventBusSubscriberAttribute), false).Length == 0) return;
ScanMethodsAndRegister(target,
type.GetMethods(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public));
}
}
private static void ScanMethodsAndRegister(object target, MethodInfo[] methods)
{
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);
}
}
private static void ProcessMethodRegistration(object target, MethodInfo method,
EventSubscribeAttribute subscribeAttr, Type parameterType)
{
try
{
string scope = target == null ? "Static" : "Instance";
string typeName = target == null ? method.DeclaringType?.Name : target.GetType().Name;
if (method.ReturnType == typeof(UniTask))
{
var funcType = typeof(Func<,>).MakeGenericType(parameterType, typeof(UniTask));
var handlerDelegate = target == null
? Delegate.CreateDelegate(funcType, method)
: Delegate.CreateDelegate(funcType, target, method);
EventBus.RegisterEventInternal(parameterType, handlerDelegate, subscribeAttr.Priority,
subscribeAttr.NumericPriority, subscribeAttr.ReceiveCanceled,
$"{scope} {typeName}.{method.Name} (UniTask)", method);
}
else if (method.ReturnType == typeof(void))
{
var actionType = typeof(Action<>).MakeGenericType(parameterType);
var actionDelegate = target == null
? Delegate.CreateDelegate(actionType, method)
: Delegate.CreateDelegate(actionType, target, method);
EventBus.RegisterEventInternal(parameterType, actionDelegate, subscribeAttr.Priority,
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)
{
#if UNITY_EDITOR
Debug.LogWarning($"[EventBus] Registration failed for {method.Name}: {ex.Message}");
#endif
}
}
}
}