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

156 lines
4.2 KiB
C#
Raw Normal View History

2021-12-06 02:49:27 +03:00
using System;
2022-08-13 08:34:20 +03:00
using System.Collections.Generic;
2022-09-17 22:13:35 +03:00
using System.Linq;
using System.Threading.Tasks;
2021-12-06 02:49:27 +03:00
namespace BlueWest.Tools
{
public sealed class EventManager
{
2022-08-13 08:34:20 +03:00
private readonly Dictionary<Type, List<EventListenerBase>> _subscribersList;
2021-12-06 02:49:27 +03:00
private static EventManager _instance;
2022-08-13 08:34:20 +03:00
public EventManager(Dictionary<Type, List<EventListenerBase>> subscribersList)
2021-12-06 02:49:27 +03:00
{
_subscribersList = subscribersList;
_instance = this;
}
2022-08-19 19:47:35 +03:00
public EventManager()
{
_subscribersList = new Dictionary<Type, List<EventListenerBase>>();
_instance = this;
}
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 void AddListener<TEvent>( EventListener<TEvent> listener ) where TEvent : struct
{
var eventType = typeof( TEvent );
if( !_subscribersList.ContainsKey( eventType ) )
2022-08-13 08:34:20 +03:00
_subscribersList[eventType] = new List<EventListenerBase>(10000);
2021-12-06 02:49:27 +03:00
//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 );
2022-08-13 08:34:20 +03:00
List<EventListenerBase> 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 )
2021-12-06 02:49:27 +03:00
_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
2022-08-13 08:34:20 +03:00
List<EventListenerBase> list = _subscribersList[type];
2022-09-17 22:13:35 +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 eventListener = list[i];
2021-12-06 02:49:27 +03:00
var casted = eventListener as EventListener<TEvent>;
2022-09-10 00:33:17 +03:00
#pragma warning disable CS8602
2021-12-06 02:49:27 +03:00
casted.OnEvent( newEvent );
2022-09-10 00:33:17 +03:00
#pragma warning restore CS8602
2021-12-06 02:49:27 +03:00
}
}
/// <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 )
{
2022-09-10 00:33:17 +03:00
if( !_subscribersList.TryGetValue( type, out var receivers ) ) return false;
2021-12-06 02:49:27 +03:00
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
if( receivers[i] == receiver )
2021-12-06 02:49:27 +03:00
{
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 );
}
}