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