using System; using System.Collections.Generic; using UnityEngine; namespace AibisDream.Framework { /// /// 单播事件系统 /// 特点:通过枚举索引事件,多处可触发,但仅有一个方法能被注册(后注册覆盖先注册) /// 用途:用于解耦项目中的单例依赖 /// public class SingleCastEventSystem { public static readonly SingleCastEventSystem Global = new(); // 内部接口:用于统一存储不同类型的事件 private interface IEventEntry { } // 类型化的条目存储 private class Entry : IEventEntry where T : Delegate { public T Handler; } // 按枚举类型分组的存储 // Key: 枚举类型, Value: 该枚举所有值的条目数组 private readonly Dictionary _entries = new(50); #region 无参数 public void Register(T key, Action handler) where T : IConvertible { var entry = GetEntry(key); #if DEBUG if (entry.Handler != null) { Debug.LogWarning($"[SingleCastEvent] {typeof(T).Name}.{key} 已被注册,正在覆盖"); } #endif entry.Handler = handler; } public void Trigger(T key) where T : IConvertible { var entry = GetEntryOrNull(key); entry?.Handler?.Invoke(); } #endregion #region 1个参数 public void Register(T key, Action handler) where T : IConvertible { var entry = GetEntry>(key); #if DEBUG if (entry.Handler != null) { Debug.LogWarning($"[SingleCastEvent] {typeof(T).Name}.{key} 已被注册,正在覆盖"); } #endif entry.Handler = handler; } public void Trigger(T key, T1 arg1) where T : IConvertible { var entry = GetEntryOrNull>(key); entry?.Handler?.Invoke(arg1); } #endregion #region 2个参数 public void Register(T key, Action handler) where T : IConvertible { var entry = GetEntry>(key); #if DEBUG if (entry.Handler != null) { Debug.LogWarning($"[SingleCastEvent] {typeof(T).Name}.{key} 已被注册,正在覆盖"); } #endif entry.Handler = handler; } public void Trigger(T key, T1 arg1, T2 arg2) where T : IConvertible { var entry = GetEntryOrNull>(key); entry?.Handler?.Invoke(arg1, arg2); } #endregion #region 注销 public void Unregister(T key) where T : IConvertible { var index = key.ToInt32(null); var enumType = typeof(T); if (_entries.TryGetValue(enumType, out var arr) && index < arr.Length) { arr[index] = null; } } public void UnregisterAll() { _entries.Clear(); } #endregion #region 内部辅助方法 private Entry GetEntry(TEnum key) where TEnum : IConvertible where TDelegate : Delegate { var index = key.ToInt32(null); var enumType = typeof(TEnum); if (!_entries.TryGetValue(enumType, out var arr)) { // 首次使用该枚举类型,创建条目数组 var valueCount = Enum.GetValues(enumType).Length; arr = new IEventEntry[valueCount]; _entries[enumType] = arr; } if (arr[index] == null) { arr[index] = new Entry(); } return (Entry)arr[index]; } private Entry GetEntryOrNull(TEnum key) where TEnum : IConvertible where TDelegate : Delegate { var index = key.ToInt32(null); var enumType = typeof(TEnum); if (!_entries.TryGetValue(enumType, out var arr)) return null; if (index >= arr.Length) return null; return arr[index] as Entry; } #endregion } }