using System; using System.Collections.Generic; using UnityEngine; namespace RedHotRoast { 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 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)) { ListPool>.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 = ListPool>.Get(); invokeFuncs.AddRange(rawList); for (int i = 0; i < funcCount; i++) { try { Action onEvent = invokeFuncs[i]; onEvent(param); } catch (Exception e) { Debug.LogError(e); } } ListPool>.Release(invokeFuncs); } protected override string ParentRootName { get { return AppObjConst.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; } } }