CTT/Server/Model/Game/Entity/Buff/BuffEventComponent.cs

97 lines
3.1 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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);
}
}
}