mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-12 10:17:22 +01:00
Use EnumerateInvocationList instead of GetInvocationList (#2303)
This commit is contained in:
parent
13306e24ba
commit
03e728e129
24 changed files with 402 additions and 294 deletions
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -184,8 +184,18 @@ internal partial class ConsoleManager : IServiceType
|
||||||
/// <returns>Whether the command was successfully processed.</returns>
|
/// <returns>Whether the command was successfully processed.</returns>
|
||||||
public bool ProcessCommand(string command)
|
public bool ProcessCommand(string command)
|
||||||
{
|
{
|
||||||
if (this.Invoke?.Invoke(command) == true)
|
foreach (var action in Delegate.EnumerateInvocationList(this.Invoke))
|
||||||
return true;
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (action(command))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Error(ex, "Exception during raise of {handler}", action.Method);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var matches = GetCommandParsingRegex().Matches(command);
|
var matches = GetCommandParsingRegex().Matches(command);
|
||||||
if (matches.Count == 0)
|
if (matches.Count == 0)
|
||||||
|
|
|
||||||
|
|
@ -42,10 +42,10 @@ internal sealed class ClientState : IInternalDisposableService, IClientState
|
||||||
|
|
||||||
[ServiceManager.ServiceDependency]
|
[ServiceManager.ServiceDependency]
|
||||||
private readonly Framework framework = Service<Framework>.Get();
|
private readonly Framework framework = Service<Framework>.Get();
|
||||||
|
|
||||||
[ServiceManager.ServiceDependency]
|
[ServiceManager.ServiceDependency]
|
||||||
private readonly NetworkHandlers networkHandlers = Service<NetworkHandlers>.Get();
|
private readonly NetworkHandlers networkHandlers = Service<NetworkHandlers>.Get();
|
||||||
|
|
||||||
private bool lastConditionNone = true;
|
private bool lastConditionNone = true;
|
||||||
|
|
||||||
[ServiceManager.ServiceConstructor]
|
[ServiceManager.ServiceConstructor]
|
||||||
|
|
@ -176,7 +176,7 @@ internal sealed class ClientState : IInternalDisposableService, IClientState
|
||||||
this.uiModuleHandlePacketHook.Dispose();
|
this.uiModuleHandlePacketHook.Dispose();
|
||||||
this.onLogoutHook.Dispose();
|
this.onLogoutHook.Dispose();
|
||||||
|
|
||||||
this.framework.Update -= this.FrameworkOnOnUpdateEvent;
|
this.framework.Update -= this.FrameworkOnOnUpdateEvent;
|
||||||
this.networkHandlers.CfPop -= this.NetworkHandlersOnCfPop;
|
this.networkHandlers.CfPop -= this.NetworkHandlersOnCfPop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -211,50 +211,51 @@ internal sealed class ClientState : IInternalDisposableService, IClientState
|
||||||
this.setupTerritoryTypeHook.Original(eventFramework, territoryType);
|
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);
|
this.uiModuleHandlePacketHook.Original(thisPtr, type, uintParam, packet);
|
||||||
|
|
||||||
switch (type)
|
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;
|
try
|
||||||
|
|
||||||
foreach (var action in callback.GetInvocationList().Cast<IClientState.ClassJobChangeDelegate>())
|
|
||||||
{
|
{
|
||||||
try
|
action(classJobId);
|
||||||
{
|
}
|
||||||
action(classJobId);
|
catch (Exception ex)
|
||||||
}
|
{
|
||||||
catch (Exception ex)
|
Log.Error(ex, "Exception during raise of {handler}", action.Method);
|
||||||
{
|
|
||||||
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;
|
try
|
||||||
var level = *(ushort*)((nint)packet + 4);
|
|
||||||
|
|
||||||
foreach (var action in callback.GetInvocationList().Cast<IClientState.LevelChangeDelegate>())
|
|
||||||
{
|
{
|
||||||
try
|
action(classJobId, level);
|
||||||
{
|
}
|
||||||
action(classJobId, level);
|
catch (Exception ex)
|
||||||
}
|
{
|
||||||
catch (Exception ex)
|
Log.Error(ex, "Exception during raise of {handler}", action.Method);
|
||||||
{
|
|
||||||
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);
|
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<IClientState.LogoutDelegate>())
|
try
|
||||||
{
|
{
|
||||||
try
|
action(type, code);
|
||||||
{
|
}
|
||||||
action(type, code);
|
catch (Exception ex)
|
||||||
}
|
{
|
||||||
catch (Exception ex)
|
Log.Error(ex, "Exception during raise of {handler}", action.Method);
|
||||||
{
|
|
||||||
Log.Error(ex, "Exception during raise of {handler}", action.Method);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ internal sealed class Condition : IInternalDisposableService, ICondition
|
||||||
|
|
||||||
[ServiceManager.ServiceDependency]
|
[ServiceManager.ServiceDependency]
|
||||||
private readonly Framework framework = Service<Framework>.Get();
|
private readonly Framework framework = Service<Framework>.Get();
|
||||||
|
|
||||||
private readonly bool[] cache = new bool[MaxConditionEntries];
|
private readonly bool[] cache = new bool[MaxConditionEntries];
|
||||||
|
|
||||||
private bool isDisposed;
|
private bool isDisposed;
|
||||||
|
|
@ -38,7 +38,7 @@ internal sealed class Condition : IInternalDisposableService, ICondition
|
||||||
|
|
||||||
this.framework.Update += this.FrameworkUpdate;
|
this.framework.Update += this.FrameworkUpdate;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Finalizes an instance of the <see cref="Condition" /> class.</summary>
|
/// <summary>Finalizes an instance of the <see cref="Condition" /> class.</summary>
|
||||||
~Condition() => this.Dispose(false);
|
~Condition() => this.Dispose(false);
|
||||||
|
|
||||||
|
|
@ -69,12 +69,12 @@ internal sealed class Condition : IInternalDisposableService, ICondition
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
void IInternalDisposableService.DisposeService() => this.Dispose(true);
|
void IInternalDisposableService.DisposeService() => this.Dispose(true);
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public IReadOnlySet<ConditionFlag> AsReadOnlySet()
|
public IReadOnlySet<ConditionFlag> AsReadOnlySet()
|
||||||
{
|
{
|
||||||
var result = new HashSet<ConditionFlag>();
|
var result = new HashSet<ConditionFlag>();
|
||||||
|
|
||||||
for (var i = 0; i < MaxConditionEntries; i++)
|
for (var i = 0; i < MaxConditionEntries; i++)
|
||||||
{
|
{
|
||||||
if (this[i])
|
if (this[i])
|
||||||
|
|
@ -99,14 +99,14 @@ internal sealed class Condition : IInternalDisposableService, ICondition
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public bool Any(params ConditionFlag[] flags)
|
public bool Any(params ConditionFlag[] flags)
|
||||||
{
|
{
|
||||||
foreach (var flag in flags)
|
foreach (var flag in flags)
|
||||||
{
|
{
|
||||||
// this[i] performs range checking, so no need to check here
|
// this[i] performs range checking, so no need to check here
|
||||||
if (this[flag])
|
if (this[flag])
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -114,7 +114,7 @@ internal sealed class Condition : IInternalDisposableService, ICondition
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public bool AnyExcept(params ConditionFlag[] excluded)
|
public bool AnyExcept(params ConditionFlag[] excluded)
|
||||||
{
|
{
|
||||||
|
|
@ -157,13 +157,16 @@ internal sealed class Condition : IInternalDisposableService, ICondition
|
||||||
{
|
{
|
||||||
this.cache[i] = value;
|
this.cache[i] = value;
|
||||||
|
|
||||||
try
|
foreach (var d in Delegate.EnumerateInvocationList(this.ConditionChange))
|
||||||
{
|
{
|
||||||
this.ConditionChange?.Invoke((ConditionFlag)i, value);
|
try
|
||||||
}
|
{
|
||||||
catch (Exception ex)
|
d((ConditionFlag)i, value);
|
||||||
{
|
}
|
||||||
Log.Error(ex, $"While invoking {nameof(this.ConditionChange)}, an exception was thrown.");
|
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;
|
this.conditionService.ConditionChange += this.ConditionChangedForward;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public event ICondition.ConditionChangeDelegate? ConditionChange;
|
public event ICondition.ConditionChangeDelegate? ConditionChange;
|
||||||
|
|
||||||
|
|
@ -202,7 +205,7 @@ internal class ConditionPluginScoped : IInternalDisposableService, ICondition
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public bool this[int flag] => this.conditionService[flag];
|
public bool this[int flag] => this.conditionService[flag];
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
void IInternalDisposableService.DisposeService()
|
void IInternalDisposableService.DisposeService()
|
||||||
{
|
{
|
||||||
|
|
@ -210,7 +213,7 @@ internal class ConditionPluginScoped : IInternalDisposableService, ICondition
|
||||||
|
|
||||||
this.ConditionChange = null;
|
this.ConditionChange = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public IReadOnlySet<ConditionFlag> AsReadOnlySet() => this.conditionService.AsReadOnlySet();
|
public IReadOnlySet<ConditionFlag> AsReadOnlySet() => this.conditionService.AsReadOnlySet();
|
||||||
|
|
||||||
|
|
@ -222,10 +225,10 @@ internal class ConditionPluginScoped : IInternalDisposableService, ICondition
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public bool AnyExcept(params ConditionFlag[] except) => this.conditionService.AnyExcept(except);
|
public bool AnyExcept(params ConditionFlag[] except) => this.conditionService.AnyExcept(except);
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public bool OnlyAny(params ConditionFlag[] other) => this.conditionService.OnlyAny(other);
|
public bool OnlyAny(params ConditionFlag[] other) => this.conditionService.OnlyAny(other);
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public bool EqualTo(params ConditionFlag[] other) => this.conditionService.EqualTo(other);
|
public bool EqualTo(params ConditionFlag[] other) => this.conditionService.EqualTo(other);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -132,7 +132,7 @@ internal sealed unsafe class CommandManager : IInternalDisposableService, IComma
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.CommandAdded?.Invoke(this, new CommandEventArgs
|
this.CommandAdded?.InvokeSafely(this, new CommandEventArgs
|
||||||
{
|
{
|
||||||
Command = command,
|
Command = command,
|
||||||
CommandInfo = info,
|
CommandInfo = info,
|
||||||
|
|
@ -160,7 +160,7 @@ internal sealed unsafe class CommandManager : IInternalDisposableService, IComma
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.CommandAdded?.Invoke(this, new CommandEventArgs
|
this.CommandAdded?.InvokeSafely(this, new CommandEventArgs
|
||||||
{
|
{
|
||||||
Command = command,
|
Command = command,
|
||||||
CommandInfo = info,
|
CommandInfo = info,
|
||||||
|
|
@ -180,7 +180,7 @@ internal sealed unsafe class CommandManager : IInternalDisposableService, IComma
|
||||||
var removed = this.commandMap.Remove(command, out var info);
|
var removed = this.commandMap.Remove(command, out var info);
|
||||||
if (removed)
|
if (removed)
|
||||||
{
|
{
|
||||||
this.CommandRemoved?.Invoke(this, new CommandEventArgs
|
this.CommandRemoved?.InvokeSafely(this, new CommandEventArgs
|
||||||
{
|
{
|
||||||
Command = command,
|
Command = command,
|
||||||
CommandInfo = info,
|
CommandInfo = info,
|
||||||
|
|
|
||||||
|
|
@ -350,17 +350,13 @@ internal sealed class Framework : IInternalDisposableService, IFramework
|
||||||
/// <param name="frameworkInstance">The Framework Instance to pass to delegate.</param>
|
/// <param name="frameworkInstance">The Framework Instance to pass to delegate.</param>
|
||||||
internal void ProfileAndInvoke(IFramework.OnUpdateDelegate? eventDelegate, IFramework frameworkInstance)
|
internal void ProfileAndInvoke(IFramework.OnUpdateDelegate? eventDelegate, IFramework frameworkInstance)
|
||||||
{
|
{
|
||||||
if (eventDelegate is null) return;
|
|
||||||
|
|
||||||
var invokeList = eventDelegate.GetInvocationList();
|
|
||||||
|
|
||||||
// Individually invoke OnUpdate handlers and time them.
|
// Individually invoke OnUpdate handlers and time them.
|
||||||
foreach (var d in invokeList)
|
foreach (var d in Delegate.EnumerateInvocationList(eventDelegate))
|
||||||
{
|
{
|
||||||
var stopwatch = Stopwatch.StartNew();
|
var stopwatch = Stopwatch.StartNew();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
d.Method.Invoke(d.Target, new object[] { frameworkInstance });
|
d(frameworkInstance);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|
@ -370,8 +366,7 @@ internal sealed class Framework : IInternalDisposableService, IFramework
|
||||||
stopwatch.Stop();
|
stopwatch.Stop();
|
||||||
|
|
||||||
var key = $"{d.Target}::{d.Method.Name}";
|
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);
|
AddToStats(key, stopwatch.Elapsed.TotalMilliseconds);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -346,24 +346,21 @@ internal sealed unsafe class ChatGui : IInternalDisposableService, IChatGui
|
||||||
// Call events
|
// Call events
|
||||||
var isHandled = false;
|
var isHandled = false;
|
||||||
|
|
||||||
if (this.CheckMessageHandled is { } handledCallback)
|
foreach (var action in Delegate.EnumerateInvocationList(this.CheckMessageHandled))
|
||||||
{
|
{
|
||||||
foreach (var action in handledCallback.GetInvocationList().Cast<IChatGui.OnCheckMessageHandledDelegate>())
|
try
|
||||||
{
|
{
|
||||||
try
|
action(chatType, timestamp, ref parsedSender, ref parsedMessage, ref isHandled);
|
||||||
{
|
}
|
||||||
action(chatType, timestamp, ref parsedSender, ref parsedMessage, ref isHandled);
|
catch (Exception e)
|
||||||
}
|
{
|
||||||
catch (Exception e)
|
Log.Error(e, "Could not invoke registered OnCheckMessageHandledDelegate for {Name}", action.Method);
|
||||||
{
|
|
||||||
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<IChatGui.OnMessageDelegate>())
|
foreach (var action in Delegate.EnumerateInvocationList(this.ChatMessage))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -394,12 +391,14 @@ internal sealed unsafe class ChatGui : IInternalDisposableService, IChatGui
|
||||||
// Print the original chat if it's handled.
|
// Print the original chat if it's handled.
|
||||||
if (isHandled)
|
if (isHandled)
|
||||||
{
|
{
|
||||||
this.ChatMessageHandled?.Invoke(chatType, timestamp, parsedSender, parsedMessage);
|
foreach (var d in Delegate.EnumerateInvocationList(this.ChatMessageHandled))
|
||||||
|
d(chatType, timestamp, parsedSender, parsedMessage);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
messageId = this.printMessageHook.Original(manager, chatType, sender, message, timestamp, silent);
|
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)
|
catch (Exception ex)
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,7 @@ internal sealed class FlyTextGui : IInternalDisposableService, IFlyTextGui
|
||||||
|
|
||||||
strArray->SetValue((int)strOffset + 0, text1.EncodeWithNullTerminator(), false, true, false);
|
strArray->SetValue((int)strOffset + 0, text1.EncodeWithNullTerminator(), false, true, false);
|
||||||
strArray->SetValue((int)strOffset + 1, text2.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);
|
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}\") " +
|
$"text1({(nint)text1:X}, \"{tmpText1}\") text2({(nint)text2:X}, \"{tmpText2}\") " +
|
||||||
$"color({color:X}) icon({icon}) yOffset({yOffset})");
|
$"color({color:X}) icon({icon}) yOffset({yOffset})");
|
||||||
Log.Verbose("[FlyText] Calling flytext events!");
|
Log.Verbose("[FlyText] Calling flytext events!");
|
||||||
this.FlyTextCreated?.Invoke(
|
foreach (var d in Delegate.EnumerateInvocationList(this.FlyTextCreated))
|
||||||
ref tmpKind,
|
{
|
||||||
ref tmpVal1,
|
try
|
||||||
ref tmpVal2,
|
{
|
||||||
ref tmpText1,
|
d(
|
||||||
ref tmpText2,
|
ref tmpKind,
|
||||||
ref tmpColor,
|
ref tmpVal1,
|
||||||
ref tmpIcon,
|
ref tmpVal2,
|
||||||
ref tmpDamageTypeIcon,
|
ref tmpText1,
|
||||||
ref tmpYOffset,
|
ref tmpText2,
|
||||||
ref handled);
|
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, ignore the original call
|
||||||
if (handled)
|
if (handled)
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ using Dalamud.Hooking;
|
||||||
using Dalamud.IoC;
|
using Dalamud.IoC;
|
||||||
using Dalamud.IoC.Internal;
|
using Dalamud.IoC.Internal;
|
||||||
using Dalamud.Plugin.Services;
|
using Dalamud.Plugin.Services;
|
||||||
|
using Dalamud.Utility;
|
||||||
|
|
||||||
using FFXIVClientStructs.FFXIV.Client.UI;
|
using FFXIVClientStructs.FFXIV.Client.UI;
|
||||||
using FFXIVClientStructs.FFXIV.Component.GUI;
|
using FFXIVClientStructs.FFXIV.Component.GUI;
|
||||||
|
|
@ -169,8 +170,8 @@ internal sealed class NamePlateGui : IInternalDisposableService, INamePlateGui
|
||||||
handler.ResetState();
|
handler.ResetState();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.OnDataUpdate?.Invoke(this.context, activeHandlers);
|
this.OnDataUpdate?.InvokeSafely(this.context, activeHandlers);
|
||||||
this.OnNamePlateUpdate?.Invoke(this.context, activeHandlers);
|
this.OnNamePlateUpdate?.InvokeSafely(this.context, activeHandlers);
|
||||||
|
|
||||||
if (this.context.HasParts)
|
if (this.context.HasParts)
|
||||||
this.ApplyBuilders(activeHandlers);
|
this.ApplyBuilders(activeHandlers);
|
||||||
|
|
@ -185,8 +186,8 @@ internal sealed class NamePlateGui : IInternalDisposableService, INamePlateGui
|
||||||
Log.Error(e, "Caught exception when calling original AddonNamePlate OnRequestedUpdate.");
|
Log.Error(e, "Caught exception when calling original AddonNamePlate OnRequestedUpdate.");
|
||||||
}
|
}
|
||||||
|
|
||||||
this.OnPostNamePlateUpdate?.Invoke(this.context, activeHandlers);
|
this.OnPostNamePlateUpdate?.InvokeSafely(this.context, activeHandlers);
|
||||||
this.OnPostDataUpdate?.Invoke(this.context, activeHandlers);
|
this.OnPostDataUpdate?.InvokeSafely(this.context, activeHandlers);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -200,8 +201,8 @@ internal sealed class NamePlateGui : IInternalDisposableService, INamePlateGui
|
||||||
|
|
||||||
if (this.OnDataUpdate is not null)
|
if (this.OnDataUpdate is not null)
|
||||||
{
|
{
|
||||||
this.OnDataUpdate?.Invoke(this.context, activeHandlers);
|
this.OnDataUpdate?.InvokeSafely(this.context, activeHandlers);
|
||||||
this.OnNamePlateUpdate?.Invoke(this.context, updatedHandlers);
|
this.OnNamePlateUpdate?.InvokeSafely(this.context, updatedHandlers);
|
||||||
|
|
||||||
if (this.context.HasParts)
|
if (this.context.HasParts)
|
||||||
this.ApplyBuilders(activeHandlers);
|
this.ApplyBuilders(activeHandlers);
|
||||||
|
|
@ -216,12 +217,12 @@ internal sealed class NamePlateGui : IInternalDisposableService, INamePlateGui
|
||||||
Log.Error(e, "Caught exception when calling original AddonNamePlate OnRequestedUpdate.");
|
Log.Error(e, "Caught exception when calling original AddonNamePlate OnRequestedUpdate.");
|
||||||
}
|
}
|
||||||
|
|
||||||
this.OnPostNamePlateUpdate?.Invoke(this.context, updatedHandlers);
|
this.OnPostNamePlateUpdate?.InvokeSafely(this.context, updatedHandlers);
|
||||||
this.OnPostDataUpdate?.Invoke(this.context, activeHandlers);
|
this.OnPostDataUpdate?.InvokeSafely(this.context, activeHandlers);
|
||||||
}
|
}
|
||||||
else if (updatedHandlers.Count != 0)
|
else if (updatedHandlers.Count != 0)
|
||||||
{
|
{
|
||||||
this.OnNamePlateUpdate?.Invoke(this.context, updatedHandlers);
|
this.OnNamePlateUpdate?.InvokeSafely(this.context, updatedHandlers);
|
||||||
|
|
||||||
if (this.context.HasParts)
|
if (this.context.HasParts)
|
||||||
this.ApplyBuilders(updatedHandlers);
|
this.ApplyBuilders(updatedHandlers);
|
||||||
|
|
@ -236,8 +237,8 @@ internal sealed class NamePlateGui : IInternalDisposableService, INamePlateGui
|
||||||
Log.Error(e, "Caught exception when calling original AddonNamePlate OnRequestedUpdate.");
|
Log.Error(e, "Caught exception when calling original AddonNamePlate OnRequestedUpdate.");
|
||||||
}
|
}
|
||||||
|
|
||||||
this.OnPostNamePlateUpdate?.Invoke(this.context, updatedHandlers);
|
this.OnPostNamePlateUpdate?.InvokeSafely(this.context, updatedHandlers);
|
||||||
this.OnPostDataUpdate?.Invoke(this.context, activeHandlers);
|
this.OnPostDataUpdate?.InvokeSafely(this.context, activeHandlers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,17 @@ internal sealed unsafe class PartyFinderGui : IInternalDisposableService, IParty
|
||||||
|
|
||||||
var listing = new PartyFinderListing(packet.Listings[i]);
|
var listing = new PartyFinderListing(packet.Listings[i]);
|
||||||
var args = new PartyFinderListingEventArgs(packet.BatchNumber);
|
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)
|
if (args.Visible)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,8 @@ using Dalamud.Plugin.Services;
|
||||||
|
|
||||||
using FFXIVClientStructs.FFXIV.Client.UI;
|
using FFXIVClientStructs.FFXIV.Client.UI;
|
||||||
|
|
||||||
|
using Serilog;
|
||||||
|
|
||||||
namespace Dalamud.Game.Gui.Toast;
|
namespace Dalamud.Game.Gui.Toast;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -112,7 +114,7 @@ internal sealed partial class ToastGui
|
||||||
options ??= new ToastOptions();
|
options ??= new ToastOptions();
|
||||||
this.normalQueue.Enqueue((Encoding.UTF8.GetBytes(message), options));
|
this.normalQueue.Enqueue((Encoding.UTF8.GetBytes(message), options));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public void ShowNormal(SeString message, ToastOptions? options = null)
|
public void ShowNormal(SeString message, ToastOptions? options = null)
|
||||||
{
|
{
|
||||||
|
|
@ -150,7 +152,17 @@ internal sealed partial class ToastGui
|
||||||
Speed = (ToastSpeed)isFast,
|
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
|
// do nothing if handled
|
||||||
if (isHandled)
|
if (isHandled)
|
||||||
|
|
@ -180,7 +192,7 @@ internal sealed partial class ToastGui
|
||||||
options ??= new QuestToastOptions();
|
options ??= new QuestToastOptions();
|
||||||
this.questQueue.Enqueue((Encoding.UTF8.GetBytes(message), options));
|
this.questQueue.Enqueue((Encoding.UTF8.GetBytes(message), options));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public void ShowQuest(SeString message, QuestToastOptions? options = null)
|
public void ShowQuest(SeString message, QuestToastOptions? options = null)
|
||||||
{
|
{
|
||||||
|
|
@ -223,7 +235,17 @@ internal sealed partial class ToastGui
|
||||||
PlaySound = playSound == 1,
|
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
|
// do nothing if handled
|
||||||
if (isHandled)
|
if (isHandled)
|
||||||
|
|
@ -286,7 +308,17 @@ internal sealed partial class ToastGui
|
||||||
var isHandled = false;
|
var isHandled = false;
|
||||||
var str = SeString.Parse(text);
|
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
|
// do nothing if handled
|
||||||
if (isHandled)
|
if (isHandled)
|
||||||
|
|
@ -321,16 +353,16 @@ internal class ToastGuiPluginScoped : IInternalDisposableService, IToastGui
|
||||||
this.toastGuiService.QuestToast += this.QuestToastForward;
|
this.toastGuiService.QuestToast += this.QuestToastForward;
|
||||||
this.toastGuiService.ErrorToast += this.ErrorToastForward;
|
this.toastGuiService.ErrorToast += this.ErrorToastForward;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public event IToastGui.OnNormalToastDelegate? Toast;
|
public event IToastGui.OnNormalToastDelegate? Toast;
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public event IToastGui.OnQuestToastDelegate? QuestToast;
|
public event IToastGui.OnQuestToastDelegate? QuestToast;
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public event IToastGui.OnErrorToastDelegate? ErrorToast;
|
public event IToastGui.OnErrorToastDelegate? ErrorToast;
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
void IInternalDisposableService.DisposeService()
|
void IInternalDisposableService.DisposeService()
|
||||||
{
|
{
|
||||||
|
|
@ -342,7 +374,7 @@ internal class ToastGuiPluginScoped : IInternalDisposableService, IToastGui
|
||||||
this.QuestToast = null;
|
this.QuestToast = null;
|
||||||
this.ErrorToast = null;
|
this.ErrorToast = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public void ShowNormal(string message, ToastOptions? options = null) => this.toastGuiService.ShowNormal(message, options);
|
public void ShowNormal(string message, ToastOptions? options = null) => this.toastGuiService.ShowNormal(message, options);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -150,9 +150,7 @@ internal class MarketBoardPluginScoped : IInternalDisposableService, IMarketBoar
|
||||||
|
|
||||||
private void OnHistoryReceived(IMarketBoardHistory history)
|
private void OnHistoryReceived(IMarketBoardHistory history)
|
||||||
{
|
{
|
||||||
if (this.HistoryReceived == null) return;
|
foreach (var action in Delegate.EnumerateInvocationList(this.HistoryReceived))
|
||||||
|
|
||||||
foreach (var action in this.HistoryReceived.GetInvocationList().Cast<HistoryReceivedDelegate>())
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -167,9 +165,7 @@ internal class MarketBoardPluginScoped : IInternalDisposableService, IMarketBoar
|
||||||
|
|
||||||
private void OnItemPurchased(IMarketBoardPurchase purchase)
|
private void OnItemPurchased(IMarketBoardPurchase purchase)
|
||||||
{
|
{
|
||||||
if (this.ItemPurchased == null) return;
|
foreach (var action in Delegate.EnumerateInvocationList(this.ItemPurchased))
|
||||||
|
|
||||||
foreach (var action in this.ItemPurchased.GetInvocationList().Cast<ItemPurchasedDelegate>())
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -184,10 +180,7 @@ internal class MarketBoardPluginScoped : IInternalDisposableService, IMarketBoar
|
||||||
|
|
||||||
private void OnOfferingsReceived(IMarketBoardCurrentOfferings currentOfferings)
|
private void OnOfferingsReceived(IMarketBoardCurrentOfferings currentOfferings)
|
||||||
{
|
{
|
||||||
if (this.OfferingsReceived == null) return;
|
foreach (var action in Delegate.EnumerateInvocationList(this.OfferingsReceived))
|
||||||
|
|
||||||
foreach (var action in this.OfferingsReceived.GetInvocationList()
|
|
||||||
.Cast<OfferingsReceivedDelegate>())
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -202,9 +195,7 @@ internal class MarketBoardPluginScoped : IInternalDisposableService, IMarketBoar
|
||||||
|
|
||||||
private void OnPurchaseRequested(IMarketBoardPurchaseHandler purchaseHandler)
|
private void OnPurchaseRequested(IMarketBoardPurchaseHandler purchaseHandler)
|
||||||
{
|
{
|
||||||
if (this.PurchaseRequested == null) return;
|
foreach (var action in Delegate.EnumerateInvocationList(this.PurchaseRequested))
|
||||||
|
|
||||||
foreach (var action in this.PurchaseRequested.GetInvocationList().Cast<PurchaseRequestedDelegate>())
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -219,9 +210,7 @@ internal class MarketBoardPluginScoped : IInternalDisposableService, IMarketBoar
|
||||||
|
|
||||||
private void OnTaxRatesReceived(IMarketTaxRates taxRates)
|
private void OnTaxRatesReceived(IMarketTaxRates taxRates)
|
||||||
{
|
{
|
||||||
if (this.TaxRatesReceived == null) return;
|
foreach (var action in Delegate.EnumerateInvocationList(this.TaxRatesReceived))
|
||||||
|
|
||||||
foreach (var action in this.TaxRatesReceived.GetInvocationList().Cast<TaxRatesReceivedDelegate>())
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ internal sealed unsafe class GameNetwork : IInternalDisposableService, IGameNetw
|
||||||
|
|
||||||
[ServiceManager.ServiceDependency]
|
[ServiceManager.ServiceDependency]
|
||||||
private readonly DalamudConfiguration configuration = Service<DalamudConfiguration>.Get();
|
private readonly DalamudConfiguration configuration = Service<DalamudConfiguration>.Get();
|
||||||
|
|
||||||
[ServiceManager.ServiceConstructor]
|
[ServiceManager.ServiceConstructor]
|
||||||
private unsafe GameNetwork(TargetSigScanner sigScanner)
|
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
|
// Go back 0x10 to get back to the start of the packet header
|
||||||
dataPtr -= 0x10;
|
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
|
try
|
||||||
{
|
{
|
||||||
var data = new byte[32];
|
d.Invoke(
|
||||||
Marshal.Copy(dataPtr, data, 0, 32);
|
dataPtr + 0x20,
|
||||||
header = BitConverter.ToString(data);
|
(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();
|
this.hitchDetectorDown.Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -153,7 +157,7 @@ internal class GameNetworkPluginScoped : IInternalDisposableService, IGameNetwor
|
||||||
{
|
{
|
||||||
this.gameNetworkService.NetworkMessage += this.NetworkMessageForward;
|
this.gameNetworkService.NetworkMessage += this.NetworkMessageForward;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public event IGameNetwork.OnNetworkMessageDelegate? NetworkMessage;
|
public event IGameNetwork.OnNetworkMessageDelegate? NetworkMessage;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ internal sealed class WndProcHookManager : IInternalDisposableService
|
||||||
this.dispatchMessageWHook.Enable();
|
this.dispatchMessageWHook.Enable();
|
||||||
|
|
||||||
// Capture the game main window handle,
|
// 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<InterfaceManager.InterfaceManagerWithScene>
|
Service<InterfaceManager.InterfaceManagerWithScene>
|
||||||
.GetAsync()
|
.GetAsync()
|
||||||
.ContinueWith(r => this.mainWindowHwnd = (HWND)r.Result.Manager.GameWindowHandle);
|
.ContinueWith(r => this.mainWindowHwnd = (HWND)r.Result.Manager.GameWindowHandle);
|
||||||
|
|
@ -82,13 +82,16 @@ internal sealed class WndProcHookManager : IInternalDisposableService
|
||||||
/// <param name="args">The arguments.</param>
|
/// <param name="args">The arguments.</param>
|
||||||
internal void InvokePreWndProc(WndProcEventArgs args)
|
internal void InvokePreWndProc(WndProcEventArgs args)
|
||||||
{
|
{
|
||||||
try
|
foreach (var d in Delegate.EnumerateInvocationList(this.PreWndProc))
|
||||||
{
|
{
|
||||||
this.PreWndProc?.Invoke(args);
|
try
|
||||||
}
|
{
|
||||||
catch (Exception e)
|
d(args);
|
||||||
{
|
}
|
||||||
Log.Error(e, $"{nameof(this.PreWndProc)} error");
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Log.Error(e, $"{nameof(this.PreWndProc)} error calling {d.Method.Name}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -98,13 +101,16 @@ internal sealed class WndProcHookManager : IInternalDisposableService
|
||||||
/// <param name="args">The arguments.</param>
|
/// <param name="args">The arguments.</param>
|
||||||
internal void InvokePostWndProc(WndProcEventArgs args)
|
internal void InvokePostWndProc(WndProcEventArgs args)
|
||||||
{
|
{
|
||||||
try
|
foreach (var d in Delegate.EnumerateInvocationList(this.PostWndProc))
|
||||||
{
|
{
|
||||||
this.PostWndProc?.Invoke(args);
|
try
|
||||||
}
|
{
|
||||||
catch (Exception e)
|
d(args);
|
||||||
{
|
}
|
||||||
Log.Error(e, $"{nameof(this.PostWndProc)} error");
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Log.Error(e, $"{nameof(this.PostWndProc)} error calling {d.Method.Name}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -278,7 +278,7 @@ internal sealed partial class ActiveNotification : IActiveNotification
|
||||||
if (@delegate is null)
|
if (@delegate is null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
foreach (var il in @delegate.GetInvocationList())
|
foreach (var il in Delegate.EnumerateInvocationList(@delegate))
|
||||||
{
|
{
|
||||||
if (il.Target is { } target && !IsOwnedByDalamud(target.GetType()))
|
if (il.Target is { } target && !IsOwnedByDalamud(target.GetType()))
|
||||||
@delegate = (T)Delegate.Remove(@delegate, il);
|
@delegate = (T)Delegate.Remove(@delegate, il);
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
using Dalamud.Configuration.Internal;
|
using Dalamud.Configuration.Internal;
|
||||||
using Dalamud.Interface.Utility;
|
using Dalamud.Interface.Utility;
|
||||||
using Dalamud.Interface.Utility.Raii;
|
using Dalamud.Interface.Utility.Raii;
|
||||||
|
using Dalamud.Utility;
|
||||||
|
|
||||||
using ImGuiNET;
|
using ImGuiNET;
|
||||||
|
|
||||||
|
|
@ -69,14 +70,14 @@ internal class NotificationPositionChooser
|
||||||
|
|
||||||
if (ImGui.IsMouseClicked(ImGuiMouseButton.Right))
|
if (ImGui.IsMouseClicked(ImGuiMouseButton.Right))
|
||||||
{
|
{
|
||||||
this.SelectionMade?.Invoke();
|
this.SelectionMade.InvokeSafely();
|
||||||
}
|
}
|
||||||
else if (ImGui.IsMouseClicked(ImGuiMouseButton.Left))
|
else if (ImGui.IsMouseClicked(ImGuiMouseButton.Left))
|
||||||
{
|
{
|
||||||
this.configuration.NotificationAnchorPosition = this.currentAnchorPosition;
|
this.configuration.NotificationAnchorPosition = this.currentAnchorPosition;
|
||||||
this.configuration.QueueSave();
|
this.configuration.QueueSave();
|
||||||
|
|
||||||
this.SelectionMade?.Invoke();
|
this.SelectionMade.InvokeSafely();
|
||||||
}
|
}
|
||||||
|
|
||||||
// In the middle of the screen, draw some instructions
|
// In the middle of the screen, draw some instructions
|
||||||
|
|
|
||||||
|
|
@ -832,7 +832,7 @@ internal partial class InterfaceManager : IInternalDisposableService
|
||||||
this.defaultFontResourceLock = fontLocked;
|
this.defaultFontResourceLock = fontLocked;
|
||||||
|
|
||||||
// Broadcast to auto-rebuilding instances.
|
// Broadcast to auto-rebuilding instances.
|
||||||
this.AfterBuildFonts?.Invoke();
|
this.AfterBuildFonts.InvokeSafely();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ internal sealed class DelegateFontHandle : FontHandle
|
||||||
var key = new DelegateFontHandle(this, buildStepDelegate);
|
var key = new DelegateFontHandle(this, buildStepDelegate);
|
||||||
lock (this.syncRoot)
|
lock (this.syncRoot)
|
||||||
this.handles.Add(key);
|
this.handles.Add(key);
|
||||||
this.RebuildRecommend?.Invoke();
|
this.RebuildRecommend.InvokeSafely();
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -259,7 +259,7 @@ internal sealed class DelegateFontHandle : FontHandle
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public void OnPreBuildCleanup(IFontAtlasBuildToolkitPreBuild toolkitPreBuild)
|
public void OnPreBuildCleanup(IFontAtlasBuildToolkitPreBuild toolkitPreBuild)
|
||||||
{
|
{
|
||||||
// irrelevant
|
// irrelevant
|
||||||
|
|
|
||||||
|
|
@ -386,7 +386,7 @@ internal sealed partial class FontAtlasFactory
|
||||||
if (this.disposed)
|
if (this.disposed)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
this.BeforeDispose?.InvokeSafely(this);
|
this.BeforeDispose.InvokeSafely(this);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -400,25 +400,11 @@ internal sealed partial class FontAtlasFactory
|
||||||
this.disposables.Dispose();
|
this.disposables.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
this.AfterDispose.InvokeSafely(this, null);
|
||||||
{
|
|
||||||
this.AfterDispose?.Invoke(this, null);
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
try
|
this.AfterDispose.InvokeSafely(this, e);
|
||||||
{
|
|
||||||
this.AfterDispose?.Invoke(this, e);
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GC.SuppressFinalize(this);
|
GC.SuppressFinalize(this);
|
||||||
|
|
@ -664,7 +650,7 @@ internal sealed partial class FontAtlasFactory
|
||||||
{
|
{
|
||||||
res = new(this, scale);
|
res = new(this, scale);
|
||||||
foreach (var fhm in this.fontHandleManagers)
|
foreach (var fhm in this.fontHandleManagers)
|
||||||
res.InitialAddSubstance(fhm.NewSubstance(res));
|
res.InitialAddSubstance(fhm.NewSubstance(res));
|
||||||
unsafe
|
unsafe
|
||||||
{
|
{
|
||||||
atlasPtr = (nint)res.Atlas.NativePtr;
|
atlasPtr = (nint)res.Atlas.NativePtr;
|
||||||
|
|
@ -699,7 +685,7 @@ internal sealed partial class FontAtlasFactory
|
||||||
|
|
||||||
res = new(this, scale);
|
res = new(this, scale);
|
||||||
foreach (var fhm in this.fontHandleManagers)
|
foreach (var fhm in this.fontHandleManagers)
|
||||||
res.InitialAddSubstance(fhm.NewSubstance(res));
|
res.InitialAddSubstance(fhm.NewSubstance(res));
|
||||||
unsafe
|
unsafe
|
||||||
{
|
{
|
||||||
atlasPtr = (nint)res.Atlas.NativePtr;
|
atlasPtr = (nint)res.Atlas.NativePtr;
|
||||||
|
|
@ -828,7 +814,7 @@ internal sealed partial class FontAtlasFactory
|
||||||
this.factory.Framework.RunOnFrameworkThread(
|
this.factory.Framework.RunOnFrameworkThread(
|
||||||
() =>
|
() =>
|
||||||
{
|
{
|
||||||
this.RebuildRecommend?.InvokeSafely();
|
this.RebuildRecommend.InvokeSafely();
|
||||||
|
|
||||||
switch (this.AutoRebuildMode)
|
switch (this.AutoRebuildMode)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -79,13 +79,16 @@ internal abstract class FontHandle : IFontHandle
|
||||||
/// <param name="font">The font, locked during the call of <see cref="ImFontChanged"/>.</param>
|
/// <param name="font">The font, locked during the call of <see cref="ImFontChanged"/>.</param>
|
||||||
public void InvokeImFontChanged(ILockedImFont font)
|
public void InvokeImFontChanged(ILockedImFont font)
|
||||||
{
|
{
|
||||||
try
|
foreach (var d in Delegate.EnumerateInvocationList(this.ImFontChanged))
|
||||||
{
|
{
|
||||||
this.ImFontChanged?.Invoke(this, font);
|
try
|
||||||
}
|
{
|
||||||
catch (Exception e)
|
d(this, font);
|
||||||
{
|
}
|
||||||
Log.Error(e, $"{nameof(this.InvokeImFontChanged)}: error");
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Log.Error(e, $"{nameof(this.InvokeImFontChanged)}: error calling {d.Method.Name}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -151,7 +151,7 @@ internal class GamePrebakedFontHandle : FontHandle
|
||||||
}
|
}
|
||||||
|
|
||||||
if (suggestRebuild)
|
if (suggestRebuild)
|
||||||
this.RebuildRecommend?.Invoke();
|
this.RebuildRecommend.InvokeSafely();
|
||||||
|
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
@ -641,7 +641,7 @@ internal class GamePrebakedFontHandle : FontHandle
|
||||||
glyphIndex = (ushort)glyphs.Length;
|
glyphIndex = (ushort)glyphs.Length;
|
||||||
glyphs.Add(default);
|
glyphs.Add(default);
|
||||||
}
|
}
|
||||||
|
|
||||||
ref var g = ref glyphs[glyphIndex];
|
ref var g = ref glyphs[glyphIndex];
|
||||||
g = sourceGlyph;
|
g = sourceGlyph;
|
||||||
if (fontScaleMode == FontScaleMode.SkipHandling)
|
if (fontScaleMode == FontScaleMode.SkipHandling)
|
||||||
|
|
@ -807,7 +807,7 @@ internal class GamePrebakedFontHandle : FontHandle
|
||||||
.GetCustomRectByIndex(rectId)
|
.GetCustomRectByIndex(rectId)
|
||||||
.NativePtr;
|
.NativePtr;
|
||||||
var widthAdjustment = this.BaseStyle.CalculateBaseWidthAdjustment(fdtFontHeader, fdtGlyph);
|
var widthAdjustment = this.BaseStyle.CalculateBaseWidthAdjustment(fdtFontHeader, fdtGlyph);
|
||||||
|
|
||||||
// Glyph is scaled at this point; undo that.
|
// Glyph is scaled at this point; undo that.
|
||||||
ref var glyph = ref glyphs[lookups[rc.GlyphId]];
|
ref var glyph = ref glyphs[lookups[rc.GlyphId]];
|
||||||
glyph.X0 = this.BaseAttr.HorizontalOffset;
|
glyph.X0 = this.BaseAttr.HorizontalOffset;
|
||||||
|
|
@ -822,7 +822,7 @@ internal class GamePrebakedFontHandle : FontHandle
|
||||||
this.gftp.GetTexFile(this.BaseAttr.TexPathFormat, fdtGlyph.TextureFileIndex);
|
this.gftp.GetTexFile(this.BaseAttr.TexPathFormat, fdtGlyph.TextureFileIndex);
|
||||||
var sourceBuffer = texFiles[fdtGlyph.TextureFileIndex].ImageData;
|
var sourceBuffer = texFiles[fdtGlyph.TextureFileIndex].ImageData;
|
||||||
var sourceBufferDelta = fdtGlyph.TextureChannelByteIndex;
|
var sourceBufferDelta = fdtGlyph.TextureChannelByteIndex;
|
||||||
|
|
||||||
for (var y = 0; y < fdtGlyph.BoundingHeight; y++)
|
for (var y = 0; y < fdtGlyph.BoundingHeight; y++)
|
||||||
{
|
{
|
||||||
var sourcePixelIndex =
|
var sourcePixelIndex =
|
||||||
|
|
@ -830,11 +830,11 @@ internal class GamePrebakedFontHandle : FontHandle
|
||||||
sourcePixelIndex *= 4;
|
sourcePixelIndex *= 4;
|
||||||
sourcePixelIndex += sourceBufferDelta;
|
sourcePixelIndex += sourceBufferDelta;
|
||||||
var blend1 = horzBlend[fdtGlyph.CurrentOffsetY + y];
|
var blend1 = horzBlend[fdtGlyph.CurrentOffsetY + y];
|
||||||
|
|
||||||
var targetOffset = ((rc.Y + y) * width) + rc.X;
|
var targetOffset = ((rc.Y + y) * width) + rc.X;
|
||||||
for (var x = 0; x < rc.Width; x++)
|
for (var x = 0; x < rc.Width; x++)
|
||||||
pixels8[targetOffset + x] = 0;
|
pixels8[targetOffset + x] = 0;
|
||||||
|
|
||||||
targetOffset += horzShift[fdtGlyph.CurrentOffsetY + y];
|
targetOffset += horzShift[fdtGlyph.CurrentOffsetY + y];
|
||||||
if (blend1 == 0)
|
if (blend1 == 0)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,18 @@ public class Localization : IServiceType
|
||||||
public void SetupWithFallbacks()
|
public void SetupWithFallbacks()
|
||||||
{
|
{
|
||||||
this.DalamudLanguageCultureInfo = CultureInfo.InvariantCulture;
|
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);
|
Loc.SetupWithFallbacks(this.assembly);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -134,7 +145,17 @@ public class Localization : IServiceType
|
||||||
}
|
}
|
||||||
|
|
||||||
this.DalamudLanguageCultureInfo = GetCultureInfoFromLangCode(langCode);
|
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
|
try
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -527,18 +527,15 @@ internal sealed class DalamudPluginInterface : IDalamudPluginInterface, IDisposa
|
||||||
/// <param name="affectedThisPlugin">If this plugin was affected by the change.</param>
|
/// <param name="affectedThisPlugin">If this plugin was affected by the change.</param>
|
||||||
internal void NotifyActivePluginsChanged(PluginListInvalidationKind kind, bool affectedThisPlugin)
|
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<IDalamudPluginInterface.ActivePluginsChangedDelegate>())
|
try
|
||||||
{
|
{
|
||||||
try
|
action(kind, affectedThisPlugin);
|
||||||
{
|
}
|
||||||
action(kind, affectedThisPlugin);
|
catch (Exception ex)
|
||||||
}
|
{
|
||||||
catch (Exception ex)
|
Log.Error(ex, "Exception during raise of {handler}", action.Method);
|
||||||
{
|
|
||||||
Log.Error(ex, "Exception during raise of {handler}", action.Method);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -547,18 +544,15 @@ internal sealed class DalamudPluginInterface : IDalamudPluginInterface, IDisposa
|
||||||
{
|
{
|
||||||
this.UiLanguage = langCode;
|
this.UiLanguage = langCode;
|
||||||
|
|
||||||
if (this.LanguageChanged is { } callback)
|
foreach (var action in Delegate.EnumerateInvocationList(this.LanguageChanged))
|
||||||
{
|
{
|
||||||
foreach (var action in callback.GetInvocationList().Cast<IDalamudPluginInterface.LanguageChangedDelegate>())
|
try
|
||||||
{
|
{
|
||||||
try
|
action(langCode);
|
||||||
{
|
}
|
||||||
action(langCode);
|
catch (Exception ex)
|
||||||
}
|
{
|
||||||
catch (Exception ex)
|
Log.Error(ex, "Exception during raise of {handler}", action.Method);
|
||||||
{
|
|
||||||
Log.Error(ex, "Exception during raise of {handler}", action.Method);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
using System.Linq;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
using Dalamud.Game;
|
using Dalamud.Game;
|
||||||
using Dalamud.Game.Gui.ContextMenu;
|
using Dalamud.Game.Gui.ContextMenu;
|
||||||
|
using Dalamud.Game.Gui.NamePlate;
|
||||||
using Dalamud.Plugin.Services;
|
using Dalamud.Plugin.Services;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
|
|
||||||
|
|
@ -14,25 +15,29 @@ internal static class EventHandlerExtensions
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Replacement for Invoke() on EventHandlers to catch exceptions that stop event propagation in case
|
/// 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.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="eh">The EventHandler in question.</param>
|
/// <param name="eh">The EventHandler in question.</param>
|
||||||
/// <param name="sender">Default sender for Invoke equivalent.</param>
|
/// <param name="sender">Default sender for Invoke equivalent.</param>
|
||||||
/// <param name="e">Default EventArgs for Invoke equivalent.</param>
|
/// <param name="e">Default EventArgs for Invoke equivalent.</param>
|
||||||
public static void InvokeSafely(this EventHandler? eh, object sender, EventArgs e)
|
public static void InvokeSafely(this EventHandler? eh, object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if (eh == null)
|
foreach (var handler in Delegate.EnumerateInvocationList(eh))
|
||||||
return;
|
|
||||||
|
|
||||||
foreach (var handler in eh.GetInvocationList().Cast<EventHandler>())
|
|
||||||
{
|
{
|
||||||
HandleInvoke(() => handler(sender, e));
|
try
|
||||||
|
{
|
||||||
|
handler(sender, e);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Error(ex, "Exception during raise of {handler}", handler.Method);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Replacement for Invoke() on generic EventHandlers to catch exceptions that stop event propagation in case
|
/// 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.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="eh">The EventHandler in question.</param>
|
/// <param name="eh">The EventHandler in question.</param>
|
||||||
/// <param name="sender">Default sender for Invoke equivalent.</param>
|
/// <param name="sender">Default sender for Invoke equivalent.</param>
|
||||||
|
|
@ -40,104 +45,135 @@ internal static class EventHandlerExtensions
|
||||||
/// <typeparam name="T">Type of EventArgs.</typeparam>
|
/// <typeparam name="T">Type of EventArgs.</typeparam>
|
||||||
public static void InvokeSafely<T>(this EventHandler<T>? eh, object sender, T e)
|
public static void InvokeSafely<T>(this EventHandler<T>? eh, object sender, T e)
|
||||||
{
|
{
|
||||||
if (eh == null)
|
foreach (var handler in Delegate.EnumerateInvocationList(eh))
|
||||||
return;
|
|
||||||
|
|
||||||
foreach (var handler in eh.GetInvocationList().Cast<EventHandler<T>>())
|
|
||||||
{
|
{
|
||||||
HandleInvoke(() => handler(sender, e));
|
try
|
||||||
|
{
|
||||||
|
handler(sender, e);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Error(ex, "Exception during raise of {handler}", handler.Method);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Replacement for Invoke() on event Actions to catch exceptions that stop event propagation in case
|
/// 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.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="act">The Action in question.</param>
|
/// <param name="act">The Action in question.</param>
|
||||||
public static void InvokeSafely(this Action? act)
|
public static void InvokeSafely(this Action? act)
|
||||||
{
|
{
|
||||||
if (act == null)
|
foreach (var action in Delegate.EnumerateInvocationList(act))
|
||||||
return;
|
|
||||||
|
|
||||||
foreach (var action in act.GetInvocationList().Cast<Action>())
|
|
||||||
{
|
{
|
||||||
HandleInvoke(action);
|
try
|
||||||
|
{
|
||||||
|
action();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Error(ex, "Exception during raise of {handler}", action.Method);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc cref="InvokeSafely(Action)"/>
|
||||||
/// Replacement for Invoke() on event Actions to catch exceptions that stop event propagation in case
|
|
||||||
/// of a thrown Exception inside of an invocation.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="act">The Action in question.</param>
|
|
||||||
/// <param name="argument">Templated argument for Action.</param>
|
|
||||||
/// <typeparam name="T">Type of Action args.</typeparam>
|
|
||||||
public static void InvokeSafely<T>(this Action<T>? act, T argument)
|
public static void InvokeSafely<T>(this Action<T>? act, T argument)
|
||||||
{
|
{
|
||||||
if (act == null)
|
foreach (var action in Delegate.EnumerateInvocationList(act))
|
||||||
return;
|
|
||||||
|
|
||||||
foreach (var action in act.GetInvocationList().Cast<Action<T>>())
|
|
||||||
{
|
{
|
||||||
HandleInvoke(action, argument);
|
try
|
||||||
|
{
|
||||||
|
action(argument);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Error(ex, "Exception during raise of {handler}", action.Method);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="InvokeSafely(Action)"/>
|
||||||
|
public static void InvokeSafely<T1, T2>(this Action<T1, T2>? 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Replacement for Invoke() on OnUpdateDelegate to catch exceptions that stop event propagation in case
|
/// 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.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="updateDelegate">The OnUpdateDelegate in question.</param>
|
/// <param name="updateDelegate">The OnUpdateDelegate in question.</param>
|
||||||
/// <param name="framework">Framework to be passed on to OnUpdateDelegate.</param>
|
/// <param name="framework">Framework to be passed on to OnUpdateDelegate.</param>
|
||||||
public static void InvokeSafely(this IFramework.OnUpdateDelegate? updateDelegate, Framework framework)
|
public static void InvokeSafely(this IFramework.OnUpdateDelegate? updateDelegate, Framework framework)
|
||||||
{
|
{
|
||||||
if (updateDelegate == null)
|
foreach (var action in Delegate.EnumerateInvocationList(updateDelegate))
|
||||||
return;
|
|
||||||
|
|
||||||
foreach (var action in updateDelegate.GetInvocationList().Cast<IFramework.OnUpdateDelegate>())
|
|
||||||
{
|
{
|
||||||
HandleInvoke(() => action(framework));
|
try
|
||||||
|
{
|
||||||
|
action(framework);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Error(ex, "Exception during raise of {handler}", action.Method);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Replacement for Invoke() on OnMenuOpenedDelegate to catch exceptions that stop event propagation in case
|
/// 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.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="openedDelegate">The OnMenuOpenedDelegate in question.</param>
|
/// <param name="openedDelegate">The OnMenuOpenedDelegate in question.</param>
|
||||||
/// <param name="argument">Templated argument for Action.</param>
|
/// <param name="argument">Templated argument for Action.</param>
|
||||||
public static void InvokeSafely(this IContextMenu.OnMenuOpenedDelegate? openedDelegate, MenuOpenedArgs argument)
|
public static void InvokeSafely(this IContextMenu.OnMenuOpenedDelegate? openedDelegate, MenuOpenedArgs argument)
|
||||||
{
|
{
|
||||||
if (openedDelegate == null)
|
foreach (var action in Delegate.EnumerateInvocationList(openedDelegate))
|
||||||
return;
|
|
||||||
|
|
||||||
foreach (var action in openedDelegate.GetInvocationList().Cast<IContextMenu.OnMenuOpenedDelegate>())
|
|
||||||
{
|
{
|
||||||
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)
|
/// <summary>
|
||||||
|
/// Replacement for Invoke() on OnMenuOpenedDelegate to catch exceptions that stop event propagation in case
|
||||||
|
/// of a thrown Exception inside an invocation.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="updatedDelegate">The OnMenuOpenedDelegate in question.</param>
|
||||||
|
/// <param name="context">An object containing information about the pending data update.</param>
|
||||||
|
/// <param name="handlers>">A list of handlers used for updating nameplate data.</param>
|
||||||
|
public static void InvokeSafely(
|
||||||
|
this INamePlateGui.OnPlateUpdateDelegate? updatedDelegate,
|
||||||
|
INamePlateUpdateContext context,
|
||||||
|
IReadOnlyList<INamePlateUpdateHandler> handlers)
|
||||||
{
|
{
|
||||||
try
|
foreach (var action in Delegate.EnumerateInvocationList(updatedDelegate))
|
||||||
{
|
{
|
||||||
act();
|
try
|
||||||
}
|
{
|
||||||
catch (Exception ex)
|
action(context, handlers);
|
||||||
{
|
}
|
||||||
Log.Error(ex, "Exception during raise of {handler}", act.Method);
|
catch (Exception ex)
|
||||||
}
|
{
|
||||||
}
|
Log.Error(ex, "Exception during raise of {handler}", action.Method);
|
||||||
|
}
|
||||||
private static void HandleInvoke<T>(Action<T> act, T argument)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
act(argument);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Log.Error(ex, "Exception during raise of {handler}", act.Method);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue