59 lines
No EOL
2 KiB
C#
59 lines
No EOL
2 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using TechbloxModdingAPI.Events;
|
|
|
|
namespace TechbloxModdingAPI.Utility
|
|
{
|
|
/// <summary>
|
|
/// Wraps the event handler in a try-catch block to avoid propagating exceptions.
|
|
/// </summary>
|
|
/// <typeparam name="T">The event arguments type</typeparam>
|
|
public struct WrappedHandler<T>
|
|
{
|
|
private EventHandler<T> eventHandler;
|
|
|
|
/// <summary>
|
|
/// Store wrappers so we can unregister them properly
|
|
/// </summary>
|
|
private static Dictionary<EventHandler<T>, EventHandler<T>> wrappers =
|
|
new Dictionary<EventHandler<T>, EventHandler<T>>();
|
|
|
|
public static WrappedHandler<T> operator +(WrappedHandler<T> original, EventHandler<T> added)
|
|
{
|
|
EventHandler<T> wrapped = (sender, e) =>
|
|
{
|
|
try
|
|
{
|
|
added(sender, e);
|
|
}
|
|
catch (Exception e1)
|
|
{
|
|
EventRuntimeException wrappedException =
|
|
new EventRuntimeException($"EventHandler with arg type {typeof(T).Name} threw an exception",
|
|
e1);
|
|
Logging.LogWarning(wrappedException.ToString());
|
|
}
|
|
};
|
|
if (wrappers.ContainsKey(added))
|
|
{
|
|
original.eventHandler -= wrapped;
|
|
wrappers.Remove(added);
|
|
}
|
|
|
|
wrappers.Add(added, wrapped);
|
|
return new WrappedHandler<T> { eventHandler = original.eventHandler + wrapped };
|
|
}
|
|
|
|
public static WrappedHandler<T> operator -(WrappedHandler<T> original, EventHandler<T> removed)
|
|
{
|
|
if (!wrappers.TryGetValue(removed, out var wrapped)) return original;
|
|
wrappers.Remove(removed);
|
|
return new WrappedHandler<T> { eventHandler = original.eventHandler - wrapped };
|
|
}
|
|
|
|
public void Invoke(object sender, T args)
|
|
{
|
|
eventHandler?.Invoke(sender, args);
|
|
}
|
|
}
|
|
} |