mirror of
https://github.com/goatcorp/Dalamud.git
synced 2026-02-20 06:47:44 +01:00
Merge pull request #2566 from MidoriKami/AddonLifecycleThreadSafety
IAddonLifecycle Thread Safety
This commit is contained in:
commit
55eb7e41d8
1 changed files with 29 additions and 15 deletions
|
|
@ -27,7 +27,11 @@ internal unsafe class AddonLifecycle : IInternalDisposableService
|
||||||
|
|
||||||
private static readonly ModuleLog Log = ModuleLog.Create<AddonLifecycle>();
|
private static readonly ModuleLog Log = ModuleLog.Create<AddonLifecycle>();
|
||||||
|
|
||||||
|
[ServiceManager.ServiceDependency]
|
||||||
|
private readonly Framework framework = Service<Framework>.Get();
|
||||||
|
|
||||||
private Hook<AtkUnitBase.Delegates.Initialize>? onInitializeAddonHook;
|
private Hook<AtkUnitBase.Delegates.Initialize>? onInitializeAddonHook;
|
||||||
|
private bool isInvokingListeners = false;
|
||||||
|
|
||||||
[ServiceManager.ServiceConstructor]
|
[ServiceManager.ServiceConstructor]
|
||||||
private AddonLifecycle()
|
private AddonLifecycle()
|
||||||
|
|
@ -58,20 +62,23 @@ internal unsafe class AddonLifecycle : IInternalDisposableService
|
||||||
/// <param name="listener">The listener to register.</param>
|
/// <param name="listener">The listener to register.</param>
|
||||||
internal void RegisterListener(AddonLifecycleEventListener listener)
|
internal void RegisterListener(AddonLifecycleEventListener listener)
|
||||||
{
|
{
|
||||||
if (!this.EventListeners.ContainsKey(listener.EventType))
|
this.framework.RunOnTick(() =>
|
||||||
{
|
{
|
||||||
if (!this.EventListeners.TryAdd(listener.EventType, []))
|
if (!this.EventListeners.ContainsKey(listener.EventType))
|
||||||
return;
|
{
|
||||||
}
|
if (!this.EventListeners.TryAdd(listener.EventType, []))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Note: string.Empty is a valid addon name, as that will trigger on any addon for this event type
|
// Note: string.Empty is a valid addon name, as that will trigger on any addon for this event type
|
||||||
if (!this.EventListeners[listener.EventType].ContainsKey(listener.AddonName))
|
if (!this.EventListeners[listener.EventType].ContainsKey(listener.AddonName))
|
||||||
{
|
{
|
||||||
if (!this.EventListeners[listener.EventType].TryAdd(listener.AddonName, []))
|
if (!this.EventListeners[listener.EventType].TryAdd(listener.AddonName, []))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.EventListeners[listener.EventType][listener.AddonName].Add(listener);
|
this.EventListeners[listener.EventType][listener.AddonName].Add(listener);
|
||||||
|
}, delayTicks: this.isInvokingListeners ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -80,13 +87,16 @@ internal unsafe class AddonLifecycle : IInternalDisposableService
|
||||||
/// <param name="listener">The listener to unregister.</param>
|
/// <param name="listener">The listener to unregister.</param>
|
||||||
internal void UnregisterListener(AddonLifecycleEventListener listener)
|
internal void UnregisterListener(AddonLifecycleEventListener listener)
|
||||||
{
|
{
|
||||||
if (this.EventListeners.TryGetValue(listener.EventType, out var addonListeners))
|
this.framework.RunOnTick(() =>
|
||||||
{
|
{
|
||||||
if (addonListeners.TryGetValue(listener.AddonName, out var addonListener))
|
if (this.EventListeners.TryGetValue(listener.EventType, out var addonListeners))
|
||||||
{
|
{
|
||||||
addonListener.Remove(listener);
|
if (addonListeners.TryGetValue(listener.AddonName, out var addonListener))
|
||||||
|
{
|
||||||
|
addonListener.Remove(listener);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}, delayTicks: this.isInvokingListeners ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -97,6 +107,8 @@ internal unsafe class AddonLifecycle : IInternalDisposableService
|
||||||
/// <param name="blame">What to blame on errors.</param>
|
/// <param name="blame">What to blame on errors.</param>
|
||||||
internal void InvokeListenersSafely(AddonEvent eventType, AddonArgs args, [CallerMemberName] string blame = "")
|
internal void InvokeListenersSafely(AddonEvent eventType, AddonArgs args, [CallerMemberName] string blame = "")
|
||||||
{
|
{
|
||||||
|
this.isInvokingListeners = true;
|
||||||
|
|
||||||
// Early return if we don't have any listeners of this type
|
// Early return if we don't have any listeners of this type
|
||||||
if (!this.EventListeners.TryGetValue(eventType, out var addonListeners)) return;
|
if (!this.EventListeners.TryGetValue(eventType, out var addonListeners)) return;
|
||||||
|
|
||||||
|
|
@ -131,6 +143,8 @@ internal unsafe class AddonLifecycle : IInternalDisposableService
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.isInvokingListeners = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue