From 6ee515e8c5981cc91ab2974a5068b434718435ed Mon Sep 17 00:00:00 2001
From: ALEXTANG <574809918@qq.com>
Date: Thu, 26 Oct 2023 10:28:05 +0800
Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=B1=80=E9=83=A8=E5=8D=95?=
=?UTF-8?q?=E4=BD=8D=E4=BA=8B=E4=BB=B6=E5=88=86=E5=8F=91=E5=99=A8=E7=9A=84?=
=?UTF-8?q?=E5=B0=81=E8=A3=85=E3=80=82?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
增加局部单位事件分发器的封装。
---
.../Core/GameEvent/ActorEventDispatcher.cs | 614 ++++++++++++++++++
.../GameEvent/ActorEventDispatcher.cs.meta | 3 +
2 files changed, 617 insertions(+)
create mode 100644 UnityProject/Assets/TEngine/Runtime/Core/GameEvent/ActorEventDispatcher.cs
create mode 100644 UnityProject/Assets/TEngine/Runtime/Core/GameEvent/ActorEventDispatcher.cs.meta
diff --git a/UnityProject/Assets/TEngine/Runtime/Core/GameEvent/ActorEventDispatcher.cs b/UnityProject/Assets/TEngine/Runtime/Core/GameEvent/ActorEventDispatcher.cs
new file mode 100644
index 00000000..e446596f
--- /dev/null
+++ b/UnityProject/Assets/TEngine/Runtime/Core/GameEvent/ActorEventDispatcher.cs
@@ -0,0 +1,614 @@
+using System;
+using System.Collections.Generic;
+
+#region Class Documentation
+/************************************************************************************************************
+Class Name: ActorEventDispatcher.cs 局部单位事件分发器。
+Type: Actor, Event
+Example:
+ private ActorEventDispatcher _event;
+
+ ///
+ /// 局部事件管理器。
+ /// 只分发和监听这个Event内部的事件
+ ///
+ public ActorEventDispatcher Event => _event ??= MemoryPool.Acquire();
+
+ // owner局部发送事件。
+ owner.Event.Send(eventId,xxx);
+
+ // owner监听自身事件并绑定持有对象为owner。 比如是组件的情况下。移除时调用RemoveAllListenerByOwner(owner)会根据持有对象(组件)移除。
+ owner.Event.AddEventListener(eventId,xxx,owner);
+************************************************************************************************************/
+#endregion
+
+namespace TEngine
+{
+ ///
+ /// 局部单位事件分发器。
+ ///
+ public class ActorEventDispatcher : IMemory
+ {
+ ///
+ /// 所有事件。
+ ///
+ private readonly Dictionary> _allEventListenerMap;
+
+ ///
+ /// 用于标记一个事件是不是正在处理。
+ ///
+ private readonly List _processEventList;
+
+ ///
+ /// 用于标记一个事件是不是被移除。
+ ///
+ private readonly List _delayDeleteEventList;
+
+ public ActorEventDispatcher()
+ {
+ _processEventList = new List();
+ _delayDeleteEventList = new List();
+ _allEventListenerMap = new Dictionary>();
+ }
+
+ ///
+ /// 移除所有事件监听。
+ ///
+ public void DestroyAllEventListener()
+ {
+ var itr = _allEventListenerMap.GetEnumerator();
+ while (itr.MoveNext())
+ {
+ var kv = itr.Current;
+ kv.Value.Clear();
+ }
+
+ _processEventList.Clear();
+ _delayDeleteEventList.Clear();
+ itr.Dispose();
+ }
+
+ ///
+ /// 延迟移除事件。
+ ///
+ ///
+ private void AddDelayDelete(int eventId)
+ {
+ if (!_delayDeleteEventList.Contains(eventId))
+ {
+ _delayDeleteEventList.Add(eventId);
+ Log.Info("delay delete eventId[{0}]", eventId);
+ }
+ }
+
+ ///
+ /// 如果找到eventId对应的监听,删除所有标记为delete的监听。
+ ///
+ /// 事件Id。
+ private void CheckDelayDelete(int eventId)
+ {
+ if (_delayDeleteEventList.Contains(eventId))
+ {
+ if (_allEventListenerMap.TryGetValue(eventId, out var listListener))
+ {
+ for (int i = 0; i < listListener.Count; i++)
+ {
+ if (listListener[i].IsDeleted)
+ {
+ Log.Info("remove delay delete eventId[{0}]", eventId);
+ listListener[i] = listListener[^1];
+ listListener.RemoveAt(listListener.Count - 1);
+ i--;
+ }
+ }
+ }
+
+ _delayDeleteEventList.Remove(eventId);
+ }
+ }
+
+ ///
+ /// 发送事件。
+ ///
+ /// 事件Id。
+ public void SendEvent(int eventId)
+ {
+ if (_allEventListenerMap.TryGetValue(eventId, out var listListener))
+ {
+ _processEventList.Add(eventId);
+#if UNITY_EDITOR
+ int iEventCnt = _processEventList.Count;
+#endif
+
+ var count = listListener.Count;
+ for (int i = 0; i < count; i++)
+ {
+ var node = listListener[i];
+ if (node.IsDeleted)
+ {
+ continue;
+ }
+
+ if (listListener[i].Callback is Action callBack)
+ {
+ callBack();
+ }
+ else
+ {
+ Log.Fatal("Invalid event data type: {0}", eventId);
+ }
+ }
+
+
+#if UNITY_EDITOR
+ Log.Assert(iEventCnt == _processEventList.Count);
+ Log.Assert(eventId == _processEventList[^1]);
+#endif
+ _processEventList.RemoveAt(_processEventList.Count - 1);
+
+ CheckDelayDelete(eventId);
+ }
+ }
+
+ ///
+ /// 发送事件。
+ ///
+ /// 事件Id。
+ /// 事件参数。
+ /// 事件参数类型1。
+ public void SendEvent(int eventId, TArg1 arg1)
+ {
+ if (_allEventListenerMap.TryGetValue(eventId, out var listListener))
+ {
+ _processEventList.Add(eventId);
+#if UNITY_EDITOR
+ int iEventCnt = _processEventList.Count;
+#endif
+
+ var count = listListener.Count;
+ for (int i = 0; i < count; i++)
+ {
+ var node = listListener[i];
+ if (node.IsDeleted)
+ {
+ continue;
+ }
+
+ if (listListener[i].Callback is Action callBack)
+ {
+ callBack(arg1);
+ }
+ else
+ {
+ Log.Fatal("Invalid event data type: {0}", eventId);
+ }
+ }
+
+
+#if UNITY_EDITOR
+ Log.Assert(iEventCnt == _processEventList.Count);
+ Log.Assert(eventId == _processEventList[^1]);
+#endif
+
+ _processEventList.RemoveAt(_processEventList.Count - 1);
+
+ CheckDelayDelete(eventId);
+ }
+ }
+
+ ///
+ /// 发送事件。
+ ///
+ /// 事件Id。
+ /// 事件参数1。
+ /// 事件参数2。
+ /// 事件参数类型1。
+ /// 事件参数类型2。
+ public void SendEvent(int eventId, TArg1 arg1, TArg2 arg2)
+ {
+ if (_allEventListenerMap.TryGetValue(eventId, out var listListener))
+ {
+ _processEventList.Add(eventId);
+#if UNITY_EDITOR
+ int iEventCnt = _processEventList.Count;
+#endif
+
+ var count = listListener.Count;
+ for (int i = 0; i < count; i++)
+ {
+ var node = listListener[i];
+ if (node.IsDeleted)
+ {
+ continue;
+ }
+
+ if (listListener[i].Callback is Action callBack)
+ {
+ callBack(arg1, arg2);
+ }
+ else
+ {
+ Log.Fatal("Invalid event data type: {0}", eventId);
+ }
+ }
+
+
+#if UNITY_EDITOR
+ Log.Assert(iEventCnt == _processEventList.Count);
+ Log.Assert(eventId == _processEventList[^1]);
+#endif
+ _processEventList.RemoveAt(_processEventList.Count - 1);
+
+ CheckDelayDelete(eventId);
+ }
+ }
+
+ ///
+ /// 发送事件。
+ ///
+ /// 事件Id。
+ /// 事件参数1。
+ /// 事件参数2。
+ /// 事件参数3。
+ /// 事件参数类型1。
+ /// 事件参数类型2。
+ /// 事件参数类型3。
+ public void SendEvent(int eventId, TArg1 arg1, TArg2 arg2, TArg3 arg3)
+ {
+ if (_allEventListenerMap.TryGetValue(eventId, out var listListener))
+ {
+ _processEventList.Add(eventId);
+#if UNITY_EDITOR
+ int iEventCnt = _processEventList.Count;
+#endif
+
+ var count = listListener.Count;
+ for (int i = 0; i < count; i++)
+ {
+ var node = listListener[i];
+ if (node.IsDeleted)
+ {
+ continue;
+ }
+
+ if (node.Callback is Action callBack)
+ {
+ callBack(arg1, arg2, arg3);
+ }
+ else
+ {
+ Log.Fatal("Invalid event data type: {0}", eventId);
+ }
+ }
+
+
+#if UNITY_EDITOR
+ Log.Assert(iEventCnt == _processEventList.Count);
+ Log.Assert(eventId == _processEventList[^1]);
+#endif
+ _processEventList.RemoveAt(_processEventList.Count - 1);
+
+ CheckDelayDelete(eventId);
+ }
+ }
+
+ ///
+ /// 发送事件。
+ ///
+ /// 事件Id。
+ /// 事件参数1。
+ /// 事件参数2。
+ /// 事件参数3。
+ /// 事件参数4。
+ /// 事件参数类型1。
+ /// 事件参数类型2。
+ /// 事件参数类型3。
+ /// 事件参数类型4。
+ public void SendEvent(int eventId, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4)
+ {
+ if (_allEventListenerMap.TryGetValue(eventId, out var listListener))
+ {
+ _processEventList.Add(eventId);
+#if UNITY_EDITOR
+ int iEventCnt = _processEventList.Count;
+#endif
+
+
+ var count = listListener.Count;
+ for (int i = 0; i < count; i++)
+ {
+ var node = listListener[i];
+ if (node.IsDeleted)
+ {
+ continue;
+ }
+
+ if (listListener[i].Callback is Action callBack)
+ {
+ callBack(arg1, arg2, arg3, arg4);
+ }
+ else
+ {
+ Log.Fatal("Invalid event data type: {0}", eventId);
+ }
+ }
+
+
+#if UNITY_EDITOR
+ Log.Assert(iEventCnt == _processEventList.Count);
+ Log.Assert(eventId == _processEventList[^1]);
+#endif
+ _processEventList.RemoveAt(_processEventList.Count - 1);
+
+ CheckDelayDelete(eventId);
+ }
+ }
+
+ ///
+ /// 增加事件监听。
+ ///
+ /// 事件Id。
+ /// 事件回调。
+ /// 持有者Tag。
+ public void AddEventListener(int eventId, Action eventCallback, object owner)
+ {
+ AddEventListenerImp(eventId, eventCallback, owner);
+ }
+
+ ///
+ /// 增加事件监听。
+ ///
+ /// 事件Id。
+ /// 事件回调。
+ /// 持有者Tag。
+ /// 事件参数类型1。
+ public void AddEventListener(int eventId, Action eventCallback, object owner)
+ {
+ AddEventListenerImp(eventId, eventCallback, owner);
+ }
+
+ ///
+ /// 增加事件监听。
+ ///
+ /// 事件Id。
+ /// 事件回调。
+ /// 持有者Tag。
+ /// 事件参数类型1。
+ /// 事件参数类型2。
+ public void AddEventListener(int eventId, Action eventCallback, object owner)
+ {
+ AddEventListenerImp(eventId, eventCallback, owner);
+ }
+
+ ///
+ /// 增加事件监听。
+ ///
+ /// 事件Id。
+ /// 事件回调。
+ /// 持有者Tag。
+ /// 事件参数类型1。
+ /// 事件参数类型2。
+ /// 事件参数类型3。
+ public void AddEventListener(int eventId, Action eventCallback, object owner)
+ {
+ AddEventListenerImp(eventId, eventCallback, owner);
+ }
+
+ ///
+ /// 增加事件监听。
+ ///
+ /// 事件Id。
+ /// 事件回调。
+ /// 持有者Tag。
+ /// 事件参数类型1。
+ /// 事件参数类型2。
+ /// 事件参数类型3。
+ /// 事件参数类型4。
+ public void AddEventListener(int eventId, Action eventCallback, object owner)
+ {
+ AddEventListenerImp(eventId, eventCallback, owner);
+ }
+
+ ///
+ /// 增加事件监听具体实现。
+ ///
+ /// 事件Id。
+ /// 事件回调。
+ /// 持有者Tag。
+ private void AddEventListenerImp(int eventId, Delegate listener, object owner)
+ {
+ if (!_allEventListenerMap.TryGetValue(eventId, out var listListener))
+ {
+ listListener = new List();
+ _allEventListenerMap.Add(eventId, listListener);
+ }
+
+ var existNode = listListener.Find((node) => node.Callback == listener);
+ if (existNode != null)
+ {
+ if (existNode.IsDeleted)
+ {
+ existNode.IsDeleted = false;
+ Log.Warning("AddEvent hashId deleted, repeat add: {0}", eventId);
+ return;
+ }
+
+ Log.Fatal("AddEvent hashId repeated: {0}", eventId);
+ return;
+ }
+
+ listListener.Add(new EventRegInfo(listener, owner));
+ }
+
+ ///
+ /// 通过持有者Tag移除监听。
+ ///
+ /// 持有者Tag。
+ public void RemoveAllListenerByOwner(object owner)
+ {
+ var itr = _allEventListenerMap.GetEnumerator();
+ while (itr.MoveNext())
+ {
+ var kv = itr.Current;
+ var list = kv.Value;
+
+ int eventId = kv.Key;
+ bool isProcessing = _processEventList.Contains(eventId);
+ bool delayDeleted = false;
+
+ for (int i = 0; i < list.Count; i++)
+ {
+ var regInfo = list[i];
+ if (regInfo.Owner == owner)
+ {
+ if (isProcessing)
+ {
+ regInfo.IsDeleted = true;
+ delayDeleted = true;
+ }
+ else
+ {
+ list[i] = list[^1];
+ list.RemoveAt(list.Count - 1);
+ i--;
+ }
+ }
+ }
+
+ if (delayDeleted)
+ {
+ AddDelayDelete(eventId);
+ }
+ }
+
+ itr.Dispose();
+ }
+
+ ///
+ /// 移除事件监听。
+ ///
+ /// 事件Id。
+ /// 消息回调。
+ public void RemoveEventListener(int eventId, Action eventCallback)
+ {
+ RemoveEventListenerImp(eventId, eventCallback);
+ }
+
+ ///
+ /// 移除事件监听。
+ ///
+ /// 事件Id。
+ /// 消息回调。
+ /// 参数类型1。
+ public void RemoveEventListener(int eventId, Action eventCallback)
+ {
+ RemoveEventListenerImp(eventId, eventCallback);
+ }
+
+ ///
+ /// 移除事件监听。
+ ///
+ /// 事件Id。
+ /// 消息回调。
+ /// 参数类型1。
+ /// 参数类型2。
+ public void RemoveEventListener(int eventId, Action eventCallback)
+ {
+ RemoveEventListenerImp(eventId, eventCallback);
+ }
+
+ ///
+ /// 移除事件监听。
+ ///
+ /// 事件Id。
+ /// 消息回调。
+ /// 参数类型1。
+ /// 参数类型2。
+ /// 参数类型3。
+ public void RemoveEventListener(int eventId, Action eventCallback)
+ {
+ RemoveEventListenerImp(eventId, eventCallback);
+ }
+
+ ///
+ /// 移除事件监听。
+ ///
+ /// 事件Id。
+ /// 消息回调。
+ /// 参数类型1。
+ /// 参数类型2。
+ /// 参数类型3。
+ /// 参数类型4。
+ public void RemoveEventListener(int eventId, Action eventCallback)
+ {
+ RemoveEventListenerImp(eventId, eventCallback);
+ }
+
+ ///
+ /// 删除监听,如果是正在处理的监听则标记为删除
+ ///
+ /// 事件Id。
+ /// 事件监听。
+ protected void RemoveEventListenerImp(int eventId, Delegate listener)
+ {
+ if (_allEventListenerMap.TryGetValue(eventId, out var listListener))
+ {
+ bool isProcessing = _processEventList.Contains(eventId);
+ if (!isProcessing)
+ {
+ listListener.RemoveAll(node => node.Callback == listener);
+ }
+ else
+ {
+ int listenCnt = listListener.Count;
+ for (int i = 0; i < listenCnt; i++)
+ {
+ var node = listListener[i];
+ if (node.Callback == listener)
+ {
+ node.IsDeleted = true;
+ AddDelayDelete(eventId);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ ///
+ /// 清除回收接口。
+ ///
+ public void Clear()
+ {
+ DestroyAllEventListener();
+ }
+ }
+
+ ///
+ /// 事件注册信息。
+ ///
+ public class EventRegInfo
+ {
+ ///
+ /// 事件回调。
+ ///
+ public readonly Delegate Callback;
+
+ ///
+ /// 事件持有者。
+ ///
+ public readonly object Owner;
+
+ ///
+ /// 事件是否删除。
+ ///
+ public bool IsDeleted;
+
+ public EventRegInfo(Delegate callback, object owner)
+ {
+ this.Callback = callback;
+ Owner = owner;
+ IsDeleted = false;
+ }
+ }
+}
\ No newline at end of file
diff --git a/UnityProject/Assets/TEngine/Runtime/Core/GameEvent/ActorEventDispatcher.cs.meta b/UnityProject/Assets/TEngine/Runtime/Core/GameEvent/ActorEventDispatcher.cs.meta
new file mode 100644
index 00000000..13ce0f62
--- /dev/null
+++ b/UnityProject/Assets/TEngine/Runtime/Core/GameEvent/ActorEventDispatcher.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 222c2a26f3b14d42950d0e9a10b61b38
+timeCreated: 1673511406
\ No newline at end of file