Less footguns in service dependency handling (#1560)

This commit is contained in:
srkizer 2023-12-07 14:29:46 +09:00 committed by GitHub
parent 5777745ab3
commit a0f4baf8fa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 659 additions and 302 deletions

View file

@ -57,6 +57,8 @@ internal unsafe class AddonEventManager : IDisposable, IServiceType
this.finalizeEventListener = new AddonLifecycleEventListener(AddonEvent.PreFinalize, string.Empty, this.OnAddonFinalize);
this.addonLifecycle.RegisterListener(this.finalizeEventListener);
this.onUpdateCursor.Enable();
}
private delegate nint UpdateCursorDelegate(RaptureAtkModule* module);
@ -149,12 +151,6 @@ internal unsafe class AddonEventManager : IDisposable, IServiceType
}
}
[ServiceManager.CallWhenServicesReady]
private void ContinueConstruction()
{
this.onUpdateCursor.Enable();
}
/// <summary>
/// When an addon finalizes, check it for any registered events, and unregister them.
/// </summary>

View file

@ -58,6 +58,14 @@ internal unsafe class AddonLifecycle : IDisposable, IServiceType
this.onAddonUpdateHook = new CallHook<AddonUpdateDelegate>(this.address.AddonUpdate, this.OnAddonUpdate);
this.onAddonRefreshHook = Hook<AddonOnRefreshDelegate>.FromAddress(this.address.AddonOnRefresh, this.OnAddonRefresh);
this.onAddonRequestedUpdateHook = new CallHook<AddonOnRequestedUpdateDelegate>(this.address.AddonOnRequestedUpdate, this.OnRequestedUpdate);
this.onAddonSetupHook.Enable();
this.onAddonSetup2Hook.Enable();
this.onAddonFinalizeHook.Enable();
this.onAddonDrawHook.Enable();
this.onAddonUpdateHook.Enable();
this.onAddonRefreshHook.Enable();
this.onAddonRequestedUpdateHook.Enable();
}
private delegate void AddonSetupDelegate(AtkUnitBase* addon, uint valueCount, AtkValue* values);
@ -181,18 +189,6 @@ internal unsafe class AddonLifecycle : IDisposable, IServiceType
}
}
[ServiceManager.CallWhenServicesReady]
private void ContinueConstruction()
{
this.onAddonSetupHook.Enable();
this.onAddonSetup2Hook.Enable();
this.onAddonFinalizeHook.Enable();
this.onAddonDrawHook.Enable();
this.onAddonUpdateHook.Enable();
this.onAddonRefreshHook.Enable();
this.onAddonRequestedUpdateHook.Enable();
}
private void RegisterReceiveEventHook(AtkUnitBase* addon)
{
// Hook the addon's ReceiveEvent function here, but only enable the hook if we have an active listener.

View file

@ -58,6 +58,8 @@ internal sealed class ClientState : IDisposable, IServiceType, IClientState
this.framework.Update += this.FrameworkOnOnUpdateEvent;
this.networkHandlers.CfPop += this.NetworkHandlersOnCfPop;
this.setupTerritoryTypeHook.Enable();
}
[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
@ -120,12 +122,6 @@ internal sealed class ClientState : IDisposable, IServiceType, IClientState
this.networkHandlers.CfPop -= this.NetworkHandlersOnCfPop;
}
[ServiceManager.CallWhenServicesReady]
private void ContinueConstruction()
{
this.setupTerritoryTypeHook.Enable();
}
private IntPtr SetupTerritoryTypeDetour(IntPtr manager, ushort terriType)
{
this.TerritoryType = terriType;

View file

@ -16,6 +16,9 @@ internal sealed partial class Condition : IServiceType, ICondition
/// Gets the current max number of conditions. You can get this just by looking at the condition sheet and how many rows it has.
/// </summary>
internal const int MaxConditionEntries = 104;
[ServiceManager.ServiceDependency]
private readonly Framework framework = Service<Framework>.Get();
private readonly bool[] cache = new bool[MaxConditionEntries];
@ -24,6 +27,12 @@ internal sealed partial class Condition : IServiceType, ICondition
{
var resolver = clientState.AddressResolver;
this.Address = resolver.ConditionFlags;
// Initialization
for (var i = 0; i < MaxConditionEntries; i++)
this.cache[i] = this[i];
this.framework.Update += this.FrameworkUpdate;
}
/// <inheritdoc/>
@ -80,17 +89,7 @@ internal sealed partial class Condition : IServiceType, ICondition
return false;
}
[ServiceManager.CallWhenServicesReady]
private void ContinueConstruction(Framework framework)
{
// Initialization
for (var i = 0; i < MaxConditionEntries; i++)
this.cache[i] = this[i];
framework.Update += this.FrameworkUpdate;
}
private void FrameworkUpdate(IFramework framework)
private void FrameworkUpdate(IFramework unused)
{
for (var i = 0; i < MaxConditionEntries; i++)
{
@ -144,7 +143,7 @@ internal sealed partial class Condition : IDisposable
if (disposing)
{
Service<Framework>.Get().Update -= this.FrameworkUpdate;
this.framework.Update -= this.FrameworkUpdate;
}
this.isDisposed = true;

View file

@ -38,6 +38,7 @@ internal unsafe class GamepadState : IDisposable, IServiceType, IGamepadState
var resolver = clientState.AddressResolver;
Log.Verbose($"GamepadPoll address 0x{resolver.GamepadPoll.ToInt64():X}");
this.gamepadPoll = Hook<ControllerPoll>.FromAddress(resolver.GamepadPoll, this.GamepadPollDetour);
this.gamepadPoll?.Enable();
}
private delegate int ControllerPoll(IntPtr controllerInput);
@ -114,12 +115,6 @@ internal unsafe class GamepadState : IDisposable, IServiceType, IGamepadState
GC.SuppressFinalize(this);
}
[ServiceManager.CallWhenServicesReady]
private void ContinueConstruction()
{
this.gamepadPoll?.Enable();
}
private int GamepadPollDetour(IntPtr gamepadInput)
{
var original = this.gamepadPoll!.Original(gamepadInput);

View file

@ -37,6 +37,8 @@ internal unsafe class DutyState : IDisposable, IServiceType, IDutyState
this.framework.Update += this.FrameworkOnUpdateEvent;
this.clientState.TerritoryChanged += this.TerritoryOnChangedEvent;
this.contentDirectorNetworkMessageHook.Enable();
}
[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
@ -67,12 +69,6 @@ internal unsafe class DutyState : IDisposable, IServiceType, IDutyState
this.clientState.TerritoryChanged -= this.TerritoryOnChangedEvent;
}
[ServiceManager.CallWhenServicesReady]
private void ContinueConstruction()
{
this.contentDirectorNetworkMessageHook.Enable();
}
private byte ContentDirectorNetworkMessageDetour(IntPtr a1, IntPtr a2, ushort* a3)
{
var category = *a3;

View file

@ -58,6 +58,9 @@ internal sealed class Framework : IDisposable, IServiceType, IFramework
this.updateHook = Hook<OnUpdateDetour>.FromAddress(this.addressResolver.TickAddress, this.HandleFrameworkUpdate);
this.destroyHook = Hook<OnRealDestroyDelegate>.FromAddress(this.addressResolver.DestroyAddress, this.HandleFrameworkDestroy);
this.updateHook.Enable();
this.destroyHook.Enable();
}
/// <summary>
@ -330,13 +333,6 @@ internal sealed class Framework : IDisposable, IServiceType, IFramework
}
}
[ServiceManager.CallWhenServicesReady]
private void ContinueConstruction()
{
this.updateHook.Enable();
this.destroyHook.Enable();
}
private void RunPendingTickTasks()
{
if (this.runOnNextTickTaskList.Count == 0 && this.runOnNextTickTaskList2.Count == 0)

View file

@ -50,6 +50,10 @@ internal sealed class ChatGui : IDisposable, IServiceType, IChatGui
this.printMessageHook = Hook<PrintMessageDelegate>.FromAddress(this.address.PrintMessage, this.HandlePrintMessageDetour);
this.populateItemLinkHook = Hook<PopulateItemLinkDelegate>.FromAddress(this.address.PopulateItemLinkObject, this.HandlePopulateItemLinkDetour);
this.interactableLinkClickedHook = Hook<InteractableLinkClickedDelegate>.FromAddress(this.address.InteractableLinkClicked, this.InteractableLinkClickedDetour);
this.printMessageHook.Enable();
this.populateItemLinkHook.Enable();
this.interactableLinkClickedHook.Enable();
}
[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
@ -182,14 +186,6 @@ internal sealed class ChatGui : IDisposable, IServiceType, IChatGui
this.dalamudLinkHandlers.Remove((pluginName, commandId));
}
[ServiceManager.CallWhenServicesReady]
private void ContinueConstruction()
{
this.printMessageHook.Enable();
this.populateItemLinkHook.Enable();
this.interactableLinkClickedHook.Enable();
}
private void PrintTagged(string message, XivChatType channel, string? tag, ushort? color)
{
var builder = new SeStringBuilder();

View file

@ -36,6 +36,8 @@ internal sealed class FlyTextGui : IDisposable, IServiceType, IFlyTextGui
this.addFlyTextNative = Marshal.GetDelegateForFunctionPointer<AddFlyTextDelegate>(this.Address.AddFlyText);
this.createFlyTextHook = Hook<CreateFlyTextDelegate>.FromAddress(this.Address.CreateFlyText, this.CreateFlyTextDetour);
this.createFlyTextHook.Enable();
}
/// <summary>
@ -143,12 +145,6 @@ internal sealed class FlyTextGui : IDisposable, IServiceType, IFlyTextGui
return terminated;
}
[ServiceManager.CallWhenServicesReady]
private void ContinueConstruction(GameGui gameGui)
{
this.createFlyTextHook.Enable();
}
private IntPtr CreateFlyTextDetour(
IntPtr addonFlyText,
FlyTextKind kind,

View file

@ -75,6 +75,15 @@ internal sealed unsafe class GameGui : IDisposable, IServiceType, IGameGui
this.toggleUiHideHook = Hook<ToggleUiHideDelegate>.FromAddress(this.address.ToggleUiHide, this.ToggleUiHideDetour);
this.utf8StringFromSequenceHook = Hook<Utf8StringFromSequenceDelegate>.FromAddress(this.address.Utf8StringFromSequence, this.Utf8StringFromSequenceDetour);
this.setGlobalBgmHook.Enable();
this.handleItemHoverHook.Enable();
this.handleItemOutHook.Enable();
this.handleImmHook.Enable();
this.toggleUiHideHook.Enable();
this.handleActionHoverHook.Enable();
this.handleActionOutHook.Enable();
this.utf8StringFromSequenceHook.Enable();
}
// Marshaled delegates
@ -376,19 +385,6 @@ internal sealed unsafe class GameGui : IDisposable, IServiceType, IGameGui
this.GameUiHidden = false;
}
[ServiceManager.CallWhenServicesReady]
private void ContinueConstruction()
{
this.setGlobalBgmHook.Enable();
this.handleItemHoverHook.Enable();
this.handleItemOutHook.Enable();
this.handleImmHook.Enable();
this.toggleUiHideHook.Enable();
this.handleActionHoverHook.Enable();
this.handleActionOutHook.Enable();
this.utf8StringFromSequenceHook.Enable();
}
private IntPtr HandleSetGlobalBgmDetour(ushort bgmKey, byte a2, uint a3, uint a4, uint a5, byte a6)
{
var retVal = this.setGlobalBgmHook.Original(bgmKey, a2, a3, a4, a5, a6);

View file

@ -253,7 +253,7 @@ internal unsafe class DalamudIME : IDisposable, IServiceType
}
}
[ServiceManager.CallWhenServicesReady]
[ServiceManager.CallWhenServicesReady("Effectively waiting for cimgui.dll to become available.")]
private void ContinueConstruction(InterfaceManager.InterfaceManagerWithScene interfaceManagerWithScene)
{
try

View file

@ -35,6 +35,7 @@ internal sealed class PartyFinderGui : IDisposable, IServiceType, IPartyFinderGu
this.memory = Marshal.AllocHGlobal(PartyFinderPacket.PacketSize);
this.receiveListingHook = Hook<ReceiveListingDelegate>.FromAddress(this.address.ReceiveListing, this.HandleReceiveListingDetour);
this.receiveListingHook.Enable();
}
[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
@ -60,12 +61,6 @@ internal sealed class PartyFinderGui : IDisposable, IServiceType, IPartyFinderGu
}
}
[ServiceManager.CallWhenServicesReady]
private void ContinueConstruction(GameGui gameGui)
{
this.receiveListingHook.Enable();
}
private void HandleReceiveListingDetour(IntPtr managerPtr, IntPtr data)
{
try

View file

@ -41,6 +41,10 @@ internal sealed partial class ToastGui : IDisposable, IServiceType, IToastGui
this.showNormalToastHook = Hook<ShowNormalToastDelegate>.FromAddress(this.address.ShowNormalToast, this.HandleNormalToastDetour);
this.showQuestToastHook = Hook<ShowQuestToastDelegate>.FromAddress(this.address.ShowQuestToast, this.HandleQuestToastDetour);
this.showErrorToastHook = Hook<ShowErrorToastDelegate>.FromAddress(this.address.ShowErrorToast, this.HandleErrorToastDetour);
this.showNormalToastHook.Enable();
this.showQuestToastHook.Enable();
this.showErrorToastHook.Enable();
}
#region Marshal delegates
@ -109,14 +113,6 @@ internal sealed partial class ToastGui : IDisposable, IServiceType, IToastGui
return terminated;
}
[ServiceManager.CallWhenServicesReady]
private void ContinueConstruction(GameGui gameGui)
{
this.showNormalToastHook.Enable();
this.showQuestToastHook.Enable();
this.showErrorToastHook.Enable();
}
private SeString ParseString(IntPtr text)
{
var bytes = new List<byte>();

View file

@ -63,6 +63,10 @@ internal sealed unsafe partial class DalamudAtkTweaks : IServiceType
this.locDalamudSettings = Loc.Localize("SystemMenuSettings", "Dalamud Settings");
// this.contextMenu.ContextMenuOpened += this.ContextMenuOnContextMenuOpened;
this.hookAgentHudOpenSystemMenu.Enable();
this.hookUiModuleRequestMainCommand.Enable();
this.hookAtkUnitBaseReceiveGlobalEvent.Enable();
}
private delegate void AgentHudOpenSystemMenuPrototype(void* thisPtr, AtkValue* atkValueArgs, uint menuSize);
@ -75,14 +79,6 @@ internal sealed unsafe partial class DalamudAtkTweaks : IServiceType
private delegate IntPtr AtkUnitBaseReceiveGlobalEvent(AtkUnitBase* thisPtr, ushort cmd, uint a3, IntPtr a4, uint* a5);
[ServiceManager.CallWhenServicesReady]
private void ContinueConstruction(DalamudInterface dalamudInterface)
{
this.hookAgentHudOpenSystemMenu.Enable();
this.hookUiModuleRequestMainCommand.Enable();
this.hookAtkUnitBaseReceiveGlobalEvent.Enable();
}
/*
private void ContextMenuOnContextMenuOpened(ContextMenuOpenedArgs args)
{

View file

@ -44,6 +44,9 @@ internal sealed class GameNetwork : IDisposable, IServiceType, IGameNetwork
this.processZonePacketDownHook = Hook<ProcessZonePacketDownDelegate>.FromAddress(this.address.ProcessZonePacketDown, this.ProcessZonePacketDownDetour);
this.processZonePacketUpHook = Hook<ProcessZonePacketUpDelegate>.FromAddress(this.address.ProcessZonePacketUp, this.ProcessZonePacketUpDetour);
this.processZonePacketDownHook.Enable();
this.processZonePacketUpHook.Enable();
}
[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
@ -62,13 +65,6 @@ internal sealed class GameNetwork : IDisposable, IServiceType, IGameNetwork
this.processZonePacketUpHook.Dispose();
}
[ServiceManager.CallWhenServicesReady]
private void ContinueConstruction()
{
this.processZonePacketDownHook.Enable();
this.processZonePacketUpHook.Enable();
}
private void ProcessZonePacketDownDetour(IntPtr a, uint targetId, IntPtr dataPtr)
{
this.baseAddress = a;