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

156 lines
4.2 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace BlueWest.Tools
{
public sealed class EventManager
{
private readonly Dictionary<Type, List<EventListenerBase>> _subscribersList;
private static EventManager _instance;
public EventManager(Dictionary<Type, List<EventListenerBase>> subscribersList)
{
_subscribersList = subscribersList;
_instance = this;
}
public EventManager()
{
_subscribersList = new Dictionary<Type, List<EventListenerBase>>();
_instance = this;
}
/// <suary>
/// Adds a new subscriber to a certain event.
/// </suary>
/// <param name="listener">listener.</param>
/// <typeparam name="TEvent">The event type.</typeparam>
public void AddListener<TEvent>( EventListener<TEvent> listener ) where TEvent : struct
{
var eventType = typeof( TEvent );
if( !_subscribersList.ContainsKey( eventType ) )
_subscribersList[eventType] = new List<EventListenerBase>(10000);
//if( !SubscriptionExists( 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 void RemoveListener<TEvent>( EventListener<TEvent> listener ) where TEvent : struct
{
var eventType = typeof( TEvent );
List<EventListenerBase> subscriberList = _subscribersList[eventType];
for (int i = 0; i<subscriberList.Count; i++)
{
if( subscriberList[i] == listener )
{
subscriberList.Remove( subscriberList[i] );
if( subscriberList.Count == 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 void TriggerEvent<TEvent>( TEvent newEvent ) where TEvent : struct
{
var type = typeof(TEvent);
#if DEBUG
if (!_subscribersList.ContainsKey(type))
{
Console.WriteLine($"{type.FullName} has no actual trigger, fix it...");
return;
}
#endif
List<EventListenerBase> list = _subscribersList[type];
for (int i=0; i<list.Count; i++)
{
var eventListener = list[i];
var casted = eventListener as EventListener<TEvent>;
#pragma warning disable CS8602
casted.OnEvent( newEvent );
#pragma warning restore CS8602
}
}
/// <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 bool SubscriptionExists( Type type, EventListenerBase receiver )
{
if( !_subscribersList.TryGetValue( type, out var receivers ) ) return false;
bool exists = false;
for (int i=0; i<receivers.Count; i++)
{
if( receivers[i] == receiver )
{
exists = true;
break;
}
}
return exists;
}
public void EventStartListening<EventType>( EventListener<EventType> caller ) where EventType : struct
{
AddListener<EventType>( caller );
}
public void EventStopListening<EventType>( EventListener<EventType> caller ) where EventType : struct
{
RemoveListener<EventType>( caller );
}
}
/// <suary>
/// Static class that allows any class to start or stop listening to events
/// </suary>
public static class EventRegister
{
public delegate void Delegate<T>( T eventType );
}
/// <suary>
/// TEvent listener basic interface
/// </suary>
public interface EventListenerBase { };
/// <suary>
/// A public interface you'll need to implement for each type of event you want to listen to.
/// </suary>
public interface EventListener<T> : EventListenerBase
{
void OnEvent( T eventType );
}
}