using System; using System.Collections.Generic; using UnityEngine; namespace TyphoonEvent { [AddComponentMenu("")] internal class EventKitImpl : MonoBehaviour { private static EventKitImpl _instance = null; private static object _lock = new object(); public static EventKitImpl Instance { get { #if UNITY_EDITOR if (!Application.isPlaying) { throw new Exception($"EventKit 仅支持在运行模式下使用"); } #endif if (_instance == null) { lock (_lock) { if (_instance == null) { _instance = new GameObject(nameof(EventKit)).AddComponent(); DontDestroyOnLoad(_instance.gameObject); } } } return _instance; } } private static uint OperationIDCounter { get; set; } = 0; public static bool HasInstance() => _instance != null; public static void SetToNull() => _instance = null; private EventKitImpl() { } public Dictionary Collections { get; } = new Dictionary(); public Dictionary Handlers { get; } = new Dictionary(); public Dictionary Groups { get; } = new Dictionary(); //注册 public IEventProxy Register(Action handler) { var type = typeof(T); var proxy = new EventProxy(type, handler); CreateGet(type).Add(proxy); return proxy; } //发布事件 public void Publish(T message) { var type = typeof(T); var collection = CreateGet(type); if (collection.Changed) { //重构事件 RebuildHandlerMap(type, collection.RebuildHandlerArray()); } var handler = Handlers[type]; foreach (var proxy in handler) { proxy?.Invoke(message); } } public void Build() { } //取消注册 internal void Unregister(IEventProxy proxy) { CreateGet(proxy.MessageType).Remove(proxy); } private ProxyCollection CreateGet(Type type) { if (Collections.TryGetValue(type, out var match)) { return match; } var result = new ProxyCollection(); Collections.Add(type, result); return result; } private void RebuildHandlerMap(Type type, IEventProxy[] delegates) { Handlers.Remove(type); Handlers.Add(type, delegates); } public void RebuildAllHandlers() { foreach (var pair in Collections) { var collection = pair.Value; var type = pair.Key; if (collection.Changed) { RebuildHandlerMap(type, collection.RebuildHandlerArray()); } } } public void RebuildHandlers() { var type = typeof(T); var collection = CreateGet(type); if (collection.Changed) { RebuildHandlerMap(type, collection.RebuildHandlerArray()); } } internal ProxyGroup GetGroup(uint key) { if (Groups.TryGetValue(key, out var match)) { return match; } return null; } internal void Register(IEventProxy[] proxies) { foreach (var proxy in proxies) { CreateGet(proxy.MessageType).Add(proxy); } } internal void ReleaseGroup(uint id) { Groups.Remove(id); } internal EventOperation NewOperation(IEventProxy[] proxies) { var id = OperationIDCounter += 1; var group = new ProxyGroup(id, proxies); Groups.Add(group.ID, group); return new EventOperation(id); } } }