2026-03-20 12:07:44 -04:00
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections.Generic;
|
2026-02-13 09:22:11 -05:00
|
|
|
|
|
2026-06-02 12:55:39 -04:00
|
|
|
|
namespace Cielonos.MainGame
|
2026-02-13 09:22:11 -05:00
|
|
|
|
{
|
2026-03-20 12:07:44 -04:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 全局泛型消息总线,提供极致的注册与派发性能。
|
|
|
|
|
|
/// 基于结构体/类事件容器,零 GC 装箱。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public static class GameEventBus
|
2026-02-13 09:22:11 -05:00
|
|
|
|
{
|
2026-03-20 12:07:44 -04:00
|
|
|
|
// 核心技术:利用 C# 泛型的静态特性,每当 T 变化时,都会独立生成一个 EventBus<T> 实例。
|
|
|
|
|
|
// 这意味着派发事件时,连字典查表的哈希开销都不需要,直接访问对应类型的 Action 链!
|
|
|
|
|
|
private static class EventNode<T> where T : IGameEvent
|
|
|
|
|
|
{
|
|
|
|
|
|
public static Action<T> OnEvent;
|
|
|
|
|
|
}
|
2026-02-13 09:22:11 -05:00
|
|
|
|
|
2026-03-20 12:07:44 -04:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 订阅一个特定类型的事件。
|
|
|
|
|
|
/// 注意:请在生命周期结束(如 OnDestroy)时务必调用 Unsubscribe,否则会导致内存泄漏。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public static void Subscribe<T>(Action<T> onEvent) where T : IGameEvent
|
|
|
|
|
|
{
|
|
|
|
|
|
EventNode<T>.OnEvent += onEvent;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 取消订阅一个特定类型的事件。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public static void Unsubscribe<T>(Action<T> onEvent) where T : IGameEvent
|
|
|
|
|
|
{
|
|
|
|
|
|
EventNode<T>.OnEvent -= onEvent;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 广播一个事件。所有订阅了该事件的监听器将立即同步处理。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public static void Publish<T>(T gameEvent) where T : IGameEvent
|
|
|
|
|
|
{
|
|
|
|
|
|
EventNode<T>.OnEvent?.Invoke(gameEvent);
|
|
|
|
|
|
}
|
2026-02-13 09:22:11 -05:00
|
|
|
|
}
|
2026-03-20 12:07:44 -04:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 所有事件必须实现该空接口。
|
|
|
|
|
|
/// 使用 Struct 作为事件可以完全消除由于 new Event 引发的堆内存分配 (GC Alloc)。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public interface IGameEvent {}
|
|
|
|
|
|
}
|