Files
BingoGrassland/Assets/BingoSun/Scripts/Keril/BaseDispatcher.cs
T

242 lines
7.2 KiB
C#
Raw Normal View History

2026-04-20 13:49:36 +08:00
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;
}
}
}