using System; using System.Collections.Generic; using UnityEngine; namespace BingoBrain.Core { public class BaseMainThreadDispatcher : SingletonUnity where T : SingletonUnity where Param : class { private class MainThreadMsgClass { public Msg currMsgId; public Param currParam; } private Queue m_msgQueue = new Queue(); private Dictionary>> m_msgPriorityDict = new Dictionary>>(); private Dictionary>> m_msgDict = new Dictionary>>(); private Dictionary>> m_msgOnceDict = new Dictionary>>(); private object m_queueLock = new object(); private void Update() { if (m_msgQueue.Count <= 0) return; while (m_msgQueue.Count > 0) { MainThreadMsgClass msg; lock (m_queueLock) { msg = m_msgQueue.Dequeue(); } AutoDispatch(msg.currMsgId, msg.currParam); } } public void AddPriorityListener(Msg msgId, Action listener) { if (m_msgPriorityDict.ContainsKey(msgId)) { m_msgPriorityDict[msgId].Add(listener); } else { List> list = Uncc>.Get(); list.Add(listener); m_msgPriorityDict.Add(msgId, list); } } public void AddListener(Msg msgId, Action listener) { if (m_msgDict.ContainsKey(msgId)) { m_msgDict[msgId].Add(listener); } else { List> list = Uncc>.Get(); list.Add(listener); m_msgDict.Add(msgId, list); } } public void AddOnceListener(Msg msgId, Action listener) { if (m_msgOnceDict.ContainsKey(msgId)) { m_msgOnceDict[msgId].Add(listener); } else { List> list = Uncc>.Get(); list.Add(listener); m_msgOnceDict.Add(msgId, list); } } public void RemovePriorityListener(Msg msgId, Action listener) { if (m_msgPriorityDict.ContainsKey(msgId)) { List> list = m_msgPriorityDict[msgId]; 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.ContainsKey(msgId)) { List> list = m_msgDict[msgId]; if (list.Contains(listener)) { list.Remove(listener); if (list.Count == 0) { Uncc>.Release(list); m_msgDict.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) { if (!m_msgPriorityDict.ContainsKey(msgId) && !m_msgDict.ContainsKey(msgId) && !m_msgOnceDict.ContainsKey(msgId)) return; MainThreadMsgClass msg = new MainThreadMsgClass { currMsgId = msgId, currParam = param, }; lock (m_queueLock) { m_msgQueue.Enqueue(msg); } } private void AutoDispatch(Msg msgId, Param param) { InvokeMethods(m_msgPriorityDict, msgId, param); InvokeMethods(m_msgDict, 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; List> rawList = msgDict[msgId]; int funcCount = rawList.Count; if (funcCount == 1) { Action onEvent = rawList[0]; onEvent(param); return; } List> invokeFuncs = Uncc>.Get(); invokeFuncs.AddRange(rawList); for (int i = 0; i < funcCount; i++) { try { Action onEvent = invokeFuncs[i]; onEvent(param); } catch (Exception e) { Debug.LogError(e); } } Uncc>.Release(invokeFuncs); } public void Clear() { lock (m_queueLock) { m_msgQueue.Clear(); } m_msgPriorityDict.Clear(); m_msgDict.Clear(); m_msgOnceDict.Clear(); } protected override string ParentRootName { get { return OCConst.DispatcherGoName; } } protected override void OnDestroy() { base.OnDestroy(); m_msgPriorityDict.Clear(); m_msgDict.Clear(); m_msgOnceDict.Clear(); m_msgPriorityDict = null; m_msgDict = null; m_msgOnceDict = null; } } }