using System;
using System.Linq;
using Dalamud.Game;
using Dalamud.Plugin.Services;
using Serilog;
using static Dalamud.Game.Framework;
namespace Dalamud.Utility;
///
/// Extensions for Events.
///
internal static class EventHandlerExtensions
{
///
/// Replacement for Invoke() on EventHandlers to catch exceptions that stop event propagation in case
/// of a thrown Exception inside of an invocation.
///
/// The EventHandler in question.
/// Default sender for Invoke equivalent.
/// Default EventArgs for Invoke equivalent.
public static void InvokeSafely(this EventHandler eh, object sender, EventArgs e)
{
if (eh == null)
return;
foreach (var handler in eh.GetInvocationList().Cast())
{
HandleInvoke(() => handler(sender, e));
}
}
///
/// Replacement for Invoke() on generic EventHandlers to catch exceptions that stop event propagation in case
/// of a thrown Exception inside of an invocation.
///
/// The EventHandler in question.
/// Default sender for Invoke equivalent.
/// Default EventArgs for Invoke equivalent.
/// Type of EventArgs.
public static void InvokeSafely(this EventHandler eh, object sender, T e)
{
if (eh == null)
return;
foreach (var handler in eh.GetInvocationList().Cast>())
{
HandleInvoke(() => handler(sender, e));
}
}
///
/// Replacement for Invoke() on event Actions to catch exceptions that stop event propagation in case
/// of a thrown Exception inside of an invocation.
///
/// The Action in question.
public static void InvokeSafely(this Action act)
{
if (act == null)
return;
foreach (var action in act.GetInvocationList().Cast())
{
HandleInvoke(action);
}
}
///
/// Replacement for Invoke() on OnUpdateDelegate to catch exceptions that stop event propagation in case
/// of a thrown Exception inside of an invocation.
///
/// The OnUpdateDelegate in question.
/// Framework to be passed on to OnUpdateDelegate.
public static void InvokeSafely(this IFramework.OnUpdateDelegate updateDelegate, Framework framework)
{
if (updateDelegate == null)
return;
foreach (var action in updateDelegate.GetInvocationList().Cast())
{
HandleInvoke(() => action(framework));
}
}
private static void HandleInvoke(Action act)
{
try
{
act();
}
catch (Exception ex)
{
Log.Error(ex, "Exception during raise of {handler}", act.Method);
}
}
}