using System; using System.Collections.Generic; namespace Mono.Event { public class EventManager { 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 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); } } } }