224 lines
6.6 KiB
C#
224 lines
6.6 KiB
C#
|
|
using System;
|
||
|
|
using System.Collections.Generic;
|
||
|
|
using UnityEngine;
|
||
|
|
|
||
|
|
namespace BingoBrain.Core
|
||
|
|
{
|
||
|
|
public class BaseMainThreadDispatcher<T, Msg, Param> : SingletonUnity<T>
|
||
|
|
where T : SingletonUnity<T>
|
||
|
|
where Param : class
|
||
|
|
{
|
||
|
|
private class MainThreadMsgClass
|
||
|
|
{
|
||
|
|
public Msg currMsgId;
|
||
|
|
public Param currParam;
|
||
|
|
}
|
||
|
|
|
||
|
|
private Queue<MainThreadMsgClass> m_msgQueue = new Queue<MainThreadMsgClass>();
|
||
|
|
private Dictionary<Msg, List<Action<Param>>> m_msgPriorityDict = new Dictionary<Msg, List<Action<Param>>>();
|
||
|
|
private Dictionary<Msg, List<Action<Param>>> m_msgDict = new Dictionary<Msg, List<Action<Param>>>();
|
||
|
|
private Dictionary<Msg, List<Action<Param>>> m_msgOnceDict = new Dictionary<Msg, List<Action<Param>>>();
|
||
|
|
|
||
|
|
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<Param> listener)
|
||
|
|
{
|
||
|
|
if (m_msgPriorityDict.ContainsKey(msgId))
|
||
|
|
{
|
||
|
|
m_msgPriorityDict[msgId].Add(listener);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
List<Action<Param>> list = Uncc<Action<Param>>.Get();
|
||
|
|
list.Add(listener);
|
||
|
|
m_msgPriorityDict.Add(msgId, list);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public void AddListener(Msg msgId, Action<Param> listener)
|
||
|
|
{
|
||
|
|
if (m_msgDict.ContainsKey(msgId))
|
||
|
|
{
|
||
|
|
m_msgDict[msgId].Add(listener);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
List<Action<Param>> list = Uncc<Action<Param>>.Get();
|
||
|
|
list.Add(listener);
|
||
|
|
m_msgDict.Add(msgId, list);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public void AddOnceListener(Msg msgId, Action<Param> listener)
|
||
|
|
{
|
||
|
|
if (m_msgOnceDict.ContainsKey(msgId))
|
||
|
|
{
|
||
|
|
m_msgOnceDict[msgId].Add(listener);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
List<Action<Param>> list = Uncc<Action<Param>>.Get();
|
||
|
|
list.Add(listener);
|
||
|
|
m_msgOnceDict.Add(msgId, list);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public void RemovePriorityListener(Msg msgId, Action<Param> listener)
|
||
|
|
{
|
||
|
|
if (m_msgPriorityDict.ContainsKey(msgId))
|
||
|
|
{
|
||
|
|
List<Action<Param>> list = m_msgPriorityDict[msgId];
|
||
|
|
if (list.Contains(listener))
|
||
|
|
{
|
||
|
|
list.Remove(listener);
|
||
|
|
if (list.Count == 0)
|
||
|
|
{
|
||
|
|
Uncc<Action<Param>>.Release(list);
|
||
|
|
m_msgPriorityDict.Remove(msgId);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public void RemoveListener(Msg msgId, Action<Param> listener)
|
||
|
|
{
|
||
|
|
if (m_msgDict.ContainsKey(msgId))
|
||
|
|
{
|
||
|
|
List<Action<Param>> list = m_msgDict[msgId];
|
||
|
|
if (list.Contains(listener))
|
||
|
|
{
|
||
|
|
list.Remove(listener);
|
||
|
|
if (list.Count == 0)
|
||
|
|
{
|
||
|
|
Uncc<Action<Param>>.Release(list);
|
||
|
|
m_msgDict.Remove(msgId);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public void RemoveOnceListener(Msg msgId, Action<Param> listener)
|
||
|
|
{
|
||
|
|
if (m_msgOnceDict.ContainsKey(msgId))
|
||
|
|
{
|
||
|
|
List<Action<Param>> list = m_msgOnceDict[msgId];
|
||
|
|
if (list.Contains(listener))
|
||
|
|
{
|
||
|
|
list.Remove(listener);
|
||
|
|
if (list.Count == 0)
|
||
|
|
{
|
||
|
|
Uncc<Action<Param>>.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<Action<Param>>.Release(m_msgOnceDict[msgId]);
|
||
|
|
m_msgOnceDict.Remove(msgId);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private void InvokeMethods(Dictionary<Msg, List<Action<Param>>> msgDict, Msg msgId, Param param)
|
||
|
|
{
|
||
|
|
if (!msgDict.ContainsKey(msgId)) return;
|
||
|
|
|
||
|
|
List<Action<Param>> rawList = msgDict[msgId];
|
||
|
|
int funcCount = rawList.Count;
|
||
|
|
if (funcCount == 1)
|
||
|
|
{
|
||
|
|
Action<Param> onEvent = rawList[0];
|
||
|
|
onEvent(param);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
List<Action<Param>> invokeFuncs = Uncc<Action<Param>>.Get();
|
||
|
|
invokeFuncs.AddRange(rawList);
|
||
|
|
for (int i = 0; i < funcCount; i++)
|
||
|
|
{
|
||
|
|
try
|
||
|
|
{
|
||
|
|
Action<Param> onEvent = invokeFuncs[i];
|
||
|
|
onEvent(param);
|
||
|
|
}
|
||
|
|
catch (Exception e)
|
||
|
|
{
|
||
|
|
Debug.LogError(e);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
Uncc<Action<Param>>.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;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|