93 lines
3.6 KiB
C#
93 lines
3.6 KiB
C#
/*
|
||
* @Author: 白哉
|
||
* @Description:
|
||
* @Date: 2025年07月01日 星期二 19:07:32
|
||
* @Modify:
|
||
*/
|
||
|
||
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using RuntimeData;
|
||
using TH1Renderer;
|
||
|
||
|
||
namespace Logic.Event
|
||
{
|
||
public static class EventManager
|
||
{
|
||
// 使用一个字典来存储所有事件的订阅者。
|
||
// 键(Key)是事件的类型(Type),值(Value)是响应该事件的委托(Delegate)。
|
||
private static Dictionary<Type, Delegate> eventListeners = new Dictionary<Type, Delegate>();
|
||
|
||
/// <summary>
|
||
/// 订阅一个事件。
|
||
/// </summary>
|
||
/// <typeparam name="T">要订阅的事件类型(必须是struct)。</typeparam>
|
||
/// <param name="listener">事件发生时要执行的回调方法。</param>
|
||
public static void Subscribe<T>(Action<T> listener) where T : struct
|
||
{
|
||
Type eventType = typeof(T);
|
||
|
||
// 如果字典中已存在该事件类型的委托
|
||
if (eventListeners.TryGetValue(eventType, out Delegate existingDelegate))
|
||
{
|
||
// 将新的监听器添加到现有委托链中
|
||
eventListeners[eventType] = Delegate.Combine(existingDelegate, listener);
|
||
}
|
||
else // 如果是第一次订阅该事件
|
||
{
|
||
// 直接将监听器作为新的委托存入字典
|
||
eventListeners[eventType] = listener;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 取消订阅一个事件。
|
||
/// </summary>
|
||
/// <typeparam name="T">要取消订阅的事件类型(必须是struct)。</typeparam>
|
||
/// <param name="listener">之前订阅时使用的回调方法。</param>
|
||
public static void Unsubscribe<T>(Action<T> listener) where T : struct
|
||
{
|
||
Type eventType = typeof(T);
|
||
|
||
// 只有在字典中存在该事件类型时才进行操作
|
||
if (eventListeners.TryGetValue(eventType, out Delegate existingDelegate))
|
||
{
|
||
// 从委托链中移除指定的监听器
|
||
Delegate resultDelegate = Delegate.Remove(existingDelegate, listener);
|
||
|
||
// 如果移除后委托链不为空,则更新字典
|
||
if (resultDelegate != null)
|
||
{
|
||
eventListeners[eventType] = resultDelegate;
|
||
}
|
||
else // 如果移除后委托链为空,则从字典中移除该事件类型
|
||
{
|
||
eventListeners.Remove(eventType);
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 发布一个事件。
|
||
/// 所有订阅了该事件的监听器都将被同步调用。
|
||
/// </summary>
|
||
/// <typeparam name="T">要发布的事件类型(必须是struct)。</typeparam>
|
||
/// <param name="eventData">要传递给监听器的事件数据。</param>
|
||
public static void Publish<T>(T eventData) where T : struct
|
||
{
|
||
Type eventType = typeof(T);
|
||
|
||
// 尝试从字典中获取该事件的委托链
|
||
if (eventListeners.TryGetValue(eventType, out Delegate existingDelegate))
|
||
{
|
||
// 将通用的 Delegate 类型安全地转换为具体的 Action<T> 类型
|
||
// 使用 ?.Invoke() 可以安全地调用,即使委托为空也不会抛出异常
|
||
var action = existingDelegate as Action<T>;
|
||
action?.Invoke(eventData);
|
||
}
|
||
// 如果没有找到任何订阅者,则什么也不做。这是一种正常情况。
|
||
}
|
||
}
|
||
} |