using GFramework.Core.Abstractions.events;
namespace GFramework.Core.events;
///
/// 支持优先级的泛型事件类
///
/// 事件回调函数的参数类型
public class PriorityEvent : IEvent
{
///
/// 存储已注册的上下文事件处理器列表
///
private readonly List _contextHandlers = new();
///
/// 存储已注册的事件处理器列表
///
private readonly List _handlers = new();
///
/// 标记事件是否已被处理(用于 UntilHandled 传播模式)
///
private bool _handled;
///
/// 显式实现 IEvent 接口中的 Register 方法
///
/// 无参事件处理方法
/// IUnRegister 对象,用于稍后注销该事件监听器
IUnRegister IEvent.Register(Action onEvent)
{
return Register(_ => onEvent(), 0);
}
///
/// 注册一个事件监听器,默认优先级为 0
///
/// 要注册的事件处理方法
/// IUnRegister 对象,用于稍后注销该事件监听器
public IUnRegister Register(Action onEvent)
{
return Register(onEvent, 0);
}
///
/// 注册一个事件监听器,并指定优先级
///
/// 要注册的事件处理方法
/// 优先级,数值越大优先级越高
/// IUnRegister 对象,用于稍后注销该事件监听器
public IUnRegister Register(Action onEvent, int priority)
{
var handler = new EventHandler(onEvent, priority);
_handlers.Add(handler);
// 按优先级降序排序(高优先级在前)
_handlers.Sort((a, b) => b.Priority.CompareTo(a.Priority));
return new DefaultUnRegister(() => UnRegister(onEvent));
}
///
/// 取消指定的事件监听器
///
/// 需要被注销的事件处理方法
public void UnRegister(Action onEvent)
{
_handlers.RemoveAll(h => h.Handler == onEvent);
}
///
/// 注册一个上下文事件监听器,并指定优先级
///
/// 要注册的事件处理方法,接收 EventContext 参数
/// 优先级,数值越大优先级越高
/// IUnRegister 对象,用于稍后注销该事件监听器
public IUnRegister RegisterWithContext(Action> onEvent, int priority = 0)
{
var handler = new ContextEventHandler(onEvent, priority);
_contextHandlers.Add(handler);
// 按优先级降序排序(高优先级在前)
_contextHandlers.Sort((a, b) => b.Priority.CompareTo(a.Priority));
return new DefaultUnRegister(() => UnRegisterContext(onEvent));
}
///
/// 取消指定的上下文事件监听器
///
/// 需要被注销的事件处理方法
public void UnRegisterContext(Action> onEvent)
{
_contextHandlers.RemoveAll(h => h.Handler == onEvent);
}
///
/// 触发事件处理程序,并指定传播模式
///
/// 传递给事件处理程序的参数
/// 事件传播模式
public void Trigger(T t, EventPropagation propagation = EventPropagation.All)
{
_handled = false;
switch (propagation)
{
case EventPropagation.All:
TriggerAll(t);
break;
case EventPropagation.UntilHandled:
TriggerUntilHandled(t);
break;
case EventPropagation.Highest:
TriggerHighest(t);
break;
}
}
///
/// 触发所有事件处理器(按优先级顺序)
///
/// 事件参数
private void TriggerAll(T t)
{
var allHandlers = MergeAndSortHandlers(t);
var context = new EventContext(t);
foreach (var item in allHandlers)
{
if (item.IsContext)
{
item.ContextHandler?.Invoke(context);
}
else
{
item.Handler?.Invoke();
}
}
}
///
/// 触发事件处理器直到被处理
///
/// 事件参数
private void TriggerUntilHandled(T t)
{
var allHandlers = MergeAndSortHandlers(t);
var context = new EventContext(t);
foreach (var item in allHandlers)
{
if (item.IsContext)
{
item.ContextHandler?.Invoke(context);
if (context.IsHandled) break;
}
else
{
item.Handler?.Invoke();
if (_handled) break; // 保持向后兼容
}
}
}
///
/// 仅触发最高优先级的事件处理器
///
/// 事件参数
private void TriggerHighest(T t)
{
var normalSnapshot = _handlers.ToArray();
var contextSnapshot = _contextHandlers.ToArray();
var highestPriority = GetHighestPriority(normalSnapshot, contextSnapshot);
if (highestPriority != int.MinValue)
{
ExecuteHighPriorityNormalHandlers(normalSnapshot, t, highestPriority);
ExecuteHighPriorityContextHandlers(contextSnapshot, t, highestPriority);
}
}
///
/// 合并并排序所有事件处理器
///
/// 事件参数
/// 合并排序后的处理器列表
private List<(int Priority, Action? Handler, Action>? ContextHandler, bool IsContext)>
MergeAndSortHandlers(T t)
{
var normalSnapshot = _handlers.ToArray();
var contextSnapshot = _contextHandlers.ToArray();
// 使用快照避免迭代期间修改
return normalSnapshot
.Select(h => (h.Priority, Handler: (Action?)(() => h.Handler.Invoke(t)),
ContextHandler: (Action>?)null, IsContext: false))
.Concat(contextSnapshot
.Select(h => (h.Priority, Handler: (Action?)null,
ContextHandler: (Action>?)h.Handler, IsContext: true)))
.OrderByDescending(h => h.Priority)
.ToList();
}
///
/// 获取最高优先级
///
/// 普通事件处理器数组
/// 上下文事件处理器数组
/// 最高优先级值
private static int GetHighestPriority(EventHandler[] normalHandlers, ContextEventHandler[] contextHandlers)
{
var highestPriority = int.MinValue;
if (normalHandlers.Length > 0)
highestPriority = Math.Max(highestPriority, normalHandlers[0].Priority);
if (contextHandlers.Length > 0)
highestPriority = Math.Max(highestPriority, contextHandlers[0].Priority);
return highestPriority;
}
///
/// 执行高优先级的普通事件处理器
///
/// 处理器数组
/// 事件参数
/// 最高优先级
private static void ExecuteHighPriorityNormalHandlers(EventHandler[] handlers, T t, int highestPriority)
{
foreach (var handler in handlers)
{
if (handler.Priority < highestPriority) break;
handler.Handler.Invoke(t);
}
}
///
/// 执行高优先级的上下文事件处理器
///
/// 处理器数组
/// 事件参数
/// 最高优先级
private static void ExecuteHighPriorityContextHandlers(ContextEventHandler[] handlers, T t, int highestPriority)
{
var context = new EventContext(t);
foreach (var handler in handlers)
{
if (handler.Priority < highestPriority) break;
handler.Handler.Invoke(context);
}
}
///
/// 获取当前已注册的监听器总数量(包括普通监听器和上下文监听器)
///
/// 监听器总数量
public int GetListenerCount()
{
return _handlers.Count + _contextHandlers.Count;
}
///
/// 事件处理器包装类,包含处理器和优先级
///
private sealed class EventHandler(Action handler, int priority)
{
public Action Handler { get; } = handler;
public int Priority { get; } = priority;
}
///
/// 上下文事件处理器包装类,包含处理器和优先级
///
private sealed class ContextEventHandler(Action> handler, int priority)
{
public Action> Handler { get; } = handler;
public int Priority { get; } = priority;
}
}