From eaaf458de337f489127d2b66c686b075ddd65811 Mon Sep 17 00:00:00 2001 From: Ding Yuntian <1491671119@qq.com> Date: Mon, 9 Mar 2026 15:59:23 +0800 Subject: [PATCH] =?UTF-8?q?feat(event-kit):=20=E6=B7=BB=E5=8A=A0=20SingleC?= =?UTF-8?q?astEventSystem=20=E5=8D=95=E6=92=AD=E4=BA=8B=E4=BB=B6=E7=B3=BB?= =?UTF-8?q?=E7=BB=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Framework/Core/SingleCastEventSystem.cs | 163 ++++++++++++++++++ .../Core/SingleCastEventSystem.cs.meta | 11 ++ 2 files changed, 174 insertions(+) create mode 100644 Assets/Scripts/Framework/Core/SingleCastEventSystem.cs create mode 100644 Assets/Scripts/Framework/Core/SingleCastEventSystem.cs.meta diff --git a/Assets/Scripts/Framework/Core/SingleCastEventSystem.cs b/Assets/Scripts/Framework/Core/SingleCastEventSystem.cs new file mode 100644 index 000000000..9012ef674 --- /dev/null +++ b/Assets/Scripts/Framework/Core/SingleCastEventSystem.cs @@ -0,0 +1,163 @@ +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 + } +} diff --git a/Assets/Scripts/Framework/Core/SingleCastEventSystem.cs.meta b/Assets/Scripts/Framework/Core/SingleCastEventSystem.cs.meta new file mode 100644 index 000000000..2d4f492f1 --- /dev/null +++ b/Assets/Scripts/Framework/Core/SingleCastEventSystem.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4f1bd51550472834dbf4fb1c4d636373 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: