CodeLiturgy.Dashboard/CodeLiturgy/Core/Events/EventManagerAsync.cs

149 lines
5.1 KiB
C#
Raw Permalink Normal View History

2021-12-06 02:49:27 +03:00
using System;
2022-09-10 00:33:17 +03:00
using System.Collections.Concurrent;
2022-08-13 08:34:20 +03:00
using System.Collections.Generic;
2021-12-06 02:49:27 +03:00
namespace BlueWest.Tools
{
public struct EventManagerAsync
{
2022-09-10 00:33:17 +03:00
private static readonly ConcurrentDictionary<Type, List<EventListenerBaseAsync>> _subscribersList;
2021-12-06 02:49:27 +03:00
static EventManagerAsync()
{
2022-09-10 00:33:17 +03:00
_subscribersList = new ConcurrentDictionary<Type, List<EventListenerBaseAsync>>();
2021-12-06 02:49:27 +03:00
}
/// <suary>
/// Adds a new subscriber to a certain event.
/// </suary>
/// <param name="listener">listener.</param>
/// <typeparam name="TEvent">The event type.</typeparam>
public static void AddListenerAsync<TEventAsync>(EventListenerAsync<TEventAsync> listener)
where TEventAsync : struct
{
var eventType = typeof(TEventAsync);
if (!_subscribersList.ContainsKey(eventType))
2022-08-13 08:34:20 +03:00
_subscribersList[eventType] = new List<EventListenerBaseAsync>(10000);
2021-12-06 02:49:27 +03:00
//if( !SubscriptionExistsAsync( eventType, listener ) )
_subscribersList[eventType].Add(listener);
}
/// <suary>
/// Removes a subscriber from a certain event.
/// </suary>
/// <param name="listener">listener.</param>
/// <typeparam name="TEvent">The event type.</typeparam>
public static void RemoveListenerAsync<TEventAsync>(EventListenerAsync<TEventAsync> listener)
where TEventAsync : struct
{
var eventType = typeof(TEventAsync);
/*
if( !_subscribersList.ContainsKey( eventType ) )
{
#if EVENTROUTER_THROWEXCEPTIONS
throw new ArgumentException( string.Format( "Removing listener \"{0}\", but the event type \"{1}\" isn't registered.", listener, eventType.ToString() ) );
#else
return;
#endif
}*/
2022-08-13 08:34:20 +03:00
List<EventListenerBaseAsync> subscriberList = _subscribersList[eventType];
2021-12-06 02:49:27 +03:00
2022-08-13 08:34:20 +03:00
for (int i = 0; i < subscriberList.Count; i++)
2021-12-06 02:49:27 +03:00
{
2022-08-13 08:34:20 +03:00
if (subscriberList[i] == listener)
2021-12-06 02:49:27 +03:00
{
subscriberList.Remove(subscriberList[i]);
2022-08-13 08:34:20 +03:00
if (subscriberList.Count == 0)
2022-09-10 00:33:17 +03:00
_subscribersList.Remove(eventType, out subscriberList);
2021-12-06 02:49:27 +03:00
return;
}
}
}
/// <suary>
/// Triggers an event. All instances that are subscribed to it will receive it (and will potentially act on it).
/// </suary>
/// <param name="newEvent">The event to trigger.</param>
/// <typeparam name="TEvent">The 1st type parameter.</typeparam>
public static void TriggerEventAsync<TEvent>(TEvent newEvent) where TEvent : struct
{
var type = typeof(TEvent);
2022-08-13 08:34:20 +03:00
List<EventListenerBaseAsync> list = _subscribersList[type];
2021-12-06 02:49:27 +03:00
2022-08-13 08:34:20 +03:00
for (int i = 0; i < list.Count; i++)
2021-12-06 02:49:27 +03:00
{
2022-08-13 08:34:20 +03:00
var baseListener = list[i];
2021-12-06 02:49:27 +03:00
var eventListenerCasted = baseListener as EventListenerAsync<TEvent>;
eventListenerCasted.OnEventAsync(newEvent);
}
}
/// <suary>
/// Checks if there are subscribers for a certain type of events
/// </suary>
/// <returns><c>true</c>, if exists was subscriptioned, <c>false</c> otherwise.</returns>
/// <param name="type">Type.</param>
/// <param name="receiver">Receiver.</param>
private static bool SubscriptionExistsAsync(Type type, EventListenerBaseAsync receiver)
{
2022-08-13 08:34:20 +03:00
List<EventListenerBaseAsync> receivers;
2021-12-06 02:49:27 +03:00
if (!_subscribersList.TryGetValue(type, out receivers)) return false;
bool exists = false;
2022-08-13 08:34:20 +03:00
for (int i = 0; i < receivers.Count; i++)
2021-12-06 02:49:27 +03:00
{
2022-08-13 08:34:20 +03:00
var eventListenerBase = receivers[i];
2021-12-06 02:49:27 +03:00
if (eventListenerBase == receiver)
{
return true;
}
}
return exists;
}
}
/// <suary>
/// Static class that allows any class to start or stop listening to events
/// </suary>
public static class EventRegisterAsync
{
public delegate void DelegateAsync<T>(T eventType);
public static void EventStartListeningAsync<EventType>(this EventListenerAsync<EventType> caller)
where EventType : struct
{
EventManagerAsync.AddListenerAsync<EventType>(caller);
}
public static void EventStopListeningAsync<EventType>(this EventListenerAsync<EventType> caller)
where EventType : struct
{
EventManagerAsync.RemoveListenerAsync<EventType>(caller);
}
}
/// <suary>
/// TEvent listener basic interface
/// </suary>
public interface EventListenerBaseAsync
{
};
/// <suary>
/// A public interface you'll need to implement for each type of event you want to listen to.
/// </suary>
public interface EventListenerAsync<T> : EventListenerBaseAsync
{
void OnEventAsync(T eventType);
}
}