feat(event-kit): 添加 SingleCastEventSystem 单播事件系统

This commit is contained in:
2026-03-09 15:59:23 +08:00
parent 30732b8f3f
commit eaaf458de3
2 changed files with 174 additions and 0 deletions
@@ -0,0 +1,163 @@
using System;
using System.Collections.Generic;
using UnityEngine;
namespace AibisDream.Framework
{
/// <summary>
/// 单播事件系统
/// 特点:通过枚举索引事件,多处可触发,但仅有一个方法能被注册(后注册覆盖先注册)
/// 用途:用于解耦项目中的单例依赖
/// </summary>
public class SingleCastEventSystem
{
public static readonly SingleCastEventSystem Global = new();
// 内部接口:用于统一存储不同类型的事件
private interface IEventEntry
{
}
// 类型化的条目存储
private class Entry<T> : IEventEntry where T : Delegate
{
public T Handler;
}
// 按枚举类型分组的存储
// Key: 枚举类型, Value: 该枚举所有值的条目数组
private readonly Dictionary<Type, IEventEntry[]> _entries = new(50);
#region
public void Register<T>(T key, Action handler) where T : IConvertible
{
var entry = GetEntry<T, Action>(key);
#if DEBUG
if (entry.Handler != null)
{
Debug.LogWarning($"[SingleCastEvent] {typeof(T).Name}.{key} 已被注册,正在覆盖");
}
#endif
entry.Handler = handler;
}
public void Trigger<T>(T key) where T : IConvertible
{
var entry = GetEntryOrNull<T, Action>(key);
entry?.Handler?.Invoke();
}
#endregion
#region 1
public void Register<T, T1>(T key, Action<T1> handler) where T : IConvertible
{
var entry = GetEntry<T, Action<T1>>(key);
#if DEBUG
if (entry.Handler != null)
{
Debug.LogWarning($"[SingleCastEvent] {typeof(T).Name}.{key} 已被注册,正在覆盖");
}
#endif
entry.Handler = handler;
}
public void Trigger<T, T1>(T key, T1 arg1) where T : IConvertible
{
var entry = GetEntryOrNull<T, Action<T1>>(key);
entry?.Handler?.Invoke(arg1);
}
#endregion
#region 2
public void Register<T, T1, T2>(T key, Action<T1, T2> handler) where T : IConvertible
{
var entry = GetEntry<T, Action<T1, T2>>(key);
#if DEBUG
if (entry.Handler != null)
{
Debug.LogWarning($"[SingleCastEvent] {typeof(T).Name}.{key} 已被注册,正在覆盖");
}
#endif
entry.Handler = handler;
}
public void Trigger<T, T1, T2>(T key, T1 arg1, T2 arg2) where T : IConvertible
{
var entry = GetEntryOrNull<T, Action<T1, T2>>(key);
entry?.Handler?.Invoke(arg1, arg2);
}
#endregion
#region
public void Unregister<T>(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<TDelegate> GetEntry<TEnum, TDelegate>(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<TDelegate>();
}
return (Entry<TDelegate>)arr[index];
}
private Entry<TDelegate> GetEntryOrNull<TEnum, TDelegate>(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<TDelegate>;
}
#endregion
}
}