diff --git a/Dalamud/Data/DataManager.cs b/Dalamud/Data/DataManager.cs index baea32dce..564b10fae 100644 --- a/Dalamud/Data/DataManager.cs +++ b/Dalamud/Data/DataManager.cs @@ -20,7 +20,7 @@ namespace Dalamud.Data; /// [PluginInterface] [InterfaceVersion("1.0")] -[ServiceManager.BlockingEarlyLoadedService] +[ServiceManager.EarlyLoadedService] #pragma warning disable SA1015 [ResolveVia] #pragma warning restore SA1015 diff --git a/Dalamud/Game/ChatHandlers.cs b/Dalamud/Game/ChatHandlers.cs index 3b972146a..7043068c9 100644 --- a/Dalamud/Game/ChatHandlers.cs +++ b/Dalamud/Game/ChatHandlers.cs @@ -26,7 +26,7 @@ namespace Dalamud.Game; /// /// Chat events and public helper functions. /// -[ServiceManager.BlockingEarlyLoadedService] +[ServiceManager.EarlyLoadedService] internal class ChatHandlers : IServiceType { // private static readonly Dictionary UnicodeToDiscordEmojiDict = new() diff --git a/Dalamud/Game/ClientState/Aetherytes/AetheryteList.cs b/Dalamud/Game/ClientState/Aetherytes/AetheryteList.cs index e6af6e1df..f4115511d 100644 --- a/Dalamud/Game/ClientState/Aetherytes/AetheryteList.cs +++ b/Dalamud/Game/ClientState/Aetherytes/AetheryteList.cs @@ -14,7 +14,7 @@ namespace Dalamud.Game.ClientState.Aetherytes; /// [PluginInterface] [InterfaceVersion("1.0")] -[ServiceManager.BlockingEarlyLoadedService] +[ServiceManager.EarlyLoadedService] #pragma warning disable SA1015 [ResolveVia] #pragma warning restore SA1015 diff --git a/Dalamud/Game/ClientState/Buddy/BuddyList.cs b/Dalamud/Game/ClientState/Buddy/BuddyList.cs index 5d0098187..949ccae25 100644 --- a/Dalamud/Game/ClientState/Buddy/BuddyList.cs +++ b/Dalamud/Game/ClientState/Buddy/BuddyList.cs @@ -16,7 +16,7 @@ namespace Dalamud.Game.ClientState.Buddy; /// [PluginInterface] [InterfaceVersion("1.0")] -[ServiceManager.BlockingEarlyLoadedService] +[ServiceManager.EarlyLoadedService] #pragma warning disable SA1015 [ResolveVia] #pragma warning restore SA1015 diff --git a/Dalamud/Game/ClientState/ClientState.cs b/Dalamud/Game/ClientState/ClientState.cs index bd4259f5a..a67a0abb6 100644 --- a/Dalamud/Game/ClientState/ClientState.cs +++ b/Dalamud/Game/ClientState/ClientState.cs @@ -22,7 +22,7 @@ namespace Dalamud.Game.ClientState; /// This class represents the state of the game client at the time of access. /// [InterfaceVersion("1.0")] -[ServiceManager.BlockingEarlyLoadedService] +[ServiceManager.EarlyLoadedService] internal sealed class ClientState : IInternalDisposableService, IClientState { private static readonly ModuleLog Log = new("ClientState"); diff --git a/Dalamud/Game/ClientState/Conditions/Condition.cs b/Dalamud/Game/ClientState/Conditions/Condition.cs index dc8b28494..98132798f 100644 --- a/Dalamud/Game/ClientState/Conditions/Condition.cs +++ b/Dalamud/Game/ClientState/Conditions/Condition.cs @@ -9,8 +9,8 @@ namespace Dalamud.Game.ClientState.Conditions; /// Provides access to conditions (generally player state). You can check whether a player is in combat, mounted, etc. /// [InterfaceVersion("1.0")] -[ServiceManager.BlockingEarlyLoadedService] -internal sealed partial class Condition : IInternalDisposableService, ICondition +[ServiceManager.EarlyLoadedService] +internal sealed class Condition : IInternalDisposableService, 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. diff --git a/Dalamud/Game/ClientState/Fates/FateTable.cs b/Dalamud/Game/ClientState/Fates/FateTable.cs index e9400842f..182db18d4 100644 --- a/Dalamud/Game/ClientState/Fates/FateTable.cs +++ b/Dalamud/Game/ClientState/Fates/FateTable.cs @@ -14,7 +14,7 @@ namespace Dalamud.Game.ClientState.Fates; /// [PluginInterface] [InterfaceVersion("1.0")] -[ServiceManager.BlockingEarlyLoadedService] +[ServiceManager.EarlyLoadedService] #pragma warning disable SA1015 [ResolveVia] #pragma warning restore SA1015 diff --git a/Dalamud/Game/ClientState/GamePad/GamepadState.cs b/Dalamud/Game/ClientState/GamePad/GamepadState.cs index a0e16f0e2..c684d1ec6 100644 --- a/Dalamud/Game/ClientState/GamePad/GamepadState.cs +++ b/Dalamud/Game/ClientState/GamePad/GamepadState.cs @@ -17,7 +17,7 @@ namespace Dalamud.Game.ClientState.GamePad; /// [PluginInterface] [InterfaceVersion("1.0")] -[ServiceManager.BlockingEarlyLoadedService] +[ServiceManager.EarlyLoadedService] #pragma warning disable SA1015 [ResolveVia] #pragma warning restore SA1015 diff --git a/Dalamud/Game/ClientState/JobGauge/JobGauges.cs b/Dalamud/Game/ClientState/JobGauge/JobGauges.cs index 74e22ddbe..5085c361c 100644 --- a/Dalamud/Game/ClientState/JobGauge/JobGauges.cs +++ b/Dalamud/Game/ClientState/JobGauge/JobGauges.cs @@ -15,7 +15,7 @@ namespace Dalamud.Game.ClientState.JobGauge; /// [PluginInterface] [InterfaceVersion("1.0")] -[ServiceManager.BlockingEarlyLoadedService] +[ServiceManager.EarlyLoadedService] #pragma warning disable SA1015 [ResolveVia] #pragma warning restore SA1015 diff --git a/Dalamud/Game/ClientState/Keys/KeyState.cs b/Dalamud/Game/ClientState/Keys/KeyState.cs index 76bee51bf..b32a7d88b 100644 --- a/Dalamud/Game/ClientState/Keys/KeyState.cs +++ b/Dalamud/Game/ClientState/Keys/KeyState.cs @@ -24,7 +24,7 @@ namespace Dalamud.Game.ClientState.Keys; /// [PluginInterface] [InterfaceVersion("1.0")] -[ServiceManager.BlockingEarlyLoadedService] +[ServiceManager.EarlyLoadedService] #pragma warning disable SA1015 [ResolveVia] #pragma warning restore SA1015 diff --git a/Dalamud/Game/ClientState/Objects/ObjectTable.cs b/Dalamud/Game/ClientState/Objects/ObjectTable.cs index 9b42e1024..220321157 100644 --- a/Dalamud/Game/ClientState/Objects/ObjectTable.cs +++ b/Dalamud/Game/ClientState/Objects/ObjectTable.cs @@ -24,7 +24,7 @@ namespace Dalamud.Game.ClientState.Objects; /// [PluginInterface] [InterfaceVersion("1.0")] -[ServiceManager.BlockingEarlyLoadedService] +[ServiceManager.EarlyLoadedService] #pragma warning disable SA1015 [ResolveVia] #pragma warning restore SA1015 diff --git a/Dalamud/Game/ClientState/Objects/TargetManager.cs b/Dalamud/Game/ClientState/Objects/TargetManager.cs index fcb242c1e..844813af4 100644 --- a/Dalamud/Game/ClientState/Objects/TargetManager.cs +++ b/Dalamud/Game/ClientState/Objects/TargetManager.cs @@ -12,7 +12,7 @@ namespace Dalamud.Game.ClientState.Objects; /// [PluginInterface] [InterfaceVersion("1.0")] -[ServiceManager.BlockingEarlyLoadedService] +[ServiceManager.EarlyLoadedService] #pragma warning disable SA1015 [ResolveVia] #pragma warning restore SA1015 diff --git a/Dalamud/Game/ClientState/Party/PartyList.cs b/Dalamud/Game/ClientState/Party/PartyList.cs index 946c73245..0e16306f1 100644 --- a/Dalamud/Game/ClientState/Party/PartyList.cs +++ b/Dalamud/Game/ClientState/Party/PartyList.cs @@ -15,7 +15,7 @@ namespace Dalamud.Game.ClientState.Party; /// [PluginInterface] [InterfaceVersion("1.0")] -[ServiceManager.BlockingEarlyLoadedService] +[ServiceManager.EarlyLoadedService] #pragma warning disable SA1015 [ResolveVia] #pragma warning restore SA1015 diff --git a/Dalamud/Game/Command/CommandManager.cs b/Dalamud/Game/Command/CommandManager.cs index 7dcca763b..6a419a34a 100644 --- a/Dalamud/Game/Command/CommandManager.cs +++ b/Dalamud/Game/Command/CommandManager.cs @@ -18,7 +18,7 @@ namespace Dalamud.Game.Command; /// This class manages registered in-game slash commands. /// [InterfaceVersion("1.0")] -[ServiceManager.BlockingEarlyLoadedService] +[ServiceManager.EarlyLoadedService] internal sealed class CommandManager : IInternalDisposableService, ICommandManager { private static readonly ModuleLog Log = new("Command"); diff --git a/Dalamud/Game/Config/GameConfig.cs b/Dalamud/Game/Config/GameConfig.cs index a021025b1..7bcb8ba2b 100644 --- a/Dalamud/Game/Config/GameConfig.cs +++ b/Dalamud/Game/Config/GameConfig.cs @@ -14,7 +14,7 @@ namespace Dalamud.Game.Config; /// This class represents the game's configuration. /// [InterfaceVersion("1.0")] -[ServiceManager.BlockingEarlyLoadedService] +[ServiceManager.EarlyLoadedService] internal sealed class GameConfig : IInternalDisposableService, IGameConfig { private readonly TaskCompletionSource tcsInitialization = new(); diff --git a/Dalamud/Game/DutyState/DutyState.cs b/Dalamud/Game/DutyState/DutyState.cs index e2e4aef15..8dca5649e 100644 --- a/Dalamud/Game/DutyState/DutyState.cs +++ b/Dalamud/Game/DutyState/DutyState.cs @@ -12,7 +12,7 @@ namespace Dalamud.Game.DutyState; /// This class represents the state of the currently occupied duty. /// [InterfaceVersion("1.0")] -[ServiceManager.BlockingEarlyLoadedService] +[ServiceManager.EarlyLoadedService] internal unsafe class DutyState : IInternalDisposableService, IDutyState { private readonly DutyStateAddressResolver address; diff --git a/Dalamud/Game/Framework.cs b/Dalamud/Game/Framework.cs index 35ac2fd10..93c1c47ea 100644 --- a/Dalamud/Game/Framework.cs +++ b/Dalamud/Game/Framework.cs @@ -22,15 +22,13 @@ namespace Dalamud.Game; /// This class represents the Framework of the native game client and grants access to various subsystems. /// [InterfaceVersion("1.0")] -[ServiceManager.BlockingEarlyLoadedService] +[ServiceManager.EarlyLoadedService] internal sealed class Framework : IInternalDisposableService, IFramework { private static readonly ModuleLog Log = new("Framework"); private static readonly Stopwatch StatsStopwatch = new(); - private readonly GameLifecycle lifecycle; - private readonly Stopwatch updateStopwatch = new(); private readonly HitchDetector hitchDetector; @@ -38,6 +36,9 @@ internal sealed class Framework : IInternalDisposableService, IFramework private readonly Hook destroyHook; private readonly FrameworkAddressResolver addressResolver; + + [ServiceManager.ServiceDependency] + private readonly GameLifecycle lifecycle = Service.Get(); [ServiceManager.ServiceDependency] private readonly DalamudConfiguration configuration = Service.Get(); @@ -51,9 +52,8 @@ internal sealed class Framework : IInternalDisposableService, IFramework private ulong tickCounter; [ServiceManager.ServiceConstructor] - private Framework(TargetSigScanner sigScanner, GameLifecycle lifecycle) + private Framework(TargetSigScanner sigScanner) { - this.lifecycle = lifecycle; this.hitchDetector = new HitchDetector("FrameworkUpdate", this.configuration.FrameworkUpdateHitch); this.addressResolver = new FrameworkAddressResolver(); @@ -90,7 +90,7 @@ internal sealed class Framework : IInternalDisposableService, IFramework /// /// Executes during FrameworkUpdate before all delegates. /// - internal event IFramework.OnUpdateDelegate BeforeUpdate; + internal event IFramework.OnUpdateDelegate? BeforeUpdate; /// /// Gets or sets a value indicating whether the collection of stats is enabled. diff --git a/Dalamud/Game/GameLifecycle.cs b/Dalamud/Game/GameLifecycle.cs index 4192d055b..eabb0f53b 100644 --- a/Dalamud/Game/GameLifecycle.cs +++ b/Dalamud/Game/GameLifecycle.cs @@ -11,7 +11,7 @@ namespace Dalamud.Game; /// [PluginInterface] [InterfaceVersion("1.0")] -[ServiceManager.BlockingEarlyLoadedService] +[ServiceManager.EarlyLoadedService] #pragma warning disable SA1015 [ResolveVia] #pragma warning restore SA1015 diff --git a/Dalamud/Game/Gui/ChatGui.cs b/Dalamud/Game/Gui/ChatGui.cs index e0b90b382..2361ec653 100644 --- a/Dalamud/Game/Gui/ChatGui.cs +++ b/Dalamud/Game/Gui/ChatGui.cs @@ -12,6 +12,7 @@ using Dalamud.IoC; using Dalamud.IoC.Internal; using Dalamud.Logging.Internal; using Dalamud.Memory; +using Dalamud.Plugin.Internal; using Dalamud.Plugin.Services; using Dalamud.Utility; using FFXIVClientStructs.FFXIV.Client.System.String; @@ -28,7 +29,7 @@ namespace Dalamud.Game.Gui; /// This class handles interacting with the native chat UI. /// [InterfaceVersion("1.0")] -[ServiceManager.BlockingEarlyLoadedService] +[ServiceManager.EarlyLoadedService] internal sealed unsafe class ChatGui : IInternalDisposableService, IChatGui { private static readonly ModuleLog Log = new("ChatGui"); diff --git a/Dalamud/Game/Gui/Dtr/DtrBar.cs b/Dalamud/Game/Gui/Dtr/DtrBar.cs index dbf6fba3c..b28c9a7d9 100644 --- a/Dalamud/Game/Gui/Dtr/DtrBar.cs +++ b/Dalamud/Game/Gui/Dtr/DtrBar.cs @@ -21,7 +21,7 @@ namespace Dalamud.Game.Gui.Dtr; /// Class used to interface with the server info bar. /// [InterfaceVersion("1.0")] -[ServiceManager.BlockingEarlyLoadedService] +[ServiceManager.EarlyLoadedService] internal sealed unsafe class DtrBar : IInternalDisposableService, IDtrBar { private const uint BaseNodeId = 1000; diff --git a/Dalamud/Game/Gui/FlyText/FlyTextGui.cs b/Dalamud/Game/Gui/FlyText/FlyTextGui.cs index 9310529e4..61bfc5d0a 100644 --- a/Dalamud/Game/Gui/FlyText/FlyTextGui.cs +++ b/Dalamud/Game/Gui/FlyText/FlyTextGui.cs @@ -15,7 +15,7 @@ namespace Dalamud.Game.Gui.FlyText; /// This class facilitates interacting with and creating native in-game "fly text". /// [InterfaceVersion("1.0")] -[ServiceManager.BlockingEarlyLoadedService] +[ServiceManager.EarlyLoadedService] internal sealed class FlyTextGui : IInternalDisposableService, IFlyTextGui { /// diff --git a/Dalamud/Game/Gui/GameGui.cs b/Dalamud/Game/Gui/GameGui.cs index 9272aa824..bdc483655 100644 --- a/Dalamud/Game/Gui/GameGui.cs +++ b/Dalamud/Game/Gui/GameGui.cs @@ -26,7 +26,7 @@ namespace Dalamud.Game.Gui; /// A class handling many aspects of the in-game UI. /// [InterfaceVersion("1.0")] -[ServiceManager.BlockingEarlyLoadedService] +[ServiceManager.EarlyLoadedService] internal sealed unsafe class GameGui : IInternalDisposableService, IGameGui { private static readonly ModuleLog Log = new("GameGui"); diff --git a/Dalamud/Game/Gui/PartyFinder/PartyFinderGui.cs b/Dalamud/Game/Gui/PartyFinder/PartyFinderGui.cs index f19fe3b0a..beac09478 100644 --- a/Dalamud/Game/Gui/PartyFinder/PartyFinderGui.cs +++ b/Dalamud/Game/Gui/PartyFinder/PartyFinderGui.cs @@ -14,7 +14,7 @@ namespace Dalamud.Game.Gui.PartyFinder; /// This class handles interacting with the native PartyFinder window. /// [InterfaceVersion("1.0")] -[ServiceManager.BlockingEarlyLoadedService] +[ServiceManager.EarlyLoadedService] internal sealed class PartyFinderGui : IInternalDisposableService, IPartyFinderGui { private readonly PartyFinderAddressResolver address; diff --git a/Dalamud/Game/Gui/Toast/ToastGui.cs b/Dalamud/Game/Gui/Toast/ToastGui.cs index 2cf327007..057b929ad 100644 --- a/Dalamud/Game/Gui/Toast/ToastGui.cs +++ b/Dalamud/Game/Gui/Toast/ToastGui.cs @@ -13,7 +13,7 @@ namespace Dalamud.Game.Gui.Toast; /// This class facilitates interacting with and creating native toast windows. /// [InterfaceVersion("1.0")] -[ServiceManager.BlockingEarlyLoadedService] +[ServiceManager.EarlyLoadedService] internal sealed partial class ToastGui : IInternalDisposableService, IToastGui { private const uint QuestToastCheckmarkMagic = 60081; diff --git a/Dalamud/Game/Inventory/GameInventory.cs b/Dalamud/Game/Inventory/GameInventory.cs index 3e3dbc685..dde0e3614 100644 --- a/Dalamud/Game/Inventory/GameInventory.cs +++ b/Dalamud/Game/Inventory/GameInventory.cs @@ -18,7 +18,7 @@ namespace Dalamud.Game.Inventory; /// This class provides events for the players in-game inventory. /// [InterfaceVersion("1.0")] -[ServiceManager.BlockingEarlyLoadedService] +[ServiceManager.EarlyLoadedService] internal class GameInventory : IInternalDisposableService { private readonly List subscribersPendingChange = new(); diff --git a/Dalamud/Game/Libc/LibcFunction.cs b/Dalamud/Game/Libc/LibcFunction.cs index f1cd07080..73ccc4399 100644 --- a/Dalamud/Game/Libc/LibcFunction.cs +++ b/Dalamud/Game/Libc/LibcFunction.cs @@ -13,7 +13,7 @@ namespace Dalamud.Game.Libc; /// [PluginInterface] [InterfaceVersion("1.0")] -[ServiceManager.BlockingEarlyLoadedService] +[ServiceManager.EarlyLoadedService] #pragma warning disable SA1015 [ResolveVia] #pragma warning restore SA1015 diff --git a/Dalamud/Game/Network/GameNetwork.cs b/Dalamud/Game/Network/GameNetwork.cs index 954612af7..1a96d8514 100644 --- a/Dalamud/Game/Network/GameNetwork.cs +++ b/Dalamud/Game/Network/GameNetwork.cs @@ -14,7 +14,7 @@ namespace Dalamud.Game.Network; /// This class handles interacting with game network events. /// [InterfaceVersion("1.0")] -[ServiceManager.BlockingEarlyLoadedService] +[ServiceManager.EarlyLoadedService] internal sealed class GameNetwork : IInternalDisposableService, IGameNetwork { private readonly GameNetworkAddressResolver address; diff --git a/Dalamud/Game/Network/Internal/NetworkHandlers.cs b/Dalamud/Game/Network/Internal/NetworkHandlers.cs index 2a46af3d3..167a3fcaa 100644 --- a/Dalamud/Game/Network/Internal/NetworkHandlers.cs +++ b/Dalamud/Game/Network/Internal/NetworkHandlers.cs @@ -25,7 +25,7 @@ namespace Dalamud.Game.Network.Internal; /// /// This class handles network notifications and uploading market board data. /// -[ServiceManager.BlockingEarlyLoadedService] +[ServiceManager.EarlyLoadedService] internal unsafe class NetworkHandlers : IInternalDisposableService { private readonly IMarketBoardUploader uploader; diff --git a/Dalamud/Hooking/WndProcHook/WndProcHookManager.cs b/Dalamud/Hooking/WndProcHook/WndProcHookManager.cs index a2253eb23..e8e0b7536 100644 --- a/Dalamud/Hooking/WndProcHook/WndProcHookManager.cs +++ b/Dalamud/Hooking/WndProcHook/WndProcHookManager.cs @@ -14,7 +14,7 @@ namespace Dalamud.Hooking.WndProcHook; /// /// Manages WndProc hooks for game main window and extra ImGui viewport windows. /// -[ServiceManager.BlockingEarlyLoadedService] +[ServiceManager.EarlyLoadedService] internal sealed class WndProcHookManager : IInternalDisposableService { private static readonly ModuleLog Log = new(nameof(WndProcHookManager)); diff --git a/Dalamud/Interface/DragDrop/DragDropManager.cs b/Dalamud/Interface/DragDrop/DragDropManager.cs index adc0ebff7..be1865415 100644 --- a/Dalamud/Interface/DragDrop/DragDropManager.cs +++ b/Dalamud/Interface/DragDrop/DragDropManager.cs @@ -15,7 +15,7 @@ namespace Dalamud.Interface.DragDrop; /// and can be used to create ImGui drag and drop sources and targets for those external events. /// [PluginInterface] -[ServiceManager.BlockingEarlyLoadedService] +[ServiceManager.EarlyLoadedService] #pragma warning disable SA1015 [ResolveVia] #pragma warning restore SA1015 diff --git a/Dalamud/Interface/Internal/InterfaceManager.cs b/Dalamud/Interface/Internal/InterfaceManager.cs index be14b882b..f72f53777 100644 --- a/Dalamud/Interface/Internal/InterfaceManager.cs +++ b/Dalamud/Interface/Internal/InterfaceManager.cs @@ -51,7 +51,7 @@ namespace Dalamud.Interface.Internal; /// /// This class manages interaction with the ImGui interface. /// -[ServiceManager.BlockingEarlyLoadedService] +[ServiceManager.EarlyLoadedService] internal class InterfaceManager : IInternalDisposableService { /// diff --git a/Dalamud/Interface/Internal/TextureManager.cs b/Dalamud/Interface/Internal/TextureManager.cs index 74ce91e5e..21c5c8cd9 100644 --- a/Dalamud/Interface/Internal/TextureManager.cs +++ b/Dalamud/Interface/Internal/TextureManager.cs @@ -22,7 +22,7 @@ namespace Dalamud.Interface.Internal; /// [PluginInterface] [InterfaceVersion("1.0")] -[ServiceManager.BlockingEarlyLoadedService] +[ServiceManager.EarlyLoadedService] #pragma warning disable SA1015 [ResolveVia] [ResolveVia] diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/ServicesWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/ServicesWidget.cs index 22b53cdaa..3a6145030 100644 --- a/Dalamud/Interface/Internal/Windows/Data/Widgets/ServicesWidget.cs +++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/ServicesWidget.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Linq; using System.Numerics; +using System.Reflection; using Dalamud.Interface.Colors; using Dalamud.Interface.Utility; @@ -96,7 +97,7 @@ internal class ServicesWidget : IDataWindowWidget var rowWidth = 0f; foreach (var node in levelNodes) - rowWidth += ImGui.CalcTextSize(node.TypeName).X + cellPad.X + margin.X; + rowWidth += node.DisplayedNameSize.X + cellPad.X + margin.X; var off = cellPad / 2; if (rowWidth < width) @@ -107,7 +108,7 @@ internal class ServicesWidget : IDataWindowWidget foreach (var node in levelNodes) { - var textSize = ImGui.CalcTextSize(node.TypeName); + var textSize = node.DisplayedNameSize; var cellSize = textSize + cellPad; var rc = new Vector4(pos + off, pos.X + off.X + cellSize.X, pos.Y + off.Y + cellSize.Y); @@ -174,7 +175,7 @@ internal class ServicesWidget : IDataWindowWidget { foreach (var node in levelNodes) { - var textSize = ImGui.CalcTextSize(node.TypeName); + var textSize = node.DisplayedNameSize; var cellSize = textSize + cellPad; var rc = this.nodeRects[node]; @@ -188,8 +189,19 @@ internal class ServicesWidget : IDataWindowWidget dl.AddRectFilled(new(rc.X, rc.Y), new(rc.Z, rc.W), rectHoverRelatedFillColor); dl.AddRect(new(rc.X, rc.Y), new(rc.Z, rc.W), rectBaseBorderColor); + ImGui.SetCursorScreenPos(new(rc.X, rc.Y)); + ImGui.InvisibleButton(node.DisplayedName, new(rc.Z - rc.X, rc.W - rc.Y)); + if (ImGui.IsItemHovered() && node.BlockingReason is not null) + ImGui.SetTooltip(node.BlockingReason); + ImGui.SetCursorPos((new Vector2(rc.X, rc.Y) - pos) + ((cellSize - textSize) / 2)); - ImGui.TextUnformatted(node.TypeName); + ImGui.PushStyleVar(ImGuiStyleVar.ItemSpacing, Vector2.Zero); + ImGui.TextUnformatted(node.DisplayedName); + ImGui.SameLine(); + ImGui.PushStyleColor(ImGuiCol.Text, node.TypeSuffixColor); + ImGui.TextUnformatted(node.TypeSuffix); + ImGui.PopStyleVar(); + ImGui.PopStyleColor(); } } @@ -259,11 +271,44 @@ internal class ServicesWidget : IDataWindowWidget private readonly List children = new(); private readonly List invalidParents = new(); - private ServiceDependencyNode(Type t) => this.Type = t; + private ServiceDependencyNode(Type t) + { + this.Type = t; + this.BlockingReason = + t.GetCustomAttribute()?.BlockReason; + this.Kind = t.GetCustomAttribute()?.Kind ?? + ServiceManager.ServiceKind.None; + this.DisplayedName = this.Type.Name; + this.TypeSuffix = this.Kind switch { + ServiceManager.ServiceKind.ProvidedService => " (P)", + ServiceManager.ServiceKind.EarlyLoadedService => " (E)", + ServiceManager.ServiceKind.BlockingEarlyLoadedService => " (B)", + ServiceManager.ServiceKind.ScopedService => " (S)", + var x => $" (? {x})", + }; + this.TypeSuffixColor = this.Kind switch { + ServiceManager.ServiceKind.ProvidedService => ImGui.GetColorU32(ImGuiColors.DalamudGrey), + ServiceManager.ServiceKind.EarlyLoadedService => ImGui.GetColorU32(ImGuiColors.DalamudWhite), + ServiceManager.ServiceKind.BlockingEarlyLoadedService => ImGui.GetColorU32(ImGuiColors.ParsedPink), + ServiceManager.ServiceKind.ScopedService => ImGui.GetColorU32(ImGuiColors.ParsedGreen), + _ => ImGui.GetColorU32(ImGuiColors.DalamudRed), + }; + } public Type Type { get; } - public string TypeName => this.Type.Name; + public string DisplayedName { get; } + + public string TypeSuffix { get; } + + public uint TypeSuffixColor { get; } + + public Vector2 DisplayedNameSize => + ImGui.CalcTextSize(this.DisplayedName) + ImGui.CalcTextSize(this.TypeSuffix) with { Y = 0 }; + + public ServiceManager.ServiceKind Kind { get; } + + public string? BlockingReason { get; } public IReadOnlyList Parents => this.parents; diff --git a/Dalamud/Interface/Internal/Windows/ProfilerWindow.cs b/Dalamud/Interface/Internal/Windows/ProfilerWindow.cs index cd653143b..93b75976a 100644 --- a/Dalamud/Interface/Internal/Windows/ProfilerWindow.cs +++ b/Dalamud/Interface/Internal/Windows/ProfilerWindow.cs @@ -25,7 +25,7 @@ public class ProfilerWindow : Window /// Initializes a new instance of the class. /// public ProfilerWindow() - : base("Profiler", forceMainWindow: true) + : base("Profiler") { } diff --git a/Dalamud/Interface/ManagedFontAtlas/Internals/FontAtlasFactory.cs b/Dalamud/Interface/ManagedFontAtlas/Internals/FontAtlasFactory.cs index 7fa41487a..2e39dcc5e 100644 --- a/Dalamud/Interface/ManagedFontAtlas/Internals/FontAtlasFactory.cs +++ b/Dalamud/Interface/ManagedFontAtlas/Internals/FontAtlasFactory.cs @@ -29,7 +29,7 @@ namespace Dalamud.Interface.ManagedFontAtlas.Internals; /// /// Factory for the implementation of . /// -[ServiceManager.BlockingEarlyLoadedService] +[ServiceManager.EarlyLoadedService] internal sealed partial class FontAtlasFactory : IInternalDisposableService, GamePrebakedFontHandle.IGameFontTextureProvider { diff --git a/Dalamud/Interface/TitleScreenMenu/TitleScreenMenu.cs b/Dalamud/Interface/TitleScreenMenu/TitleScreenMenu.cs index 6fbc0b4f3..69dd7c2f5 100644 --- a/Dalamud/Interface/TitleScreenMenu/TitleScreenMenu.cs +++ b/Dalamud/Interface/TitleScreenMenu/TitleScreenMenu.cs @@ -15,7 +15,7 @@ namespace Dalamud.Interface; /// Class responsible for managing elements in the title screen menu. /// [InterfaceVersion("1.0")] -[ServiceManager.BlockingEarlyLoadedService] +[ServiceManager.EarlyLoadedService] internal class TitleScreenMenu : IServiceType, ITitleScreenMenu { /// diff --git a/Dalamud/Networking/Http/HappyHttpClient.cs b/Dalamud/Networking/Http/HappyHttpClient.cs index 23c6e3899..37e327e84 100644 --- a/Dalamud/Networking/Http/HappyHttpClient.cs +++ b/Dalamud/Networking/Http/HappyHttpClient.cs @@ -3,6 +3,7 @@ using System.Net; using System.Net.Http; using System.Net.Http.Headers; +using Dalamud.Plugin.Internal; using Dalamud.Utility; namespace Dalamud.Networking.Http; @@ -11,7 +12,9 @@ namespace Dalamud.Networking.Http; /// A service to help build and manage HttpClients with some semblance of Happy Eyeballs (RFC 8305 - IPv4 fallback) /// awareness. /// -[ServiceManager.BlockingEarlyLoadedService] +[ServiceManager.BlockingEarlyLoadedService($"{nameof(PluginManager)} currently uses this.")] +// ^ TODO: This seems unnecessary, remove the hard dependency at a later time. +// Otherwise, if PM eventually marks this class as required, note that in the comment above. internal class HappyHttpClient : IInternalDisposableService { /// diff --git a/Dalamud/Plugin/Internal/PluginManager.cs b/Dalamud/Plugin/Internal/PluginManager.cs index 9e3eae9f8..5924a4e08 100644 --- a/Dalamud/Plugin/Internal/PluginManager.cs +++ b/Dalamud/Plugin/Internal/PluginManager.cs @@ -39,22 +39,10 @@ namespace Dalamud.Plugin.Internal; /// /// Class responsible for loading and unloading plugins. -/// NOTE: ALL plugin exposed services are marked as dependencies for PluginManager in Service{T}. +/// NOTE: ALL plugin exposed services are marked as dependencies for +/// from . /// -[ServiceManager.BlockingEarlyLoadedService] -#pragma warning disable SA1015 - -// DalamudTextureWrap registers textures to dispose with IM -[InherentDependency] - -// LocalPlugin uses ServiceContainer to create scopes -[InherentDependency] - -// DalamudPluginInterface hands out a reference to this, so we have to keep it around -// TODO api9: make it a service -[InherentDependency] - -#pragma warning restore SA1015 +[ServiceManager.BlockingEarlyLoadedService("Accomodation of plugins that blocks the game startup.")] internal partial class PluginManager : IInternalDisposableService { /// @@ -72,7 +60,7 @@ internal partial class PluginManager : IInternalDisposableService private readonly List availablePluginsList = new(); private readonly List updatablePluginsList = new(); - private readonly DalamudLinkPayload openInstallerWindowPluginChangelogsLink; + private readonly Task openInstallerWindowPluginChangelogsLink; [ServiceManager.ServiceDependency] private readonly DalamudConfiguration configuration = Service.Get(); @@ -86,9 +74,6 @@ internal partial class PluginManager : IInternalDisposableService [ServiceManager.ServiceDependency] private readonly HappyHttpClient happyHttpClient = Service.Get(); - [ServiceManager.ServiceDependency] - private readonly ChatGui chatGui = Service.Get(); - static PluginManager() { DalamudApiLevel = typeof(PluginManager).Assembly.GetName().Version!.Major; @@ -137,10 +122,16 @@ internal partial class PluginManager : IInternalDisposableService throw new InvalidDataException("Couldn't deserialize banned plugins manifest."); } - this.openInstallerWindowPluginChangelogsLink = this.chatGui.AddChatLinkHandler("Dalamud", 1003, (_, _) => - { - Service.GetNullable()?.OpenPluginInstallerTo(PluginInstallerWindow.PluginInstallerOpenKind.Changelogs); - }); + this.openInstallerWindowPluginChangelogsLink = + Service.GetAsync().ContinueWith( + chatGuiTask => chatGuiTask.Result.AddChatLinkHandler( + "Dalamud", + 1003, + (_, _) => + { + Service.GetNullable()?.OpenPluginInstallerTo( + PluginInstallerWindow.PluginInstallerOpenKind.Changelogs); + })); this.configuration.PluginTestingOptIns ??= new(); this.MainRepo = PluginRepository.CreateMainRepo(this.happyHttpClient); @@ -304,41 +295,54 @@ internal partial class PluginManager : IInternalDisposableService /// The list of updated plugin metadata. /// The header text to send to chat prior to any update info. public void PrintUpdatedPlugins(List? updateMetadata, string header) - { - if (updateMetadata is { Count: > 0 }) - { - this.chatGui.Print(new XivChatEntry + => Service.GetAsync().ContinueWith( + chatGuiTask => { - Message = new SeString(new List() - { - new TextPayload(header), - new TextPayload(" ["), - new UIForegroundPayload(500), - this.openInstallerWindowPluginChangelogsLink, - new TextPayload(Loc.Localize("DalamudInstallerPluginChangelogHelp", "Open plugin changelogs")), - RawPayload.LinkTerminator, - new UIForegroundPayload(0), - new TextPayload("]"), - }), - }); + if (!chatGuiTask.IsCompletedSuccessfully) + return; - foreach (var metadata in updateMetadata) - { - if (metadata.Status == PluginUpdateStatus.StatusKind.Success) + var chatGui = chatGuiTask.Result; + if (updateMetadata is { Count: > 0 }) { - this.chatGui.Print(Locs.DalamudPluginUpdateSuccessful(metadata.Name, metadata.Version)); - } - else - { - this.chatGui.Print(new XivChatEntry + chatGui.Print( + new XivChatEntry + { + Message = new SeString( + new List() + { + new TextPayload(header), + new TextPayload(" ["), + new UIForegroundPayload(500), + this.openInstallerWindowPluginChangelogsLink.Result, + new TextPayload( + Loc.Localize("DalamudInstallerPluginChangelogHelp", "Open plugin changelogs")), + RawPayload.LinkTerminator, + new UIForegroundPayload(0), + new TextPayload("]"), + }), + }); + + foreach (var metadata in updateMetadata) { - Message = Locs.DalamudPluginUpdateFailed(metadata.Name, metadata.Version, PluginUpdateStatus.LocalizeUpdateStatusKind(metadata.Status)), - Type = XivChatType.Urgent, - }); + if (metadata.Status == PluginUpdateStatus.StatusKind.Success) + { + chatGui.Print(Locs.DalamudPluginUpdateSuccessful(metadata.Name, metadata.Version)); + } + else + { + chatGui.Print( + new XivChatEntry + { + Message = Locs.DalamudPluginUpdateFailed( + metadata.Name, + metadata.Version, + PluginUpdateStatus.LocalizeUpdateStatusKind(metadata.Status)), + Type = XivChatType.Urgent, + }); + } + } } - } - } - } + }); /// /// For a given manifest, determine if the user opted into testing this plugin. @@ -1257,6 +1261,16 @@ internal partial class PluginManager : IInternalDisposableService /// The dependency services. private static IEnumerable ResolvePossiblePluginDependencyServices() { + // DalamudPluginInterface hands out a reference to this, so we have to keep it around. + // TODO api9: make it a service + yield return typeof(DataShare); + + // DalamudTextureWrap registers textures to dispose with IM. + yield return typeof(InterfaceManager); + + // Note: LocalPlugin uses ServiceContainer to create scopes, but it is done outside PM ctor. + // This is not required: yield return typeof(ServiceContainer); + foreach (var serviceType in ServiceManager.GetConcreteServiceTypes()) { if (serviceType == typeof(PluginManager)) diff --git a/Dalamud/Plugin/Internal/Profiles/ProfileManager.cs b/Dalamud/Plugin/Internal/Profiles/ProfileManager.cs index 10d94de73..ee8505174 100644 --- a/Dalamud/Plugin/Internal/Profiles/ProfileManager.cs +++ b/Dalamud/Plugin/Internal/Profiles/ProfileManager.cs @@ -15,7 +15,7 @@ namespace Dalamud.Plugin.Internal.Profiles; /// /// Class responsible for managing plugin profiles. /// -[ServiceManager.BlockingEarlyLoadedService] +[ServiceManager.BlockingEarlyLoadedService($"Data provider for {nameof(PluginManager)}.")] internal class ProfileManager : IServiceType { private static readonly ModuleLog Log = new("PROFMAN"); diff --git a/Dalamud/Plugin/Ipc/Internal/DataShare.cs b/Dalamud/Plugin/Ipc/Internal/DataShare.cs index b122f481d..0d3eb1a10 100644 --- a/Dalamud/Plugin/Ipc/Internal/DataShare.cs +++ b/Dalamud/Plugin/Ipc/Internal/DataShare.cs @@ -11,7 +11,7 @@ namespace Dalamud.Plugin.Ipc.Internal; /// /// This class facilitates sharing data-references of standard types between plugins without using more expensive IPC. /// -[ServiceManager.BlockingEarlyLoadedService] +[ServiceManager.EarlyLoadedService] internal class DataShare : IServiceType { /// diff --git a/Dalamud/ServiceManager.cs b/Dalamud/ServiceManager.cs index 845a65d6e..bdc0918b0 100644 --- a/Dalamud/ServiceManager.cs +++ b/Dalamud/ServiceManager.cs @@ -638,10 +638,15 @@ internal static class ServiceManager /// /// Initializes a new instance of the class. /// - public BlockingEarlyLoadedServiceAttribute() + /// Reason of blocking the game startup. + public BlockingEarlyLoadedServiceAttribute(string blockReason) : base(ServiceKind.BlockingEarlyLoadedService) { + this.BlockReason = blockReason; } + + /// Gets the reason of blocking the startup of the game. + public string BlockReason { get; } } /// diff --git a/Dalamud/Service{T}.cs b/Dalamud/Service{T}.cs index ed03749d5..165257ef5 100644 --- a/Dalamud/Service{T}.cs +++ b/Dalamud/Service{T}.cs @@ -6,6 +6,7 @@ using System.Threading.Tasks; using Dalamud.IoC; using Dalamud.IoC.Internal; +using Dalamud.Utility; using Dalamud.Utility.Timing; using JetBrains.Annotations; @@ -198,13 +199,16 @@ internal static class Service where T : IServiceType .ToArray(); if (offenders.Any()) { - ServiceManager.Log.Error( - "{me} is a {bels}; it can only depend on {bels} and {ps}.\nOffending dependencies:\n{offenders}", - typeof(T), - nameof(ServiceManager.BlockingEarlyLoadedServiceAttribute), - nameof(ServiceManager.BlockingEarlyLoadedServiceAttribute), - nameof(ServiceManager.ProvidedServiceAttribute), - string.Join("\n", offenders.Select(x => $"\t* {x.Name}"))); + const string bels = nameof(ServiceManager.BlockingEarlyLoadedServiceAttribute); + const string ps = nameof(ServiceManager.ProvidedServiceAttribute); + var errmsg = + $"{typeof(T)} is a {bels}; it can only depend on {bels} and {ps}.\nOffending dependencies:\n" + + string.Join("\n", offenders.Select(x => $"\t* {x.Name}")); +#if DEBUG + Util.Fatal(errmsg, "Service Dependency Check"); +#else + ServiceManager.Log.Error(errmsg); +#endif } } diff --git a/Dalamud/Storage/Assets/DalamudAssetManager.cs b/Dalamud/Storage/Assets/DalamudAssetManager.cs index 4f53460fb..3536bfb52 100644 --- a/Dalamud/Storage/Assets/DalamudAssetManager.cs +++ b/Dalamud/Storage/Assets/DalamudAssetManager.cs @@ -23,7 +23,8 @@ namespace Dalamud.Storage.Assets; /// A concrete class for . /// [PluginInterface] -[ServiceManager.BlockingEarlyLoadedService] +[ServiceManager.BlockingEarlyLoadedService( + "Ensuring that it is worth continuing loading Dalamud, by checking if all required assets are properly available.")] #pragma warning disable SA1015 [ResolveVia] #pragma warning restore SA1015