using System;
using System.Collections.Generic;
using TechbloxModdingAPI.Events;
namespace TechbloxModdingAPI.Utility
{
///
/// Wraps the event handler in a try-catch block to avoid propagating exceptions.
///
/// The event arguments type
public struct WrappedHandler
{
private EventHandler eventHandler;
///
/// Store wrappers so we can unregister them properly
///
private static Dictionary, EventHandler> wrappers =
new Dictionary, EventHandler>();
public static WrappedHandler operator +(WrappedHandler original, EventHandler added)
{
EventHandler 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());
}
};
wrappers.Add(added, wrapped);
return new WrappedHandler { eventHandler = original.eventHandler + wrapped };
}
public static WrappedHandler operator -(WrappedHandler original, EventHandler removed)
{
if (!wrappers.TryGetValue(removed, out var wrapped)) return original;
wrappers.Remove(removed);
return new WrappedHandler { eventHandler = original.eventHandler - wrapped };
}
public void Invoke(object sender, T args)
{
eventHandler?.Invoke(sender, args);
}
}
}