2021-12-06 02:49:27 +03:00
|
|
|
|
using System;
|
2022-09-10 00:33:17 +03:00
|
|
|
|
using System.Collections.Concurrent;
|
2022-08-13 08:34:20 +03:00
|
|
|
|
using System.Collections.Generic;
|
2021-12-06 02:49:27 +03:00
|
|
|
|
|
|
|
|
|
namespace BlueWest.Tools
|
|
|
|
|
{
|
|
|
|
|
public struct EventManagerAsync
|
|
|
|
|
{
|
2022-09-10 00:33:17 +03:00
|
|
|
|
private static readonly ConcurrentDictionary<Type, List<EventListenerBaseAsync>> _subscribersList;
|
2021-12-06 02:49:27 +03:00
|
|
|
|
|
|
|
|
|
static EventManagerAsync()
|
|
|
|
|
{
|
2022-09-10 00:33:17 +03:00
|
|
|
|
_subscribersList = new ConcurrentDictionary<Type, List<EventListenerBaseAsync>>();
|
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 static void AddListenerAsync<TEventAsync>(EventListenerAsync<TEventAsync> listener)
|
|
|
|
|
where TEventAsync : struct
|
|
|
|
|
{
|
|
|
|
|
var eventType = typeof(TEventAsync);
|
|
|
|
|
|
|
|
|
|
if (!_subscribersList.ContainsKey(eventType))
|
2022-08-13 08:34:20 +03:00
|
|
|
|
_subscribersList[eventType] = new List<EventListenerBaseAsync>(10000);
|
2021-12-06 02:49:27 +03:00
|
|
|
|
|
|
|
|
|
//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
|
|
|
|
|
}*/
|
|
|
|
|
|
2022-08-13 08:34:20 +03:00
|
|
|
|
List<EventListenerBaseAsync> 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)
|
2022-09-10 00:33:17 +03:00
|
|
|
|
_subscribersList.Remove(eventType, out subscriberList);
|
2021-12-06 02:49:27 +03:00
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
2022-08-13 08:34:20 +03:00
|
|
|
|
List<EventListenerBaseAsync> 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 baseListener = list[i];
|
2021-12-06 02:49:27 +03:00
|
|
|
|
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)
|
|
|
|
|
{
|
2022-08-13 08:34:20 +03:00
|
|
|
|
List<EventListenerBaseAsync> 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
|
|
|
|
var eventListenerBase = receivers[i];
|
2021-12-06 02:49:27 +03:00
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
}
|