事件总线 EventBus

using System.Collections.Concurrent;

namespace ClassLibrary1;

public class EventBus
{
    private static readonly ConcurrentDictionary<EventType, Delegate> _buses = new();
    private static readonly object _locker = new object();
    /// <summary>
    /// 添加监听事件
    /// </summary>
    /// <param name="eventType"></param>
    /// <param name="delegate"></param>
    public static void on(EventType @eventType, Delegate @delegate)
    {
        if (@delegate == null)
            throw new ArgumentNullException(nameof(@delegate));

        _buses.AddOrUpdate(@eventType, @delegate, (k, v) => Delegate.Combine(v, @delegate));
    }

    /// <summary>
    /// 移除监听事件
    /// </summary>
    public static void off(EventType eventType, Delegate @delegate)
    {
        if (@delegate == null)
            throw new ArgumentNullException(nameof(@delegate));

        lock (_locker)
        {
            if (_buses.TryGetValue(eventType, out var existingDelegates))
            {
                // 获取委托的方法指针
                nint ptr = @delegate.Method.MethodHandle.GetFunctionPointer();

                // 过滤掉匹配的委托
                var delegates = existingDelegates.GetInvocationList();
                var remaining = delegates.Where(d =>
                    d.Method.MethodHandle.GetFunctionPointer() != ptr).ToArray();

                if (remaining.Any() == true)
                {
                    _buses.TryUpdate(eventType, Delegate.Combine(remaining)!, existingDelegates);
                }
                else
                {
                    _buses.TryRemove(eventType, out _);
                }
            }
        }
    }
    public static void emit(EventType @eventType)
    {
        Delegate[]? delegates = getMethods(@eventType);
        if (delegates is null) return;
        foreach (var d in delegates)
        {
            try
            {
                if (d.Target is null) continue;
                (d as Action)?.Invoke();
            }
            catch
            { }
            
        }
    }
    public static void emit<T>(EventType @eventType, T arg1)
    {
        Delegate[]? delegates = getMethods(@eventType);
        if (delegates is null) return;
        foreach (var d in delegates)
        {
            try 
            {
                if (d.Target is null) continue;
                (d as Action<T>)?.Invoke(arg1);
            }
            catch { }
            
        }
    }
    public static void emit<T1, T2>(EventType @eventType, T1 arg1, T2 arg2)
    {
        Delegate[]? delegates = getMethods(@eventType);
        if (delegates is null) return;
        foreach (var d in delegates)
        {
            try
            {
                if (d.Target is null) continue;
                (d as Action<T1, T2>)?.Invoke(arg1, arg2);
            }
            catch { }
            
        }
    }
    public static void emit<T1, T2, T3>(EventType @eventType, T1 arg1, T2 arg2, T3 arg3)
    {
        Delegate[]? delegates = getMethods(@eventType);
        if (delegates is null) return;
        foreach (var d in delegates)
        {
            try
            {
                if (d.Target is null) continue;
                (d as Action<T1, T2, T3>)?.Invoke(arg1, arg2, arg3);
            }
            catch { }
        }
    }
    public static void emit<T1, T2, T3, T4>(EventType @eventType, T1 arg1, T2 arg2, T3 arg3, T4 arg4)
    {
        Delegate[]? delegates = getMethods(@eventType);
        if (delegates is null) return;
        foreach (var d in delegates)
        {
            try
            {
                if (d.Target is null) continue;
                (d as Action<T1, T2, T3, T4>)?.Invoke(arg1, arg2, arg3, arg4);
            }
            catch { }
        }
    }
    public static void emit<T1, T2, T3, T4, T5>(EventType @eventType, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5)
    {
        Delegate[]? delegates = getMethods(@eventType);
        if (delegates is null) return;
        foreach (var d in delegates)
        {
            try
            {
                if (d.Target is null) continue;
                (d as Action<T1, T2, T3, T4, T5>)?.Invoke(arg1, arg2, arg3, arg4, arg5);
            }
            catch { }
            
        }
    }
    public static void emit<T1, T2, T3, T4, T5, T6>(EventType @eventType, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6)
    {
        Delegate[]? delegates = getMethods(@eventType);
        if (delegates is null) return;
        foreach (var d in delegates)
        {
            try
            {
                if (d.Target is null) continue;
                (d as Action<T1, T2, T3, T4, T5, T6>)?.Invoke(arg1, arg2, arg3, arg4, arg5, arg6);
            }
            catch { }
            
        }
    }
    public static void emit<T1, T2, T3, T4, T5, T6, T7>(EventType @eventType, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7)
    {
        Delegate[]? delegates = getMethods(@eventType);
        if (delegates is null) return;
        foreach (var d in delegates)
        {
            try
            {
                if (d.Target is null) continue;
                (d as Action<T1, T2, T3, T4, T5, T6, T7>)?.Invoke(arg1, arg2, arg3, arg4, arg5, arg6, arg7);
            }
            catch { }
            
        }
    }
    static Delegate[]? getMethods(EventType @eventType)
    {
        _buses.TryGetValue(@eventType, out Delegate? outDelegates);
        return outDelegates?.GetInvocationList();
    }
}
public enum EventType
{
    /// <summary>
    /// 控制台日志
    /// </summary>
    ConsoleLog,
    /// <summary>
    /// 向客户端广播消息
    /// </summary>
    BroadcastMessageToClient,
}

 

posted @ 2023-09-27 16:07  cchong005  阅读(95)  评论(0)    收藏  举报