using System; using System.Collections.Generic; using UnityEngine; namespace ZC { public class EventManager : IEventManager { private static EventManager instance; public static EventManager Instance { get { if (instance == null) { instance = new EventManager(); } return instance; } } private readonly Dictionary>> m_EventPool; private EventHandler m_DefaultHandler; private Queue m_EventInfos; private Queue> _cache; /// /// 初始化事件管理器的新实例。 /// public EventManager() { m_EventInfos = new Queue(); _cache = new Queue>(); m_EventPool = new Dictionary>>(); } /// /// 获取事件处理函数的数量。 /// public int EventHandlerCount { get { return m_EventPool.Count; } } /// /// 获取事件数量。 /// public int EventCount { get { return m_EventPool.Count; } } public int Count(int id) { if (!m_EventPool.TryGetValue(id, out var list)) { return 0; } return list.Count; } /// /// 检查是否存在事件处理函数。 /// /// 事件类型编号。 /// 要检查的事件处理函数。 /// 是否存在事件处理函数。 public bool Check(int id, EventHandler handler) { if (handler == null) { throw new Exception("Event handler is invalid."); } if (!m_EventPool.TryGetValue(id, out var list) || list.Count == 0) { return false; } return list.Contains(handler); } /// /// 订阅事件处理函数。 /// /// 事件类型编号。 /// 要订阅的事件处理函数。 public void Subscribe(int id, EventHandler handler) { if (handler == null) { throw new Exception("Event handler is invalid."); } if (!m_EventPool.TryGetValue(id, out var list)) { m_EventPool[id] = list = new List>(); } list.Add(handler); } /// /// 取消订阅事件处理函数。 /// /// 事件类型编号。 /// 要取消订阅的事件处理函数。 public void Unsubscribe(int id, EventHandler handler) { if (handler == null) { throw new Exception("Event handler is invalid."); } if (!m_EventPool.TryGetValue(id, out var list)) { throw new Exception($"Event '{id}' not exists specified handler."); } if (list.Count == 0) { throw new Exception($"Event '{id}' not exists specified handler."); } var indexOf = list.IndexOf(handler); if (indexOf == -1) { throw new Exception($"Event '{id}' not exists specified handler."); } list.RemoveAt(indexOf); if (list.Count == 0) { m_EventPool.Remove(id); } } /// /// 设置默认事件处理函数。 /// /// 要设置的默认事件处理函数。 public void SetDefaultHandler(EventHandler handler) { m_DefaultHandler = handler; } struct EventInfo { public object sender { get; } public GameEventArgs args { get; } public EventInfo(object sender, GameEventArgs args) { this.sender = sender; this.args = args; } } /// /// 抛出事件,这个操作是线程安全的,即使不在主线程中抛出,也可保证在主线程中回调事件处理函数,但事件会在抛出后的下一帧分发。 /// /// 事件源。 /// 事件参数。 public void Fire(object sender, GameEventArgs e) { if (e == null) { throw new Exception("Event is invalid."); } m_EventInfos.Enqueue(new EventInfo(sender, e)); } /// /// 抛出事件立即模式,这个操作不是线程安全的,事件会立刻分发。 /// /// 事件源。 /// 事件参数。 public void FireNow(object sender, GameEventArgs e) { if (e == null) { throw new Exception("Event is invalid."); } HandleEvent(sender, e); } /// /// 每帧调用 /// public void Update() { while (m_EventInfos.Count > 0) { var eventInfo = m_EventInfos.Dequeue(); HandleEvent(eventInfo.sender, eventInfo.args); } } /// /// 处理事件结点。 /// /// 事件源。 /// 事件参数。 private void HandleEvent(object sender, GameEventArgs e) { if (!m_EventPool.TryGetValue(e.Id, out var list) || list.Count == 0) { if (m_DefaultHandler != null) { m_DefaultHandler(sender, e); return; } else { return; Debug.LogWarning($"Event '{e.Id}' not allow no handler."); // throw new ArgumentException(string.Format("Event '{0}' not allow no handler.", e.Id)); } } foreach (var eventHandler in list) { _cache.Enqueue(eventHandler); } while (_cache.Count > 0) { var eventHandler = _cache.Dequeue(); eventHandler.Invoke(sender, e); } } } }