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}");
}
}
}
}
}