mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-12 18:27:23 +01:00
Better unload
This commit is contained in:
parent
b8724f7a59
commit
c51e65e0bd
2 changed files with 14 additions and 34 deletions
|
|
@ -19,13 +19,13 @@ namespace Dalamud.Game.Addon.Lifecycle;
|
|||
[ServiceManager.EarlyLoadedService]
|
||||
internal unsafe class AddonLifecycle : IInternalDisposableService
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a list of all allocated addon virtual tables.
|
||||
/// </summary>
|
||||
public static readonly List<AddonVirtualTable> AllocatedTables = [];
|
||||
|
||||
private static readonly ModuleLog Log = new("AddonLifecycle");
|
||||
|
||||
[ServiceManager.ServiceDependency]
|
||||
private readonly Framework framework = Service<Framework>.Get();
|
||||
|
||||
private readonly Dictionary<string, AddonVirtualTable> modifiedTables = [];
|
||||
|
||||
private Hook<AtkUnitBase.Delegates.Initialize>? onInitializeAddonHook;
|
||||
|
||||
[ServiceManager.ServiceConstructor]
|
||||
|
|
@ -47,13 +47,8 @@ internal unsafe class AddonLifecycle : IInternalDisposableService
|
|||
this.onInitializeAddonHook?.Dispose();
|
||||
this.onInitializeAddonHook = null;
|
||||
|
||||
this.framework.RunOnFrameworkThread(() =>
|
||||
{
|
||||
foreach (var virtualTable in this.modifiedTables.Values)
|
||||
{
|
||||
virtualTable.Dispose();
|
||||
}
|
||||
});
|
||||
AllocatedTables.ForEach(entry => entry.Dispose());
|
||||
AllocatedTables.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -141,18 +136,8 @@ internal unsafe class AddonLifecycle : IInternalDisposableService
|
|||
{
|
||||
this.LogInitialize(addon->NameString);
|
||||
|
||||
if (!this.modifiedTables.ContainsKey(addon->NameString))
|
||||
{
|
||||
// AddonVirtualTable class handles creating the virtual table, and overriding each of the tracked virtual functions
|
||||
var managedVirtualTableEntry = new AddonVirtualTable(addon, this)
|
||||
{
|
||||
// This event is invoked when the game itself has disposed of an addon
|
||||
// We can use this to know when to remove our virtual table entry
|
||||
OnAddonFinalized = () => this.modifiedTables.Remove(addon->NameString),
|
||||
};
|
||||
|
||||
this.modifiedTables.Add(addon->NameString, managedVirtualTableEntry);
|
||||
}
|
||||
// AddonVirtualTable class handles creating the virtual table, and overriding each of the tracked virtual functions
|
||||
AllocatedTables.Add(new AddonVirtualTable(addon, this));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using System.Diagnostics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
|
||||
using Dalamud.Game.Addon.Lifecycle.AddonArgTypes;
|
||||
using Dalamud.Logging.Internal;
|
||||
|
|
@ -108,17 +109,11 @@ internal unsafe class AddonVirtualTable : IDisposable
|
|||
this.modifiedVirtualTable->Hide = (delegate* unmanaged<AtkUnitBase*, bool, bool, uint, void>)Marshal.GetFunctionPointerForDelegate(this.hideFunction);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets an event that is invoked when this addon's Finalize method is called from native.
|
||||
/// </summary>
|
||||
public required Action OnAddonFinalized { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// <em>WARNING!</em> This should not be called at any time except during dalamud unload.
|
||||
/// </summary>
|
||||
/// <inheritdoc/>
|
||||
public void Dispose()
|
||||
{
|
||||
this.atkUnitBase->VirtualTable = this.originalVirtualTable;
|
||||
// Ensure restoration is done atomically.
|
||||
Interlocked.Exchange(ref *(nint*)&this.atkUnitBase->VirtualTable, (nint)this.originalVirtualTable);
|
||||
IMemorySpace.Free(this.modifiedVirtualTable, 0x8 * VirtualTableEntryCount);
|
||||
}
|
||||
|
||||
|
|
@ -131,7 +126,7 @@ internal unsafe class AddonVirtualTable : IDisposable
|
|||
if ((freeFlags & 1) == 1)
|
||||
{
|
||||
IMemorySpace.Free(this.modifiedVirtualTable, 0x8 * VirtualTableEntryCount);
|
||||
this.OnAddonFinalized();
|
||||
AddonLifecycle.AllocatedTables.Remove(this);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue