97 lines
3.1 KiB
C#
97 lines
3.1 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
|
||
namespace ET
|
||
{
|
||
public class BuffEventComponent:Entity
|
||
{
|
||
private readonly Dictionary<Type, LinkedList<IEvent>> allEvents = new Dictionary<Type, LinkedList<IEvent>>();
|
||
|
||
/// <summary>
|
||
/// 缓存的结点字典
|
||
/// </summary>
|
||
private readonly Dictionary<Type, LinkedListNode<IEvent>> cachedNodes = new Dictionary<Type, LinkedListNode<IEvent>>();
|
||
|
||
/// <summary>
|
||
/// 临时结点字典
|
||
/// </summary>
|
||
private readonly Dictionary<Type, LinkedListNode<IEvent>> tempNodes = new Dictionary<Type, LinkedListNode<IEvent>>();
|
||
|
||
public void RegisterEvent(Type eventId, IEvent e)
|
||
{
|
||
if (!this.allEvents.ContainsKey(eventId))
|
||
{
|
||
this.allEvents.Add(eventId, new LinkedList<IEvent>());
|
||
}
|
||
|
||
this.allEvents[eventId].AddLast(e);
|
||
}
|
||
|
||
public void RemoveEvent(Type eventId, IEvent e)
|
||
{
|
||
if (cachedNodes.Count > 0)
|
||
{
|
||
foreach (KeyValuePair<Type, LinkedListNode<IEvent>> cachedNode in cachedNodes)
|
||
{
|
||
//预防极端情况,比如两个不同的事件id订阅了同一个事件处理者
|
||
if (cachedNode.Value != null && cachedNode.Key == eventId && cachedNode.Value.Value == e)
|
||
{
|
||
//注意这里添加的Handler是下一个
|
||
tempNodes.Add(cachedNode.Key, cachedNode.Value.Next);
|
||
}
|
||
}
|
||
|
||
//把临时结点字典中的目标元素值更新到缓存结点字典
|
||
if (tempNodes.Count > 0)
|
||
{
|
||
foreach (KeyValuePair<Type, LinkedListNode<IEvent>> cachedNode in tempNodes)
|
||
{
|
||
cachedNodes[cachedNode.Key] = cachedNode.Value;
|
||
}
|
||
|
||
//清除临时结点
|
||
tempNodes.Clear();
|
||
}
|
||
}
|
||
|
||
if (this.allEvents.ContainsKey(eventId))
|
||
{
|
||
this.allEvents[eventId].Remove(e);
|
||
}
|
||
}
|
||
|
||
public async ETTask Public<T>(T a)where T:struct
|
||
{
|
||
Type type = typeof(T);
|
||
if (!this.allEvents.TryGetValue(type, out LinkedList<IEvent> iEvents))
|
||
{
|
||
return;
|
||
}
|
||
|
||
LinkedListNode<IEvent> temp = iEvents.First;
|
||
|
||
while (temp != null)
|
||
{
|
||
try
|
||
{
|
||
this.cachedNodes[type] = temp.Next;
|
||
if (!( temp.Value is AEvent<T> aEvent))
|
||
{
|
||
Log.Error($"event error: { temp.Value.GetType().Name}");
|
||
continue;
|
||
}
|
||
await aEvent.Run(a);
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
Log.Error(e);
|
||
}
|
||
|
||
temp = this.cachedNodes[type];
|
||
}
|
||
|
||
this.cachedNodes.Remove(type);
|
||
}
|
||
}
|
||
}
|