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: