using System; using System.Collections.Concurrent; using System.Collections.Generic; using MrWu.Debug; namespace Server.Core { /// /// 多处理器派发器 /// /// /// /// public abstract class MultiHandleBaseDispatcher : SingleInstance where T : SingleInstance, new() where Param : class { private class EventData where Param1 : class { public Msg1 msg; public Param1 param; public EventData(Msg1 msg, Param1 param) { this.msg = msg; this.param = param; } } /// /// 下一帧要执行的事件 /// private ConcurrentQueue> nextEvent = new ConcurrentQueue>(); private Queue>> m_eventQueue = new Queue>>(); private Dictionary>> m_msgDict = new Dictionary>>(); /// /// 普通事件派发器 /// /// /// public void AddListener(Msg msgId, Action listener) { if (m_msgDict.ContainsKey(msgId)) { m_msgDict[msgId].Add(listener); } else { List> list = new List>(); list.Add(listener); m_msgDict.Add(msgId, list); } } 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) { m_msgDict.Remove(msgId); } } } } public void Dispatch(Msg msgId, Param param = null) { InvokeMethods(m_msgDict, msgId, param); } public void DispatchNextFrame(Msg msgId, Param param = null) { nextEvent.Enqueue(new EventData(msgId, param)); } private List> GetEmptyEventList() { if (m_eventQueue.Count > 0) { return m_eventQueue.Dequeue(); } return new List>(); } 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 = GetEmptyEventList(); invokeFuncs.AddRange(rawList); for (int i = 0; i < funcCount; i++) { try { Action onEvent = invokeFuncs[i]; onEvent(param); } catch (Exception e) { Debug.Error($"MuiltHandleError MsgId:{msgId} Error:{e}"); } } invokeFuncs.Clear(); m_eventQueue.Enqueue(invokeFuncs); } public void Update() { while (nextEvent.TryDequeue(out EventData eventData)) { try { Dispatch(eventData.msg, eventData.param); } catch (Exception e) { Debug.Error($"事件执行错误:{eventData.msg},{e.Message}"); } } } } }