Tagging interface for event handlers
Support events in the TorchAPI Static registry, non-static registration methods. Support unregister by assembly.
This commit is contained in:
@@ -1,10 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Torch.Managers.EventManager
|
||||
namespace Torch.API.Managers.Event
|
||||
{
|
||||
/// <summary>
|
||||
/// Attribute indicating that a method should be invoked when the event occurs.
|
@@ -1,10 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Torch.Managers.EventManager
|
||||
namespace Torch.API.Managers.Event
|
||||
{
|
||||
public interface IEvent
|
||||
{
|
9
Torch.API/Managers/Event/IEventHandler.cs
Normal file
9
Torch.API/Managers/Event/IEventHandler.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace Torch.API.Managers.Event
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface used to tag an event handler. This does <b>not</b> register it with the event manager.
|
||||
/// </summary>
|
||||
public interface IEventHandler
|
||||
{
|
||||
}
|
||||
}
|
27
Torch.API/Managers/Event/IEventManager.cs
Normal file
27
Torch.API/Managers/Event/IEventManager.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Torch.API.Managers.Event
|
||||
{
|
||||
/// <summary>
|
||||
/// Manager class responsible for registration of event handlers.
|
||||
/// </summary>
|
||||
public interface IEventManager
|
||||
{
|
||||
/// <summary>
|
||||
/// Registers all event handler methods contained in the given instance
|
||||
/// </summary>
|
||||
/// <param name="handler">Instance to register</param>
|
||||
/// <returns><b>true</b> if added, <b>false</b> otherwise</returns>
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
bool RegisterHandler(IEventHandler handler);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Unregisters all event handler methods contained in the given instance
|
||||
/// </summary>
|
||||
/// <param name="handler">Instance to unregister</param>
|
||||
/// <returns><b>true</b> if removed, <b>false</b> otherwise</returns>
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
bool UnregisterHandler(IEventHandler handler);
|
||||
}
|
||||
}
|
@@ -1,13 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Torch.API.Managers.Event;
|
||||
using Torch.Managers.EventManager;
|
||||
|
||||
namespace Torch.Managers.EventManager
|
||||
namespace Torch.Managers.Event
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an ordered list of callbacks.
|
||||
@@ -49,7 +48,7 @@ namespace Torch.Managers.EventManager
|
||||
private readonly ReaderWriterLockSlim _lock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void AddHandler(MethodInfo method, object instance)
|
||||
public void AddHandler(MethodInfo method, IEventHandler instance)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -64,7 +63,7 @@ namespace Torch.Managers.EventManager
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public int RemoveHandlers(object instance)
|
||||
public int RemoveHandlers(IEventHandler instance)
|
||||
{
|
||||
try
|
||||
{
|
@@ -3,23 +3,21 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using NLog;
|
||||
using Torch.API;
|
||||
using Torch.API.Managers;
|
||||
using VRage.Game.ModAPI;
|
||||
using Torch.API.Managers.Event;
|
||||
using Torch.Managers.EventManager;
|
||||
|
||||
namespace Torch.Managers.EventManager
|
||||
namespace Torch.Managers.Event
|
||||
{
|
||||
/// <summary>
|
||||
/// Manager class responsible for managing registration and dispatching of events.
|
||||
/// </summary>
|
||||
public class EventManager : Manager
|
||||
public class EventManager : Manager, IEventManager
|
||||
{
|
||||
private static readonly Logger _log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
private static Dictionary<Type, IEventList> _eventLists = new Dictionary<Type, IEventList>();
|
||||
private static readonly Dictionary<Type, IEventList> _eventLists = new Dictionary<Type, IEventList>();
|
||||
|
||||
static EventManager()
|
||||
{
|
||||
@@ -41,11 +39,7 @@ namespace Torch.Managers.EventManager
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds all event handlers in the given type, and its base types
|
||||
/// </summary>
|
||||
/// <param name="exploreType">Type to explore</param>
|
||||
/// <returns>All event handlers</returns>
|
||||
/// <inheritdoc/>
|
||||
private static IEnumerable<MethodInfo> EventHandlers(Type exploreType)
|
||||
{
|
||||
IEnumerable<MethodInfo> enumerable = exploreType.GetMethods(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance)
|
||||
@@ -62,11 +56,8 @@ namespace Torch.Managers.EventManager
|
||||
return exploreType.BaseType != null ? enumerable.Concat(EventHandlers(exploreType.BaseType)) : enumerable;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers all handlers the given instance owns.
|
||||
/// </summary>
|
||||
/// <param name="instance">Instance to register handlers from</param>
|
||||
private static void RegisterHandler(object instance)
|
||||
/// <inheritdoc/>
|
||||
private static void RegisterHandlerInternal(IEventHandler instance)
|
||||
{
|
||||
foreach (MethodInfo handler in EventHandlers(instance.GetType()))
|
||||
{
|
||||
@@ -96,15 +87,86 @@ namespace Torch.Managers.EventManager
|
||||
/// Unregisters all handlers owned by the given instance
|
||||
/// </summary>
|
||||
/// <param name="instance">Instance</param>
|
||||
private static void UnregisterHandlers(object instance)
|
||||
private static void UnregisterHandlerInternal(IEventHandler instance)
|
||||
{
|
||||
foreach (IEventList list in _eventLists.Values)
|
||||
list.RemoveHandlers(instance);
|
||||
}
|
||||
|
||||
private Dictionary<Assembly, HashSet<IEventHandler>> _registeredHandlers = new Dictionary<Assembly, HashSet<IEventHandler>>();
|
||||
|
||||
/// <inheritdoc/>
|
||||
public EventManager(ITorchBase torchInstance) : base(torchInstance)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers all event handler methods contained in the given instance
|
||||
/// </summary>
|
||||
/// <param name="handler">Instance to register</param>
|
||||
/// <returns><b>true</b> if added, <b>false</b> otherwise</returns>
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
public bool RegisterHandler(IEventHandler handler)
|
||||
{
|
||||
Assembly caller = Assembly.GetCallingAssembly();
|
||||
lock (_registeredHandlers)
|
||||
{
|
||||
if (!_registeredHandlers.TryGetValue(caller, out HashSet<IEventHandler> handlers))
|
||||
_registeredHandlers.Add(caller, handlers = new HashSet<IEventHandler>());
|
||||
if (handlers.Add(handler))
|
||||
{
|
||||
RegisterHandlerInternal(handler);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Unregisters all event handler methods contained in the given instance
|
||||
/// </summary>
|
||||
/// <param name="handler">Instance to unregister</param>
|
||||
/// <returns><b>true</b> if removed, <b>false</b> otherwise</returns>
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
public bool UnregisterHandler(IEventHandler handler)
|
||||
{
|
||||
Assembly caller = Assembly.GetCallingAssembly();
|
||||
lock (_registeredHandlers)
|
||||
{
|
||||
if (!_registeredHandlers.TryGetValue(caller, out HashSet<IEventHandler> handlers))
|
||||
return false;
|
||||
if (handlers.Remove(handler))
|
||||
{
|
||||
UnregisterHandlerInternal(handler);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unregisters all handlers owned by the given assembly.
|
||||
/// </summary>
|
||||
/// <param name="asm">Assembly to unregister</param>
|
||||
/// <param name="callback">Optional callback invoked for every registered handler in the assembly. Ignored if null</param>
|
||||
/// <returns>the number of handlers that were unregistered</returns>
|
||||
internal int UnregisterAllHandlers(Assembly asm, Func<IEventHandler> callback = null)
|
||||
{
|
||||
lock (_registeredHandlers)
|
||||
{
|
||||
if (!_registeredHandlers.TryGetValue(asm, out HashSet<IEventHandler> handlers))
|
||||
return 0;
|
||||
foreach (IEventHandler k in handlers)
|
||||
{
|
||||
callback?.Invoke();
|
||||
UnregisterHandlerInternal(k);
|
||||
}
|
||||
int count = handlers.Count;
|
||||
handlers.Clear();
|
||||
_registeredHandlers.Remove(asm);
|
||||
return count;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -6,6 +6,8 @@ using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Sandbox.Game.Entities;
|
||||
using Sandbox.Game.Entities.Blocks;
|
||||
using Torch.API.Managers.Event;
|
||||
using Torch.Managers.Event;
|
||||
using Torch.Managers.PatchManager;
|
||||
using Torch.Utils;
|
||||
|
@@ -1,11 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Reflection;
|
||||
using Torch.API.Managers.Event;
|
||||
|
||||
namespace Torch.Managers.EventManager
|
||||
namespace Torch.Managers.Event
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the interface for adding and removing from an ordered list of callbacks.
|
||||
@@ -17,13 +13,13 @@ namespace Torch.Managers.EventManager
|
||||
/// </summary>
|
||||
/// <param name="method">Handler method</param>
|
||||
/// <param name="instance">Instance to invoke the handler on</param>
|
||||
void AddHandler(MethodInfo method, object instance);
|
||||
void AddHandler(MethodInfo method, IEventHandler instance);
|
||||
|
||||
/// <summary>
|
||||
/// Removes all event handlers invoked on the given instance.
|
||||
/// </summary>
|
||||
/// <param name="instance">Instance to remove event handlers for</param>
|
||||
/// <returns>The number of event handlers removed</returns>
|
||||
int RemoveHandlers(object instance);
|
||||
int RemoveHandlers(IEventHandler instance);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user