2021-12-06 02:49:27 +03:00
|
|
|
|
using System;
|
2022-08-13 08:34:20 +03:00
|
|
|
|
using System.Collections.Generic;
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <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];
|
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 eventListener = list[i];
|
2021-12-06 02:49:27 +03:00
|
|
|
|
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 )
|
|
|
|
|
{
|
2022-08-13 08:34:20 +03:00
|
|
|
|
List<EventListenerBase> 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
|
|
|
|
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 );
|
|
|
|
|
}
|
|
|
|
|
}
|