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,
}