using System; using UnityEngine; using System.Collections.Generic; namespace BingoBrain.Core { public abstract class BaseDispatcher : IDisposable where T : class, new() where Param : class { private static T m_instance; public static T Instance { get { if (m_instance == null) { m_instance = new T(); } return m_instance; } } private Dictionary>> m_msgPriorityDict = new(); private Dictionary>> m_msgDict = new(); private Dictionary>> m_msgFinallyDict = new(); private Dictionary>> m_msgOnceDict = new(); public void AddPriorityListener(Msg msgId, Action listener) { if (m_msgPriorityDict.TryGetValue(msgId, out var value)) { value.Add(listener); } else { var list = Uncc>.Get(); list.Add(listener); m_msgPriorityDict.Add(msgId, list); } } public void AddListener(Msg msgId, Action listener) { if (m_msgDict.TryGetValue(msgId, out var value)) { value.Add(listener); } else { var list = Uncc>.Get(); list.Add(listener); m_msgDict.Add(msgId, list); } } public void AddFinallyListener(Msg msgId, Action listener) { if (m_msgFinallyDict.TryGetValue(msgId, out var value)) { value.Add(listener); } else { var list = Uncc>.Get(); list.Add(listener); m_msgFinallyDict.Add(msgId, list); } } public void AddOnceListener(Msg msgId, Action listener) { if (m_msgOnceDict.TryGetValue(msgId, out var value)) { value.Add(listener); } else { var list = Uncc>.Get(); list.Add(listener); m_msgOnceDict.Add(msgId, list); } } private bool ContainsListener(Msg msgId, Action listener, Dictionary>> msgDict) { return msgDict.TryGetValue(msgId, out var list) && list.Contains(listener); } private bool ContainsPriorityListener(Msg msgId, Action listener) { return ContainsListener(msgId, listener, m_msgPriorityDict); } private bool ContainsListener(Msg msgId, Action listener) { return ContainsListener(msgId, listener, m_msgDict); } private bool ContainsFinallyListener(Msg msgId, Action listener) { return ContainsListener(msgId, listener, m_msgFinallyDict); } private bool ContainsOnceListener(Msg msgId, Action listener) { return ContainsListener(msgId, listener, m_msgOnceDict); } public void RemovePriorityListener(Msg msgId, Action listener) { if (m_msgPriorityDict.TryGetValue(msgId, out var list)) { if (list.Contains(listener)) { list.Remove(listener); if (list.Count == 0) { Uncc>.Release(list); m_msgPriorityDict.Remove(msgId); } } } } public void RemoveListener(Msg msgId, Action listener) { if (m_msgDict.TryGetValue(msgId, out var list)) { if (list.Contains(listener)) { list.Remove(listener); if (list.Count == 0) { Uncc>.Release(list); m_msgDict.Remove(msgId); } } } } public void RemoveFinallyListener(Msg msgId, Action listener) { if (m_msgFinallyDict.TryGetValue(msgId, out var list)) { if (list.Contains(listener)) { list.Remove(listener); if (list.Count == 0) { Uncc>.Release(list); m_msgFinallyDict.Remove(msgId); } } } } public void RemoveOnceListener(Msg msgId, Action listener) { if (m_msgOnceDict.ContainsKey(msgId)) { List> list = m_msgOnceDict[msgId]; if (list.Contains(listener)) { list.Remove(listener); if (list.Count == 0) { Uncc>.Release(list); m_msgOnceDict.Remove(msgId); } } } } public void Dispatch(Msg msgId, Param param = null) { InvokeMethods(m_msgPriorityDict, msgId, param); InvokeMethods(m_msgDict, msgId, param); InvokeMethods(m_msgFinallyDict, msgId, param); InvokeMethods(m_msgOnceDict, msgId, param); if (m_msgOnceDict.ContainsKey(msgId)) { Uncc>.Release(m_msgOnceDict[msgId]); m_msgOnceDict.Remove(msgId); } } private void InvokeMethods(Dictionary>> msgDict, Msg msgId, Param param) { if (!msgDict.ContainsKey(msgId)) return; var rawList = msgDict[msgId]; int funcCount = rawList.Count; if (funcCount == 1) { Action onEvent = rawList[0]; onEvent(param); return; } var invokeFuncs = Uncc>.Get(); invokeFuncs.AddRange(rawList); for (var i = 0; i < funcCount; i++) { try { var onEvent = invokeFuncs[i]; onEvent(param); } catch (Exception e) { Debug.LogError(e); } } Uncc>.Release(invokeFuncs); } public void Clear() { m_msgPriorityDict.Clear(); m_msgDict.Clear(); m_msgFinallyDict.Clear(); m_msgOnceDict.Clear(); } public void Dispose() { m_instance = null; m_msgPriorityDict.Clear(); m_msgDict.Clear(); m_msgFinallyDict.Clear(); m_msgOnceDict.Clear(); m_msgPriorityDict = null; m_msgDict = null; m_msgFinallyDict = null; m_msgOnceDict = null; } } }