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

148 lines
5.0 KiB
C#

using System;
using BlueWest.Collections;
namespace BlueWest.Tools
{
public struct EventManagerAsync
{
private static readonly FastDictionary<Type, FastList<EventListenerBaseAsync>> _subscribersList;
static EventManagerAsync()
{
_subscribersList = new FastDictionary<Type, FastList<EventListenerBaseAsync>>(12412);
}
/// <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))
_subscribersList[eventType] = new FastList<EventListenerBaseAsync>(10000);
//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
}*/
FastList<EventListenerBaseAsync> subscriberList = _subscribersList[eventType];
for (int i = 0; i < subscriberList.Length; i++)
{
if (subscriberList.Buffer[i] == listener)
{
subscriberList.Remove(subscriberList[i]);
if (subscriberList.Length == 0)
_subscribersList.Remove(eventType);
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);
FastList<EventListenerBaseAsync> list = _subscribersList[type];
for (int i = 0; i < list.Length; i++)
{
var baseListener = list.Buffer[i];
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)
{
FastList<EventListenerBaseAsync> receivers;
if (!_subscribersList.TryGetValue(type, out receivers)) return false;
bool exists = false;
for (int i = 0; i < receivers.Length; i++)
{
var eventListenerBase = receivers.Buffer[i];
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);
}
}