diff --git a/Dalamud/Configuration/Internal/DalamudConfiguration.cs b/Dalamud/Configuration/Internal/DalamudConfiguration.cs
index 168382fab..8dafd897e 100644
--- a/Dalamud/Configuration/Internal/DalamudConfiguration.cs
+++ b/Dalamud/Configuration/Internal/DalamudConfiguration.cs
@@ -650,6 +650,16 @@ internal sealed class DalamudConfiguration : IInternalDisposableService
}
});
- this.DalamudConfigurationSaved?.Invoke(this);
+ foreach (var action in Delegate.EnumerateInvocationList(this.DalamudConfigurationSaved))
+ {
+ try
+ {
+ action(this);
+ }
+ catch (Exception ex)
+ {
+ Log.Error(ex, "Exception during raise of {handler}", action.Method);
+ }
+ }
}
}
diff --git a/Dalamud/Console/ConsoleManager.cs b/Dalamud/Console/ConsoleManager.cs
index c79a104e1..377bac208 100644
--- a/Dalamud/Console/ConsoleManager.cs
+++ b/Dalamud/Console/ConsoleManager.cs
@@ -184,8 +184,18 @@ internal partial class ConsoleManager : IServiceType
/// Whether the command was successfully processed.
public bool ProcessCommand(string command)
{
- if (this.Invoke?.Invoke(command) == true)
- return true;
+ foreach (var action in Delegate.EnumerateInvocationList(this.Invoke))
+ {
+ try
+ {
+ if (action(command))
+ return true;
+ }
+ catch (Exception ex)
+ {
+ Log.Error(ex, "Exception during raise of {handler}", action.Method);
+ }
+ }
var matches = GetCommandParsingRegex().Matches(command);
if (matches.Count == 0)
diff --git a/Dalamud/Game/ClientState/ClientState.cs b/Dalamud/Game/ClientState/ClientState.cs
index 5101657ba..4c32873c6 100644
--- a/Dalamud/Game/ClientState/ClientState.cs
+++ b/Dalamud/Game/ClientState/ClientState.cs
@@ -42,10 +42,10 @@ internal sealed class ClientState : IInternalDisposableService, IClientState
[ServiceManager.ServiceDependency]
private readonly Framework framework = Service.Get();
-
+
[ServiceManager.ServiceDependency]
private readonly NetworkHandlers networkHandlers = Service.Get();
-
+
private bool lastConditionNone = true;
[ServiceManager.ServiceConstructor]
@@ -176,7 +176,7 @@ internal sealed class ClientState : IInternalDisposableService, IClientState
this.uiModuleHandlePacketHook.Dispose();
this.onLogoutHook.Dispose();
- this.framework.Update -= this.FrameworkOnOnUpdateEvent;
+ this.framework.Update -= this.FrameworkOnOnUpdateEvent;
this.networkHandlers.CfPop -= this.NetworkHandlersOnCfPop;
}
@@ -211,50 +211,51 @@ internal sealed class ClientState : IInternalDisposableService, IClientState
this.setupTerritoryTypeHook.Original(eventFramework, territoryType);
}
- private unsafe void UIModuleHandlePacketDetour(UIModule* thisPtr, UIModulePacketType type, uint uintParam, void* packet)
+ private unsafe void UIModuleHandlePacketDetour(
+ UIModule* thisPtr, UIModulePacketType type, uint uintParam, void* packet)
{
this.uiModuleHandlePacketHook.Original(thisPtr, type, uintParam, packet);
switch (type)
{
- case UIModulePacketType.ClassJobChange when this.ClassJobChanged is { } callback:
+ case UIModulePacketType.ClassJobChange:
+ {
+ var classJobId = uintParam;
+
+ foreach (var action in Delegate.EnumerateInvocationList(this.ClassJobChanged))
{
- var classJobId = uintParam;
-
- foreach (var action in callback.GetInvocationList().Cast())
+ try
{
- try
- {
- action(classJobId);
- }
- catch (Exception ex)
- {
- Log.Error(ex, "Exception during raise of {handler}", action.Method);
- }
+ action(classJobId);
+ }
+ catch (Exception ex)
+ {
+ Log.Error(ex, "Exception during raise of {handler}", action.Method);
}
-
- break;
}
- case UIModulePacketType.LevelChange when this.LevelChanged is { } callback:
+ break;
+ }
+
+ case UIModulePacketType.LevelChange:
+ {
+ var classJobId = *(uint*)packet;
+ var level = *(ushort*)((nint)packet + 4);
+
+ foreach (var action in Delegate.EnumerateInvocationList(this.LevelChanged))
{
- var classJobId = *(uint*)packet;
- var level = *(ushort*)((nint)packet + 4);
-
- foreach (var action in callback.GetInvocationList().Cast())
+ try
{
- try
- {
- action(classJobId, level);
- }
- catch (Exception ex)
- {
- Log.Error(ex, "Exception during raise of {handler}", action.Method);
- }
+ action(classJobId, level);
+ }
+ catch (Exception ex)
+ {
+ Log.Error(ex, "Exception during raise of {handler}", action.Method);
}
-
- break;
}
+
+ break;
+ }
}
}
@@ -291,18 +292,15 @@ internal sealed class ClientState : IInternalDisposableService, IClientState
Log.Debug("Logout: Type {type}, Code {code}", type, code);
- if (this.Logout is { } callback)
+ foreach (var action in Delegate.EnumerateInvocationList(this.Logout))
{
- foreach (var action in callback.GetInvocationList().Cast())
+ try
{
- try
- {
- action(type, code);
- }
- catch (Exception ex)
- {
- Log.Error(ex, "Exception during raise of {handler}", action.Method);
- }
+ action(type, code);
+ }
+ catch (Exception ex)
+ {
+ Log.Error(ex, "Exception during raise of {handler}", action.Method);
}
}
diff --git a/Dalamud/Game/ClientState/Conditions/Condition.cs b/Dalamud/Game/ClientState/Conditions/Condition.cs
index 8f39df46f..99748f71b 100644
--- a/Dalamud/Game/ClientState/Conditions/Condition.cs
+++ b/Dalamud/Game/ClientState/Conditions/Condition.cs
@@ -22,7 +22,7 @@ internal sealed class Condition : IInternalDisposableService, ICondition
[ServiceManager.ServiceDependency]
private readonly Framework framework = Service.Get();
-
+
private readonly bool[] cache = new bool[MaxConditionEntries];
private bool isDisposed;
@@ -38,7 +38,7 @@ internal sealed class Condition : IInternalDisposableService, ICondition
this.framework.Update += this.FrameworkUpdate;
}
-
+
/// Finalizes an instance of the class.
~Condition() => this.Dispose(false);
@@ -69,12 +69,12 @@ internal sealed class Condition : IInternalDisposableService, ICondition
///
void IInternalDisposableService.DisposeService() => this.Dispose(true);
-
+
///
public IReadOnlySet AsReadOnlySet()
{
var result = new HashSet();
-
+
for (var i = 0; i < MaxConditionEntries; i++)
{
if (this[i])
@@ -99,14 +99,14 @@ internal sealed class Condition : IInternalDisposableService, ICondition
return false;
}
-
+
///
public bool Any(params ConditionFlag[] flags)
{
foreach (var flag in flags)
{
// this[i] performs range checking, so no need to check here
- if (this[flag])
+ if (this[flag])
{
return true;
}
@@ -114,7 +114,7 @@ internal sealed class Condition : IInternalDisposableService, ICondition
return false;
}
-
+
///
public bool AnyExcept(params ConditionFlag[] excluded)
{
@@ -157,13 +157,16 @@ internal sealed class Condition : IInternalDisposableService, ICondition
{
this.cache[i] = value;
- try
+ foreach (var d in Delegate.EnumerateInvocationList(this.ConditionChange))
{
- this.ConditionChange?.Invoke((ConditionFlag)i, value);
- }
- catch (Exception ex)
- {
- Log.Error(ex, $"While invoking {nameof(this.ConditionChange)}, an exception was thrown.");
+ try
+ {
+ d((ConditionFlag)i, value);
+ }
+ catch (Exception ex)
+ {
+ Log.Error(ex, $"While invoking {d.Method.Name}, an exception was thrown.");
+ }
}
}
}
@@ -190,7 +193,7 @@ internal class ConditionPluginScoped : IInternalDisposableService, ICondition
{
this.conditionService.ConditionChange += this.ConditionChangedForward;
}
-
+
///
public event ICondition.ConditionChangeDelegate? ConditionChange;
@@ -202,7 +205,7 @@ internal class ConditionPluginScoped : IInternalDisposableService, ICondition
///
public bool this[int flag] => this.conditionService[flag];
-
+
///
void IInternalDisposableService.DisposeService()
{
@@ -210,7 +213,7 @@ internal class ConditionPluginScoped : IInternalDisposableService, ICondition
this.ConditionChange = null;
}
-
+
///
public IReadOnlySet AsReadOnlySet() => this.conditionService.AsReadOnlySet();
@@ -222,10 +225,10 @@ internal class ConditionPluginScoped : IInternalDisposableService, ICondition
///
public bool AnyExcept(params ConditionFlag[] except) => this.conditionService.AnyExcept(except);
-
+
///
public bool OnlyAny(params ConditionFlag[] other) => this.conditionService.OnlyAny(other);
-
+
///
public bool EqualTo(params ConditionFlag[] other) => this.conditionService.EqualTo(other);
diff --git a/Dalamud/Game/Command/CommandManager.cs b/Dalamud/Game/Command/CommandManager.cs
index b72238abe..01442c409 100644
--- a/Dalamud/Game/Command/CommandManager.cs
+++ b/Dalamud/Game/Command/CommandManager.cs
@@ -132,7 +132,7 @@ internal sealed unsafe class CommandManager : IInternalDisposableService, IComma
return false;
}
- this.CommandAdded?.Invoke(this, new CommandEventArgs
+ this.CommandAdded?.InvokeSafely(this, new CommandEventArgs
{
Command = command,
CommandInfo = info,
@@ -160,7 +160,7 @@ internal sealed unsafe class CommandManager : IInternalDisposableService, IComma
return false;
}
- this.CommandAdded?.Invoke(this, new CommandEventArgs
+ this.CommandAdded?.InvokeSafely(this, new CommandEventArgs
{
Command = command,
CommandInfo = info,
@@ -180,7 +180,7 @@ internal sealed unsafe class CommandManager : IInternalDisposableService, IComma
var removed = this.commandMap.Remove(command, out var info);
if (removed)
{
- this.CommandRemoved?.Invoke(this, new CommandEventArgs
+ this.CommandRemoved?.InvokeSafely(this, new CommandEventArgs
{
Command = command,
CommandInfo = info,
diff --git a/Dalamud/Game/Framework.cs b/Dalamud/Game/Framework.cs
index 88f9d0bb6..808bbce50 100644
--- a/Dalamud/Game/Framework.cs
+++ b/Dalamud/Game/Framework.cs
@@ -350,17 +350,13 @@ internal sealed class Framework : IInternalDisposableService, IFramework
/// The Framework Instance to pass to delegate.
internal void ProfileAndInvoke(IFramework.OnUpdateDelegate? eventDelegate, IFramework frameworkInstance)
{
- if (eventDelegate is null) return;
-
- var invokeList = eventDelegate.GetInvocationList();
-
// Individually invoke OnUpdate handlers and time them.
- foreach (var d in invokeList)
+ foreach (var d in Delegate.EnumerateInvocationList(eventDelegate))
{
var stopwatch = Stopwatch.StartNew();
try
{
- d.Method.Invoke(d.Target, new object[] { frameworkInstance });
+ d(frameworkInstance);
}
catch (Exception ex)
{
@@ -370,8 +366,7 @@ internal sealed class Framework : IInternalDisposableService, IFramework
stopwatch.Stop();
var key = $"{d.Target}::{d.Method.Name}";
- if (this.NonUpdatedSubDelegates.Contains(key))
- this.NonUpdatedSubDelegates.Remove(key);
+ this.NonUpdatedSubDelegates.Remove(key);
AddToStats(key, stopwatch.Elapsed.TotalMilliseconds);
}
diff --git a/Dalamud/Game/Gui/ChatGui.cs b/Dalamud/Game/Gui/ChatGui.cs
index 721070d9b..022968c7e 100644
--- a/Dalamud/Game/Gui/ChatGui.cs
+++ b/Dalamud/Game/Gui/ChatGui.cs
@@ -346,24 +346,21 @@ internal sealed unsafe class ChatGui : IInternalDisposableService, IChatGui
// Call events
var isHandled = false;
- if (this.CheckMessageHandled is { } handledCallback)
+ foreach (var action in Delegate.EnumerateInvocationList(this.CheckMessageHandled))
{
- foreach (var action in handledCallback.GetInvocationList().Cast())
+ try
{
- try
- {
- action(chatType, timestamp, ref parsedSender, ref parsedMessage, ref isHandled);
- }
- catch (Exception e)
- {
- Log.Error(e, "Could not invoke registered OnCheckMessageHandledDelegate for {Name}", action.Method);
- }
+ action(chatType, timestamp, ref parsedSender, ref parsedMessage, ref isHandled);
+ }
+ catch (Exception e)
+ {
+ Log.Error(e, "Could not invoke registered OnCheckMessageHandledDelegate for {Name}", action.Method);
}
}
- if (!isHandled && this.ChatMessage is { } callback)
+ if (!isHandled)
{
- foreach (var action in callback.GetInvocationList().Cast())
+ foreach (var action in Delegate.EnumerateInvocationList(this.ChatMessage))
{
try
{
@@ -394,12 +391,14 @@ internal sealed unsafe class ChatGui : IInternalDisposableService, IChatGui
// Print the original chat if it's handled.
if (isHandled)
{
- this.ChatMessageHandled?.Invoke(chatType, timestamp, parsedSender, parsedMessage);
+ foreach (var d in Delegate.EnumerateInvocationList(this.ChatMessageHandled))
+ d(chatType, timestamp, parsedSender, parsedMessage);
}
else
{
messageId = this.printMessageHook.Original(manager, chatType, sender, message, timestamp, silent);
- this.ChatMessageUnhandled?.Invoke(chatType, timestamp, parsedSender, parsedMessage);
+ foreach (var d in Delegate.EnumerateInvocationList(this.ChatMessageUnhandled))
+ d(chatType, timestamp, parsedSender, parsedMessage);
}
}
catch (Exception ex)
diff --git a/Dalamud/Game/Gui/FlyText/FlyTextGui.cs b/Dalamud/Game/Gui/FlyText/FlyTextGui.cs
index cbf166cfc..d869c6fd1 100644
--- a/Dalamud/Game/Gui/FlyText/FlyTextGui.cs
+++ b/Dalamud/Game/Gui/FlyText/FlyTextGui.cs
@@ -75,7 +75,7 @@ internal sealed class FlyTextGui : IInternalDisposableService, IFlyTextGui
strArray->SetValue((int)strOffset + 0, text1.EncodeWithNullTerminator(), false, true, false);
strArray->SetValue((int)strOffset + 1, text2.EncodeWithNullTerminator(), false, true, false);
-
+
flytext->AddFlyText(actorIndex, 1, numArray, numOffset, 10, strArray, strOffset, 2, 0);
}
@@ -116,17 +116,27 @@ internal sealed class FlyTextGui : IInternalDisposableService, IFlyTextGui
$"text1({(nint)text1:X}, \"{tmpText1}\") text2({(nint)text2:X}, \"{tmpText2}\") " +
$"color({color:X}) icon({icon}) yOffset({yOffset})");
Log.Verbose("[FlyText] Calling flytext events!");
- this.FlyTextCreated?.Invoke(
- ref tmpKind,
- ref tmpVal1,
- ref tmpVal2,
- ref tmpText1,
- ref tmpText2,
- ref tmpColor,
- ref tmpIcon,
- ref tmpDamageTypeIcon,
- ref tmpYOffset,
- ref handled);
+ foreach (var d in Delegate.EnumerateInvocationList(this.FlyTextCreated))
+ {
+ try
+ {
+ d(
+ ref tmpKind,
+ ref tmpVal1,
+ ref tmpVal2,
+ ref tmpText1,
+ ref tmpText2,
+ ref tmpColor,
+ ref tmpIcon,
+ ref tmpDamageTypeIcon,
+ ref tmpYOffset,
+ ref handled);
+ }
+ catch (Exception ex)
+ {
+ Log.Error(ex, "Exception during raise of {handler}", d.Method);
+ }
+ }
// If handled, ignore the original call
if (handled)
diff --git a/Dalamud/Game/Gui/NamePlate/NamePlateGui.cs b/Dalamud/Game/Gui/NamePlate/NamePlateGui.cs
index 32192ad21..cd84b996b 100644
--- a/Dalamud/Game/Gui/NamePlate/NamePlateGui.cs
+++ b/Dalamud/Game/Gui/NamePlate/NamePlateGui.cs
@@ -6,6 +6,7 @@ using Dalamud.Hooking;
using Dalamud.IoC;
using Dalamud.IoC.Internal;
using Dalamud.Plugin.Services;
+using Dalamud.Utility;
using FFXIVClientStructs.FFXIV.Client.UI;
using FFXIVClientStructs.FFXIV.Component.GUI;
@@ -169,8 +170,8 @@ internal sealed class NamePlateGui : IInternalDisposableService, INamePlateGui
handler.ResetState();
}
- this.OnDataUpdate?.Invoke(this.context, activeHandlers);
- this.OnNamePlateUpdate?.Invoke(this.context, activeHandlers);
+ this.OnDataUpdate?.InvokeSafely(this.context, activeHandlers);
+ this.OnNamePlateUpdate?.InvokeSafely(this.context, activeHandlers);
if (this.context.HasParts)
this.ApplyBuilders(activeHandlers);
@@ -185,8 +186,8 @@ internal sealed class NamePlateGui : IInternalDisposableService, INamePlateGui
Log.Error(e, "Caught exception when calling original AddonNamePlate OnRequestedUpdate.");
}
- this.OnPostNamePlateUpdate?.Invoke(this.context, activeHandlers);
- this.OnPostDataUpdate?.Invoke(this.context, activeHandlers);
+ this.OnPostNamePlateUpdate?.InvokeSafely(this.context, activeHandlers);
+ this.OnPostDataUpdate?.InvokeSafely(this.context, activeHandlers);
}
else
{
@@ -200,8 +201,8 @@ internal sealed class NamePlateGui : IInternalDisposableService, INamePlateGui
if (this.OnDataUpdate is not null)
{
- this.OnDataUpdate?.Invoke(this.context, activeHandlers);
- this.OnNamePlateUpdate?.Invoke(this.context, updatedHandlers);
+ this.OnDataUpdate?.InvokeSafely(this.context, activeHandlers);
+ this.OnNamePlateUpdate?.InvokeSafely(this.context, updatedHandlers);
if (this.context.HasParts)
this.ApplyBuilders(activeHandlers);
@@ -216,12 +217,12 @@ internal sealed class NamePlateGui : IInternalDisposableService, INamePlateGui
Log.Error(e, "Caught exception when calling original AddonNamePlate OnRequestedUpdate.");
}
- this.OnPostNamePlateUpdate?.Invoke(this.context, updatedHandlers);
- this.OnPostDataUpdate?.Invoke(this.context, activeHandlers);
+ this.OnPostNamePlateUpdate?.InvokeSafely(this.context, updatedHandlers);
+ this.OnPostDataUpdate?.InvokeSafely(this.context, activeHandlers);
}
else if (updatedHandlers.Count != 0)
{
- this.OnNamePlateUpdate?.Invoke(this.context, updatedHandlers);
+ this.OnNamePlateUpdate?.InvokeSafely(this.context, updatedHandlers);
if (this.context.HasParts)
this.ApplyBuilders(updatedHandlers);
@@ -236,8 +237,8 @@ internal sealed class NamePlateGui : IInternalDisposableService, INamePlateGui
Log.Error(e, "Caught exception when calling original AddonNamePlate OnRequestedUpdate.");
}
- this.OnPostNamePlateUpdate?.Invoke(this.context, updatedHandlers);
- this.OnPostDataUpdate?.Invoke(this.context, activeHandlers);
+ this.OnPostNamePlateUpdate?.InvokeSafely(this.context, updatedHandlers);
+ this.OnPostDataUpdate?.InvokeSafely(this.context, activeHandlers);
}
}
}
diff --git a/Dalamud/Game/Gui/PartyFinder/PartyFinderGui.cs b/Dalamud/Game/Gui/PartyFinder/PartyFinderGui.cs
index 0b25a87be..5caadb29d 100644
--- a/Dalamud/Game/Gui/PartyFinder/PartyFinderGui.cs
+++ b/Dalamud/Game/Gui/PartyFinder/PartyFinderGui.cs
@@ -89,7 +89,17 @@ internal sealed unsafe class PartyFinderGui : IInternalDisposableService, IParty
var listing = new PartyFinderListing(packet.Listings[i]);
var args = new PartyFinderListingEventArgs(packet.BatchNumber);
- this.ReceiveListing?.Invoke(listing, args);
+ foreach (var d in Delegate.EnumerateInvocationList(this.ReceiveListing))
+ {
+ try
+ {
+ d(listing, args);
+ }
+ catch (Exception ex)
+ {
+ Log.Error(ex, "Exception during raise of {handler}", d.Method);
+ }
+ }
if (args.Visible)
{
diff --git a/Dalamud/Game/Gui/Toast/ToastGui.cs b/Dalamud/Game/Gui/Toast/ToastGui.cs
index 6b55b3408..ab0b05445 100644
--- a/Dalamud/Game/Gui/Toast/ToastGui.cs
+++ b/Dalamud/Game/Gui/Toast/ToastGui.cs
@@ -10,6 +10,8 @@ using Dalamud.Plugin.Services;
using FFXIVClientStructs.FFXIV.Client.UI;
+using Serilog;
+
namespace Dalamud.Game.Gui.Toast;
///
@@ -112,7 +114,7 @@ internal sealed partial class ToastGui
options ??= new ToastOptions();
this.normalQueue.Enqueue((Encoding.UTF8.GetBytes(message), options));
}
-
+
///
public void ShowNormal(SeString message, ToastOptions? options = null)
{
@@ -150,7 +152,17 @@ internal sealed partial class ToastGui
Speed = (ToastSpeed)isFast,
};
- this.Toast?.Invoke(ref str, ref options, ref isHandled);
+ foreach (var d in Delegate.EnumerateInvocationList(this.Toast))
+ {
+ try
+ {
+ d.Invoke(ref str, ref options, ref isHandled);
+ }
+ catch (Exception ex)
+ {
+ Log.Error(ex, "Exception during raise of {handler}", d.Method);
+ }
+ }
// do nothing if handled
if (isHandled)
@@ -180,7 +192,7 @@ internal sealed partial class ToastGui
options ??= new QuestToastOptions();
this.questQueue.Enqueue((Encoding.UTF8.GetBytes(message), options));
}
-
+
///
public void ShowQuest(SeString message, QuestToastOptions? options = null)
{
@@ -223,7 +235,17 @@ internal sealed partial class ToastGui
PlaySound = playSound == 1,
};
- this.QuestToast?.Invoke(ref str, ref options, ref isHandled);
+ foreach (var d in Delegate.EnumerateInvocationList(this.QuestToast))
+ {
+ try
+ {
+ d.Invoke(ref str, ref options, ref isHandled);
+ }
+ catch (Exception ex)
+ {
+ Log.Error(ex, "Exception during raise of {handler}", d.Method);
+ }
+ }
// do nothing if handled
if (isHandled)
@@ -286,7 +308,17 @@ internal sealed partial class ToastGui
var isHandled = false;
var str = SeString.Parse(text);
- this.ErrorToast?.Invoke(ref str, ref isHandled);
+ foreach (var d in Delegate.EnumerateInvocationList(this.ErrorToast))
+ {
+ try
+ {
+ d.Invoke(ref str, ref isHandled);
+ }
+ catch (Exception ex)
+ {
+ Log.Error(ex, "Exception during raise of {handler}", d.Method);
+ }
+ }
// do nothing if handled
if (isHandled)
@@ -321,16 +353,16 @@ internal class ToastGuiPluginScoped : IInternalDisposableService, IToastGui
this.toastGuiService.QuestToast += this.QuestToastForward;
this.toastGuiService.ErrorToast += this.ErrorToastForward;
}
-
+
///
public event IToastGui.OnNormalToastDelegate? Toast;
-
+
///
public event IToastGui.OnQuestToastDelegate? QuestToast;
-
+
///
public event IToastGui.OnErrorToastDelegate? ErrorToast;
-
+
///
void IInternalDisposableService.DisposeService()
{
@@ -342,7 +374,7 @@ internal class ToastGuiPluginScoped : IInternalDisposableService, IToastGui
this.QuestToast = null;
this.ErrorToast = null;
}
-
+
///
public void ShowNormal(string message, ToastOptions? options = null) => this.toastGuiService.ShowNormal(message, options);
diff --git a/Dalamud/Game/Marketboard/MarketBoard.cs b/Dalamud/Game/Marketboard/MarketBoard.cs
index 79de09dea..962e0010e 100644
--- a/Dalamud/Game/Marketboard/MarketBoard.cs
+++ b/Dalamud/Game/Marketboard/MarketBoard.cs
@@ -150,9 +150,7 @@ internal class MarketBoardPluginScoped : IInternalDisposableService, IMarketBoar
private void OnHistoryReceived(IMarketBoardHistory history)
{
- if (this.HistoryReceived == null) return;
-
- foreach (var action in this.HistoryReceived.GetInvocationList().Cast())
+ foreach (var action in Delegate.EnumerateInvocationList(this.HistoryReceived))
{
try
{
@@ -167,9 +165,7 @@ internal class MarketBoardPluginScoped : IInternalDisposableService, IMarketBoar
private void OnItemPurchased(IMarketBoardPurchase purchase)
{
- if (this.ItemPurchased == null) return;
-
- foreach (var action in this.ItemPurchased.GetInvocationList().Cast())
+ foreach (var action in Delegate.EnumerateInvocationList(this.ItemPurchased))
{
try
{
@@ -184,10 +180,7 @@ internal class MarketBoardPluginScoped : IInternalDisposableService, IMarketBoar
private void OnOfferingsReceived(IMarketBoardCurrentOfferings currentOfferings)
{
- if (this.OfferingsReceived == null) return;
-
- foreach (var action in this.OfferingsReceived.GetInvocationList()
- .Cast())
+ foreach (var action in Delegate.EnumerateInvocationList(this.OfferingsReceived))
{
try
{
@@ -202,9 +195,7 @@ internal class MarketBoardPluginScoped : IInternalDisposableService, IMarketBoar
private void OnPurchaseRequested(IMarketBoardPurchaseHandler purchaseHandler)
{
- if (this.PurchaseRequested == null) return;
-
- foreach (var action in this.PurchaseRequested.GetInvocationList().Cast())
+ foreach (var action in Delegate.EnumerateInvocationList(this.PurchaseRequested))
{
try
{
@@ -219,9 +210,7 @@ internal class MarketBoardPluginScoped : IInternalDisposableService, IMarketBoar
private void OnTaxRatesReceived(IMarketTaxRates taxRates)
{
- if (this.TaxRatesReceived == null) return;
-
- foreach (var action in this.TaxRatesReceived.GetInvocationList().Cast())
+ foreach (var action in Delegate.EnumerateInvocationList(this.TaxRatesReceived))
{
try
{
diff --git a/Dalamud/Game/Network/GameNetwork.cs b/Dalamud/Game/Network/GameNetwork.cs
index 5022eb93d..5c21add0f 100644
--- a/Dalamud/Game/Network/GameNetwork.cs
+++ b/Dalamud/Game/Network/GameNetwork.cs
@@ -28,7 +28,7 @@ internal sealed unsafe class GameNetwork : IInternalDisposableService, IGameNetw
[ServiceManager.ServiceDependency]
private readonly DalamudConfiguration configuration = Service.Get();
-
+
[ServiceManager.ServiceConstructor]
private unsafe GameNetwork(TargetSigScanner sigScanner)
{
@@ -71,32 +71,36 @@ internal sealed unsafe class GameNetwork : IInternalDisposableService, IGameNetw
// Go back 0x10 to get back to the start of the packet header
dataPtr -= 0x10;
- try
+ foreach (var d in Delegate.EnumerateInvocationList(this.NetworkMessage))
{
- // Call events
- this.NetworkMessage?.Invoke(dataPtr + 0x20, (ushort)Marshal.ReadInt16(dataPtr, 0x12), 0, targetId, NetworkMessageDirection.ZoneDown);
-
- this.processZonePacketDownHook.Original(dispatcher, targetId, dataPtr + 0x10);
- }
- catch (Exception ex)
- {
- string header;
try
{
- var data = new byte[32];
- Marshal.Copy(dataPtr, data, 0, 32);
- header = BitConverter.ToString(data);
+ d.Invoke(
+ dataPtr + 0x20,
+ (ushort)Marshal.ReadInt16(dataPtr, 0x12),
+ 0,
+ targetId,
+ NetworkMessageDirection.ZoneDown);
}
- catch (Exception)
+ catch (Exception ex)
{
- header = "failed";
+ string header;
+ try
+ {
+ var data = new byte[32];
+ Marshal.Copy(dataPtr, data, 0, 32);
+ header = BitConverter.ToString(data);
+ }
+ catch (Exception)
+ {
+ header = "failed";
+ }
+
+ Log.Error(ex, "Exception on ProcessZonePacketDown hook. Header: " + header);
}
-
- Log.Error(ex, "Exception on ProcessZonePacketDown hook. Header: " + header);
-
- this.processZonePacketDownHook.Original(dispatcher, targetId, dataPtr + 0x10);
}
+ this.processZonePacketDownHook.Original(dispatcher, targetId, dataPtr + 0x10);
this.hitchDetectorDown.Stop();
}
@@ -153,7 +157,7 @@ internal class GameNetworkPluginScoped : IInternalDisposableService, IGameNetwor
{
this.gameNetworkService.NetworkMessage += this.NetworkMessageForward;
}
-
+
///
public event IGameNetwork.OnNetworkMessageDelegate? NetworkMessage;
diff --git a/Dalamud/Hooking/WndProcHook/WndProcHookManager.cs b/Dalamud/Hooking/WndProcHook/WndProcHookManager.cs
index e8e0b7536..7c70a9f0b 100644
--- a/Dalamud/Hooking/WndProcHook/WndProcHookManager.cs
+++ b/Dalamud/Hooking/WndProcHook/WndProcHookManager.cs
@@ -36,7 +36,7 @@ internal sealed class WndProcHookManager : IInternalDisposableService
this.dispatchMessageWHook.Enable();
// Capture the game main window handle,
- // so that no guarantees would have to be made on the service dispose order.
+ // so that no guarantees would have to be made on the service dispose order.
Service
.GetAsync()
.ContinueWith(r => this.mainWindowHwnd = (HWND)r.Result.Manager.GameWindowHandle);
@@ -82,13 +82,16 @@ internal sealed class WndProcHookManager : IInternalDisposableService
/// The arguments.
internal void InvokePreWndProc(WndProcEventArgs args)
{
- try
+ foreach (var d in Delegate.EnumerateInvocationList(this.PreWndProc))
{
- this.PreWndProc?.Invoke(args);
- }
- catch (Exception e)
- {
- Log.Error(e, $"{nameof(this.PreWndProc)} error");
+ try
+ {
+ d(args);
+ }
+ catch (Exception e)
+ {
+ Log.Error(e, $"{nameof(this.PreWndProc)} error calling {d.Method.Name}");
+ }
}
}
@@ -98,13 +101,16 @@ internal sealed class WndProcHookManager : IInternalDisposableService
/// The arguments.
internal void InvokePostWndProc(WndProcEventArgs args)
{
- try
+ foreach (var d in Delegate.EnumerateInvocationList(this.PostWndProc))
{
- this.PostWndProc?.Invoke(args);
- }
- catch (Exception e)
- {
- Log.Error(e, $"{nameof(this.PostWndProc)} error");
+ try
+ {
+ d(args);
+ }
+ catch (Exception e)
+ {
+ Log.Error(e, $"{nameof(this.PostWndProc)} error calling {d.Method.Name}");
+ }
}
}
diff --git a/Dalamud/Interface/ImGuiNotification/Internal/ActiveNotification.cs b/Dalamud/Interface/ImGuiNotification/Internal/ActiveNotification.cs
index c3135853d..77a4925f8 100644
--- a/Dalamud/Interface/ImGuiNotification/Internal/ActiveNotification.cs
+++ b/Dalamud/Interface/ImGuiNotification/Internal/ActiveNotification.cs
@@ -278,7 +278,7 @@ internal sealed partial class ActiveNotification : IActiveNotification
if (@delegate is null)
return null;
- foreach (var il in @delegate.GetInvocationList())
+ foreach (var il in Delegate.EnumerateInvocationList(@delegate))
{
if (il.Target is { } target && !IsOwnedByDalamud(target.GetType()))
@delegate = (T)Delegate.Remove(@delegate, il);
diff --git a/Dalamud/Interface/ImGuiNotification/Internal/NotificationPositionChooser.cs b/Dalamud/Interface/ImGuiNotification/Internal/NotificationPositionChooser.cs
index 2a50c5ae8..9cda48145 100644
--- a/Dalamud/Interface/ImGuiNotification/Internal/NotificationPositionChooser.cs
+++ b/Dalamud/Interface/ImGuiNotification/Internal/NotificationPositionChooser.cs
@@ -3,6 +3,7 @@
using Dalamud.Configuration.Internal;
using Dalamud.Interface.Utility;
using Dalamud.Interface.Utility.Raii;
+using Dalamud.Utility;
using ImGuiNET;
@@ -69,14 +70,14 @@ internal class NotificationPositionChooser
if (ImGui.IsMouseClicked(ImGuiMouseButton.Right))
{
- this.SelectionMade?.Invoke();
+ this.SelectionMade.InvokeSafely();
}
else if (ImGui.IsMouseClicked(ImGuiMouseButton.Left))
{
this.configuration.NotificationAnchorPosition = this.currentAnchorPosition;
this.configuration.QueueSave();
- this.SelectionMade?.Invoke();
+ this.SelectionMade.InvokeSafely();
}
// In the middle of the screen, draw some instructions
diff --git a/Dalamud/Interface/Internal/InterfaceManager.cs b/Dalamud/Interface/Internal/InterfaceManager.cs
index ec175c5aa..ed6fffb4e 100644
--- a/Dalamud/Interface/Internal/InterfaceManager.cs
+++ b/Dalamud/Interface/Internal/InterfaceManager.cs
@@ -832,7 +832,7 @@ internal partial class InterfaceManager : IInternalDisposableService
this.defaultFontResourceLock = fontLocked;
// Broadcast to auto-rebuilding instances.
- this.AfterBuildFonts?.Invoke();
+ this.AfterBuildFonts.InvokeSafely();
});
};
}
diff --git a/Dalamud/Interface/ManagedFontAtlas/Internals/DelegateFontHandle.cs b/Dalamud/Interface/ManagedFontAtlas/Internals/DelegateFontHandle.cs
index 52939385b..39e324ff2 100644
--- a/Dalamud/Interface/ManagedFontAtlas/Internals/DelegateFontHandle.cs
+++ b/Dalamud/Interface/ManagedFontAtlas/Internals/DelegateFontHandle.cs
@@ -66,7 +66,7 @@ internal sealed class DelegateFontHandle : FontHandle
var key = new DelegateFontHandle(this, buildStepDelegate);
lock (this.syncRoot)
this.handles.Add(key);
- this.RebuildRecommend?.Invoke();
+ this.RebuildRecommend.InvokeSafely();
return key;
}
@@ -259,7 +259,7 @@ internal sealed class DelegateFontHandle : FontHandle
}
}
- ///
+ ///
public void OnPreBuildCleanup(IFontAtlasBuildToolkitPreBuild toolkitPreBuild)
{
// irrelevant
diff --git a/Dalamud/Interface/ManagedFontAtlas/Internals/FontAtlasFactory.Implementation.cs b/Dalamud/Interface/ManagedFontAtlas/Internals/FontAtlasFactory.Implementation.cs
index 61ac00faf..2d3b9582c 100644
--- a/Dalamud/Interface/ManagedFontAtlas/Internals/FontAtlasFactory.Implementation.cs
+++ b/Dalamud/Interface/ManagedFontAtlas/Internals/FontAtlasFactory.Implementation.cs
@@ -386,7 +386,7 @@ internal sealed partial class FontAtlasFactory
if (this.disposed)
return;
- this.BeforeDispose?.InvokeSafely(this);
+ this.BeforeDispose.InvokeSafely(this);
try
{
@@ -400,25 +400,11 @@ internal sealed partial class FontAtlasFactory
this.disposables.Dispose();
}
- try
- {
- this.AfterDispose?.Invoke(this, null);
- }
- catch
- {
- // ignore
- }
+ this.AfterDispose.InvokeSafely(this, null);
}
catch (Exception e)
{
- try
- {
- this.AfterDispose?.Invoke(this, e);
- }
- catch
- {
- // ignore
- }
+ this.AfterDispose.InvokeSafely(this, e);
}
GC.SuppressFinalize(this);
@@ -664,7 +650,7 @@ internal sealed partial class FontAtlasFactory
{
res = new(this, scale);
foreach (var fhm in this.fontHandleManagers)
- res.InitialAddSubstance(fhm.NewSubstance(res));
+ res.InitialAddSubstance(fhm.NewSubstance(res));
unsafe
{
atlasPtr = (nint)res.Atlas.NativePtr;
@@ -699,7 +685,7 @@ internal sealed partial class FontAtlasFactory
res = new(this, scale);
foreach (var fhm in this.fontHandleManagers)
- res.InitialAddSubstance(fhm.NewSubstance(res));
+ res.InitialAddSubstance(fhm.NewSubstance(res));
unsafe
{
atlasPtr = (nint)res.Atlas.NativePtr;
@@ -828,7 +814,7 @@ internal sealed partial class FontAtlasFactory
this.factory.Framework.RunOnFrameworkThread(
() =>
{
- this.RebuildRecommend?.InvokeSafely();
+ this.RebuildRecommend.InvokeSafely();
switch (this.AutoRebuildMode)
{
diff --git a/Dalamud/Interface/ManagedFontAtlas/Internals/FontHandle.cs b/Dalamud/Interface/ManagedFontAtlas/Internals/FontHandle.cs
index b84a857da..7f390350c 100644
--- a/Dalamud/Interface/ManagedFontAtlas/Internals/FontHandle.cs
+++ b/Dalamud/Interface/ManagedFontAtlas/Internals/FontHandle.cs
@@ -79,13 +79,16 @@ internal abstract class FontHandle : IFontHandle
/// The font, locked during the call of .
public void InvokeImFontChanged(ILockedImFont font)
{
- try
+ foreach (var d in Delegate.EnumerateInvocationList(this.ImFontChanged))
{
- this.ImFontChanged?.Invoke(this, font);
- }
- catch (Exception e)
- {
- Log.Error(e, $"{nameof(this.InvokeImFontChanged)}: error");
+ try
+ {
+ d(this, font);
+ }
+ catch (Exception e)
+ {
+ Log.Error(e, $"{nameof(this.InvokeImFontChanged)}: error calling {d.Method.Name}");
+ }
}
}
diff --git a/Dalamud/Interface/ManagedFontAtlas/Internals/GamePrebakedFontHandle.cs b/Dalamud/Interface/ManagedFontAtlas/Internals/GamePrebakedFontHandle.cs
index 636bee2e2..3d1dfa674 100644
--- a/Dalamud/Interface/ManagedFontAtlas/Internals/GamePrebakedFontHandle.cs
+++ b/Dalamud/Interface/ManagedFontAtlas/Internals/GamePrebakedFontHandle.cs
@@ -151,7 +151,7 @@ internal class GamePrebakedFontHandle : FontHandle
}
if (suggestRebuild)
- this.RebuildRecommend?.Invoke();
+ this.RebuildRecommend.InvokeSafely();
return handle;
}
@@ -641,7 +641,7 @@ internal class GamePrebakedFontHandle : FontHandle
glyphIndex = (ushort)glyphs.Length;
glyphs.Add(default);
}
-
+
ref var g = ref glyphs[glyphIndex];
g = sourceGlyph;
if (fontScaleMode == FontScaleMode.SkipHandling)
@@ -807,7 +807,7 @@ internal class GamePrebakedFontHandle : FontHandle
.GetCustomRectByIndex(rectId)
.NativePtr;
var widthAdjustment = this.BaseStyle.CalculateBaseWidthAdjustment(fdtFontHeader, fdtGlyph);
-
+
// Glyph is scaled at this point; undo that.
ref var glyph = ref glyphs[lookups[rc.GlyphId]];
glyph.X0 = this.BaseAttr.HorizontalOffset;
@@ -822,7 +822,7 @@ internal class GamePrebakedFontHandle : FontHandle
this.gftp.GetTexFile(this.BaseAttr.TexPathFormat, fdtGlyph.TextureFileIndex);
var sourceBuffer = texFiles[fdtGlyph.TextureFileIndex].ImageData;
var sourceBufferDelta = fdtGlyph.TextureChannelByteIndex;
-
+
for (var y = 0; y < fdtGlyph.BoundingHeight; y++)
{
var sourcePixelIndex =
@@ -830,11 +830,11 @@ internal class GamePrebakedFontHandle : FontHandle
sourcePixelIndex *= 4;
sourcePixelIndex += sourceBufferDelta;
var blend1 = horzBlend[fdtGlyph.CurrentOffsetY + y];
-
+
var targetOffset = ((rc.Y + y) * width) + rc.X;
for (var x = 0; x < rc.Width; x++)
pixels8[targetOffset + x] = 0;
-
+
targetOffset += horzShift[fdtGlyph.CurrentOffsetY + y];
if (blend1 == 0)
{
diff --git a/Dalamud/Localization.cs b/Dalamud/Localization.cs
index 84e8437b3..1e72c3075 100644
--- a/Dalamud/Localization.cs
+++ b/Dalamud/Localization.cs
@@ -117,7 +117,18 @@ public class Localization : IServiceType
public void SetupWithFallbacks()
{
this.DalamudLanguageCultureInfo = CultureInfo.InvariantCulture;
- this.LocalizationChanged?.Invoke(FallbackLangCode);
+ foreach (var d in Delegate.EnumerateInvocationList(this.LocalizationChanged))
+ {
+ try
+ {
+ d(FallbackLangCode);
+ }
+ catch (Exception ex)
+ {
+ Log.Error(ex, "Exception during raise of {handler}", d.Method);
+ }
+ }
+
Loc.SetupWithFallbacks(this.assembly);
}
@@ -134,7 +145,17 @@ public class Localization : IServiceType
}
this.DalamudLanguageCultureInfo = GetCultureInfoFromLangCode(langCode);
- this.LocalizationChanged?.Invoke(langCode);
+ foreach (var d in Delegate.EnumerateInvocationList(this.LocalizationChanged))
+ {
+ try
+ {
+ d(langCode);
+ }
+ catch (Exception ex)
+ {
+ Log.Error(ex, "Exception during raise of {handler}", d.Method);
+ }
+ }
try
{
diff --git a/Dalamud/Plugin/DalamudPluginInterface.cs b/Dalamud/Plugin/DalamudPluginInterface.cs
index f82d241d4..e1c6b7830 100644
--- a/Dalamud/Plugin/DalamudPluginInterface.cs
+++ b/Dalamud/Plugin/DalamudPluginInterface.cs
@@ -527,18 +527,15 @@ internal sealed class DalamudPluginInterface : IDalamudPluginInterface, IDisposa
/// If this plugin was affected by the change.
internal void NotifyActivePluginsChanged(PluginListInvalidationKind kind, bool affectedThisPlugin)
{
- if (this.ActivePluginsChanged is { } callback)
+ foreach (var action in Delegate.EnumerateInvocationList(this.ActivePluginsChanged))
{
- foreach (var action in callback.GetInvocationList().Cast())
+ try
{
- try
- {
- action(kind, affectedThisPlugin);
- }
- catch (Exception ex)
- {
- Log.Error(ex, "Exception during raise of {handler}", action.Method);
- }
+ action(kind, affectedThisPlugin);
+ }
+ catch (Exception ex)
+ {
+ Log.Error(ex, "Exception during raise of {handler}", action.Method);
}
}
}
@@ -547,18 +544,15 @@ internal sealed class DalamudPluginInterface : IDalamudPluginInterface, IDisposa
{
this.UiLanguage = langCode;
- if (this.LanguageChanged is { } callback)
+ foreach (var action in Delegate.EnumerateInvocationList(this.LanguageChanged))
{
- foreach (var action in callback.GetInvocationList().Cast())
+ try
{
- try
- {
- action(langCode);
- }
- catch (Exception ex)
- {
- Log.Error(ex, "Exception during raise of {handler}", action.Method);
- }
+ action(langCode);
+ }
+ catch (Exception ex)
+ {
+ Log.Error(ex, "Exception during raise of {handler}", action.Method);
}
}
}
diff --git a/Dalamud/Utility/EventHandlerExtensions.cs b/Dalamud/Utility/EventHandlerExtensions.cs
index 9bb35a8f1..285e18fa2 100644
--- a/Dalamud/Utility/EventHandlerExtensions.cs
+++ b/Dalamud/Utility/EventHandlerExtensions.cs
@@ -1,7 +1,8 @@
-using System.Linq;
+using System.Collections.Generic;
using Dalamud.Game;
using Dalamud.Game.Gui.ContextMenu;
+using Dalamud.Game.Gui.NamePlate;
using Dalamud.Plugin.Services;
using Serilog;
@@ -14,25 +15,29 @@ 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.
+ /// of a thrown Exception inside 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())
+ foreach (var handler in Delegate.EnumerateInvocationList(eh))
{
- HandleInvoke(() => handler(sender, e));
+ try
+ {
+ handler(sender, e);
+ }
+ catch (Exception ex)
+ {
+ Log.Error(ex, "Exception during raise of {handler}", handler.Method);
+ }
}
}
///
/// Replacement for Invoke() on generic EventHandlers to catch exceptions that stop event propagation in case
- /// of a thrown Exception inside of an invocation.
+ /// of a thrown Exception inside an invocation.
///
/// The EventHandler in question.
/// Default sender for Invoke equivalent.
@@ -40,104 +45,135 @@ internal static class EventHandlerExtensions
/// 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>())
+ foreach (var handler in Delegate.EnumerateInvocationList(eh))
{
- HandleInvoke(() => handler(sender, e));
+ try
+ {
+ handler(sender, e);
+ }
+ catch (Exception ex)
+ {
+ Log.Error(ex, "Exception during raise of {handler}", handler.Method);
+ }
}
}
///
/// Replacement for Invoke() on event Actions to catch exceptions that stop event propagation in case
- /// of a thrown Exception inside of an invocation.
+ /// of a thrown Exception inside an invocation.
///
/// The Action in question.
public static void InvokeSafely(this Action? act)
{
- if (act == null)
- return;
-
- foreach (var action in act.GetInvocationList().Cast())
+ foreach (var action in Delegate.EnumerateInvocationList(act))
{
- HandleInvoke(action);
+ try
+ {
+ action();
+ }
+ catch (Exception ex)
+ {
+ Log.Error(ex, "Exception during raise of {handler}", action.Method);
+ }
}
}
- ///
- /// 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.
- /// Templated argument for Action.
- /// Type of Action args.
+ ///
public static void InvokeSafely(this Action? act, T argument)
{
- if (act == null)
- return;
-
- foreach (var action in act.GetInvocationList().Cast>())
+ foreach (var action in Delegate.EnumerateInvocationList(act))
{
- HandleInvoke(action, argument);
+ try
+ {
+ action(argument);
+ }
+ catch (Exception ex)
+ {
+ Log.Error(ex, "Exception during raise of {handler}", action.Method);
+ }
+ }
+ }
+
+ ///
+ public static void InvokeSafely(this Action? act, T1 arg1, T2 arg2)
+ {
+ foreach (var action in Delegate.EnumerateInvocationList(act))
+ {
+ try
+ {
+ action(arg1, arg2);
+ }
+ catch (Exception ex)
+ {
+ Log.Error(ex, "Exception during raise of {handler}", action.Method);
+ }
}
}
///
/// Replacement for Invoke() on OnUpdateDelegate to catch exceptions that stop event propagation in case
- /// of a thrown Exception inside of an invocation.
+ /// of a thrown Exception inside 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())
+ foreach (var action in Delegate.EnumerateInvocationList(updateDelegate))
{
- HandleInvoke(() => action(framework));
+ try
+ {
+ action(framework);
+ }
+ catch (Exception ex)
+ {
+ Log.Error(ex, "Exception during raise of {handler}", action.Method);
+ }
}
}
///
/// Replacement for Invoke() on OnMenuOpenedDelegate to catch exceptions that stop event propagation in case
- /// of a thrown Exception inside of an invocation.
+ /// of a thrown Exception inside an invocation.
///
/// The OnMenuOpenedDelegate in question.
/// Templated argument for Action.
public static void InvokeSafely(this IContextMenu.OnMenuOpenedDelegate? openedDelegate, MenuOpenedArgs argument)
{
- if (openedDelegate == null)
- return;
-
- foreach (var action in openedDelegate.GetInvocationList().Cast())
+ foreach (var action in Delegate.EnumerateInvocationList(openedDelegate))
{
- HandleInvoke(() => action(argument));
+ try
+ {
+ action(argument);
+ }
+ catch (Exception ex)
+ {
+ Log.Error(ex, "Exception during raise of {handler}", action.Method);
+ }
}
}
- private static void HandleInvoke(Action act)
+ ///
+ /// Replacement for Invoke() on OnMenuOpenedDelegate to catch exceptions that stop event propagation in case
+ /// of a thrown Exception inside an invocation.
+ ///
+ /// The OnMenuOpenedDelegate in question.
+ /// An object containing information about the pending data update.
+ /// A list of handlers used for updating nameplate data.
+ public static void InvokeSafely(
+ this INamePlateGui.OnPlateUpdateDelegate? updatedDelegate,
+ INamePlateUpdateContext context,
+ IReadOnlyList handlers)
{
- try
+ foreach (var action in Delegate.EnumerateInvocationList(updatedDelegate))
{
- act();
- }
- catch (Exception ex)
- {
- Log.Error(ex, "Exception during raise of {handler}", act.Method);
- }
- }
-
- private static void HandleInvoke(Action act, T argument)
- {
- try
- {
- act(argument);
- }
- catch (Exception ex)
- {
- Log.Error(ex, "Exception during raise of {handler}", act.Method);
+ try
+ {
+ action(context, handlers);
+ }
+ catch (Exception ex)
+ {
+ Log.Error(ex, "Exception during raise of {handler}", action.Method);
+ }
}
}
}