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

148 lines
4.1 KiB
C#

using System;
using BlueWest.Collections;
namespace BlueWest.Tools
{
public sealed class EventManager
{
private readonly FastDictionary<Type, FastList<EventListenerBase>> _subscribersList;
private static EventManager _instance;
public EventManager(FastDictionary<Type, FastList<EventListenerBase>> subscribersList)
{
_subscribersList = subscribersList;
_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 FastList<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 );
FastList<EventListenerBase> 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 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
FastList<EventListenerBase> list = _subscribersList[type];
for (int i=0; i<list.Length; i++)
{
var eventListener = list.Buffer[i];
var casted = eventListener as EventListener<TEvent>;
casted.OnEvent( 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 bool SubscriptionExists( Type type, EventListenerBase receiver )
{
FastList<EventListenerBase> receivers;
if( !_subscribersList.TryGetValue( type, out receivers ) ) return false;
bool exists = false;
for (int i=0; i<receivers.Length; i++)
{
if( receivers.Buffer[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 );
}
}