242 lines
7.2 KiB
C#
242 lines
7.2 KiB
C#
using System;
|
|
using UnityEngine;
|
|
using System.Collections.Generic;
|
|
|
|
namespace BingoBrain.Core
|
|
{
|
|
public abstract class BaseDispatcher<T, Msg, Param> : IDisposable where T : class, new() where Param : class
|
|
{
|
|
private static T m_instance;
|
|
|
|
public static T Instance
|
|
{
|
|
get
|
|
{
|
|
if (m_instance == null)
|
|
{
|
|
m_instance = new T();
|
|
}
|
|
|
|
return m_instance;
|
|
}
|
|
}
|
|
|
|
private Dictionary<Msg, List<Action<Param>>> m_msgPriorityDict = new();
|
|
private Dictionary<Msg, List<Action<Param>>> m_msgDict = new();
|
|
private Dictionary<Msg, List<Action<Param>>> m_msgFinallyDict = new();
|
|
private Dictionary<Msg, List<Action<Param>>> m_msgOnceDict = new();
|
|
|
|
public void AddPriorityListener(Msg msgId, Action<Param> listener)
|
|
{
|
|
if (m_msgPriorityDict.TryGetValue(msgId, out var value))
|
|
{
|
|
value.Add(listener);
|
|
}
|
|
else
|
|
{
|
|
var list = Uncc<Action<Param>>.Get();
|
|
list.Add(listener);
|
|
m_msgPriorityDict.Add(msgId, list);
|
|
}
|
|
}
|
|
|
|
public void AddListener(Msg msgId, Action<Param> listener)
|
|
{
|
|
if (m_msgDict.TryGetValue(msgId, out var value))
|
|
{
|
|
value.Add(listener);
|
|
}
|
|
else
|
|
{
|
|
var list = Uncc<Action<Param>>.Get();
|
|
list.Add(listener);
|
|
m_msgDict.Add(msgId, list);
|
|
}
|
|
}
|
|
|
|
public void AddFinallyListener(Msg msgId, Action<Param> listener)
|
|
{
|
|
if (m_msgFinallyDict.TryGetValue(msgId, out var value))
|
|
{
|
|
value.Add(listener);
|
|
}
|
|
else
|
|
{
|
|
var list = Uncc<Action<Param>>.Get();
|
|
list.Add(listener);
|
|
m_msgFinallyDict.Add(msgId, list);
|
|
}
|
|
}
|
|
|
|
public void AddOnceListener(Msg msgId, Action<Param> listener)
|
|
{
|
|
if (m_msgOnceDict.TryGetValue(msgId, out var value))
|
|
{
|
|
value.Add(listener);
|
|
}
|
|
else
|
|
{
|
|
var list = Uncc<Action<Param>>.Get();
|
|
list.Add(listener);
|
|
m_msgOnceDict.Add(msgId, list);
|
|
}
|
|
}
|
|
|
|
private bool ContainsListener(Msg msgId, Action<Param> listener, Dictionary<Msg, List<Action<Param>>> msgDict)
|
|
{
|
|
return msgDict.TryGetValue(msgId, out var list) && list.Contains(listener);
|
|
}
|
|
|
|
private bool ContainsPriorityListener(Msg msgId, Action<Param> listener)
|
|
{
|
|
return ContainsListener(msgId, listener, m_msgPriorityDict);
|
|
}
|
|
|
|
private bool ContainsListener(Msg msgId, Action<Param> listener)
|
|
{
|
|
return ContainsListener(msgId, listener, m_msgDict);
|
|
}
|
|
|
|
private bool ContainsFinallyListener(Msg msgId, Action<Param> listener)
|
|
{
|
|
return ContainsListener(msgId, listener, m_msgFinallyDict);
|
|
}
|
|
|
|
private bool ContainsOnceListener(Msg msgId, Action<Param> listener)
|
|
{
|
|
return ContainsListener(msgId, listener, m_msgOnceDict);
|
|
}
|
|
|
|
public void RemovePriorityListener(Msg msgId, Action<Param> listener)
|
|
{
|
|
if (m_msgPriorityDict.TryGetValue(msgId, out var list))
|
|
{
|
|
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.TryGetValue(msgId, out var list))
|
|
{
|
|
if (list.Contains(listener))
|
|
{
|
|
list.Remove(listener);
|
|
if (list.Count == 0)
|
|
{
|
|
Uncc<Action<Param>>.Release(list);
|
|
m_msgDict.Remove(msgId);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public void RemoveFinallyListener(Msg msgId, Action<Param> listener)
|
|
{
|
|
if (m_msgFinallyDict.TryGetValue(msgId, out var list))
|
|
{
|
|
if (list.Contains(listener))
|
|
{
|
|
list.Remove(listener);
|
|
if (list.Count == 0)
|
|
{
|
|
Uncc<Action<Param>>.Release(list);
|
|
m_msgFinallyDict.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)
|
|
{
|
|
InvokeMethods(m_msgPriorityDict, msgId, param);
|
|
InvokeMethods(m_msgDict, msgId, param);
|
|
InvokeMethods(m_msgFinallyDict, 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;
|
|
|
|
var rawList = msgDict[msgId];
|
|
int funcCount = rawList.Count;
|
|
if (funcCount == 1)
|
|
{
|
|
Action<Param> onEvent = rawList[0];
|
|
onEvent(param);
|
|
return;
|
|
}
|
|
|
|
var invokeFuncs = Uncc<Action<Param>>.Get();
|
|
invokeFuncs.AddRange(rawList);
|
|
for (var i = 0; i < funcCount; i++)
|
|
{
|
|
try
|
|
{
|
|
var onEvent = invokeFuncs[i];
|
|
onEvent(param);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Debug.LogError(e);
|
|
}
|
|
}
|
|
|
|
Uncc<Action<Param>>.Release(invokeFuncs);
|
|
}
|
|
|
|
public void Clear()
|
|
{
|
|
m_msgPriorityDict.Clear();
|
|
m_msgDict.Clear();
|
|
m_msgFinallyDict.Clear();
|
|
m_msgOnceDict.Clear();
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
m_instance = null;
|
|
|
|
m_msgPriorityDict.Clear();
|
|
m_msgDict.Clear();
|
|
m_msgFinallyDict.Clear();
|
|
m_msgOnceDict.Clear();
|
|
m_msgPriorityDict = null;
|
|
m_msgDict = null;
|
|
m_msgFinallyDict = null;
|
|
m_msgOnceDict = null;
|
|
}
|
|
}
|
|
} |