using System; using System.Collections; using System.Collections.Generic; using MotionFramework.Console; using MotionFramework.Reference; namespace MotionFramework.Event { /// <summary> /// 事件管理器 /// </summary> public sealed class EventManager : ModuleSingleton<EventManager>, IModule { private class PostWrapper : IReference { public int PostFrame; public int EventID; public IEventMessage Message; public void OnRelease() { PostFrame = 0; EventID = 0; Message = null; } } private readonly Dictionary<int, LinkedList<Action<IEventMessage>>> _listeners = new Dictionary<int, LinkedList<Action<IEventMessage>>>(1000); private readonly List<PostWrapper> _postWrappers = new List<PostWrapper>(1000); void IModule.OnCreate(System.Object param) { } void IModule.OnUpdate() { for (int i = _postWrappers.Count - 1; i >= 0; i--) { var wrapper = _postWrappers[i]; if (UnityEngine.Time.frameCount > wrapper.PostFrame) { SendMessage(wrapper.EventID, wrapper.Message); _postWrappers.RemoveAt(i); ReferencePool.Release(wrapper); } } } void IModule.OnDestroy() { DestroySingleton(); } void IModule.OnGUI() { ConsoleGUI.Lable($"[{nameof(EventManager)}] Listener total count : {GetAllListenerCount()}"); } /// <summary> /// 添加监听 /// </summary> public void AddListener<TEvent>(System.Action<IEventMessage> listener) where TEvent : IEventMessage { AddListener(typeof(TEvent), listener); } /// <summary> /// 添加监听 /// </summary> public void AddListener(System.Type eventType, System.Action<IEventMessage> listener) { int eventId = eventType.GetHashCode(); AddListener(eventId, listener); } /// <summary> /// 添加监听 /// </summary> public void AddListener(int eventId, System.Action<IEventMessage> listener) { if (_listeners.ContainsKey(eventId) == false) _listeners.Add(eventId, new LinkedList<Action<IEventMessage>>()); if (_listeners[eventId].Contains(listener) == false) _listeners[eventId].AddLast(listener); } /// <summary> /// 移除监听 /// </summary> public void RemoveListener<TEvent>(System.Action<IEventMessage> listener) where TEvent : IEventMessage { RemoveListener(typeof(TEvent), listener); } /// <summary> /// 移除监听 /// </summary> public void RemoveListener(System.Type eventType, System.Action<IEventMessage> listener) { int eventId = eventType.GetHashCode(); RemoveListener(eventId, listener); } /// <summary> /// 移除监听 /// </summary> public void RemoveListener(int eventId, System.Action<IEventMessage> listener) { if (_listeners.ContainsKey(eventId)) { if (_listeners[eventId].Contains(listener)) _listeners[eventId].Remove(listener); } } /// <summary> /// 实时广播事件 /// </summary> public void SendMessage(IEventMessage message) { int eventId = message.GetType().GetHashCode(); SendMessage(eventId, message); } /// <summary> /// 实时广播事件 /// </summary> public void SendMessage(int eventId, IEventMessage message) { if (_listeners.ContainsKey(eventId) == false) return; LinkedList<Action<IEventMessage>> listeners = _listeners[eventId]; if (listeners.Count > 0) { var currentNode = listeners.Last; while (currentNode != null) { currentNode.Value.Invoke(message); currentNode = currentNode.Previous; } } // 回收引用对象 IReference refClass = message as IReference; if (refClass != null) ReferencePool.Release(refClass); } /// <summary> /// 延迟广播事件 /// </summary> public void PostMessage(IEventMessage message) { int eventId = message.GetType().GetHashCode(); PostMessage(eventId, message); } /// <summary> /// 延迟广播事件 /// </summary> public void PostMessage(int eventId, IEventMessage message) { var wrapper = ReferencePool.Spawn<PostWrapper>(); wrapper.PostFrame = UnityEngine.Time.frameCount; wrapper.EventID = eventId; wrapper.Message = message; _postWrappers.Add(wrapper); } /// <summary> /// 清空所有监听 /// </summary> public void ClearListeners() { foreach (int eventId in _listeners.Keys) { _listeners[eventId].Clear(); } _listeners.Clear(); } /// <summary> /// 获取监听者总数 /// </summary> private int GetAllListenerCount() { int count = 0; foreach (var list in _listeners) { count += list.Value.Count; } return count; } } }