From a8e00f91e7837458cad2221b82b8d7ed9df2f7ee Mon Sep 17 00:00:00 2001 From: goat <16760685+goaaats@users.noreply.github.com> Date: Tue, 10 Aug 2021 23:33:37 +0200 Subject: [PATCH] feat: add self test --- .../Interface/Internal/DalamudInterface.cs | 21 ++ .../AgingSteps/ActorTableAgingStep.cs | 45 +++ .../SelfTest/AgingSteps/ChatAgingStep.cs | 68 +++++ .../SelfTest/AgingSteps/ConditionAgingStep.cs | 35 +++ .../AgingSteps/EnterTerritoryAgingStep.cs | 65 +++++ .../SelfTest/AgingSteps/FateTableAgingStep.cs | 45 +++ .../AgingSteps/GamepadStateAgingStep.cs | 35 +++ .../SelfTest/AgingSteps/HoverAgingStep.cs | 58 ++++ .../Windows/SelfTest/AgingSteps/IAgingStep.cs | 26 ++ .../SelfTest/AgingSteps/KeyStateAgingStep.cs | 37 +++ .../AgingSteps/LoginEventAgingStep.cs | 54 ++++ .../SelfTest/AgingSteps/LuminaAgingStep.cs | 39 +++ .../AgingSteps/PartyFinderAgingStep.cs | 53 ++++ .../SelfTest/AgingSteps/TargetAgingStep.cs | 73 +++++ .../SelfTest/AgingSteps/ToastAgingStep.cs | 26 ++ .../AgingSteps/WaitFramesAgingStep.cs | 38 +++ .../Windows/SelfTest/SelfTestStepResult.cs | 28 ++ .../Windows/SelfTest/SelfTestWindow.cs | 258 ++++++++++++++++++ 18 files changed, 1004 insertions(+) create mode 100644 Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/ActorTableAgingStep.cs create mode 100644 Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/ChatAgingStep.cs create mode 100644 Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/ConditionAgingStep.cs create mode 100644 Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/EnterTerritoryAgingStep.cs create mode 100644 Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/FateTableAgingStep.cs create mode 100644 Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/GamepadStateAgingStep.cs create mode 100644 Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/HoverAgingStep.cs create mode 100644 Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/IAgingStep.cs create mode 100644 Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/KeyStateAgingStep.cs create mode 100644 Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/LoginEventAgingStep.cs create mode 100644 Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/LuminaAgingStep.cs create mode 100644 Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/PartyFinderAgingStep.cs create mode 100644 Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/TargetAgingStep.cs create mode 100644 Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/ToastAgingStep.cs create mode 100644 Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/WaitFramesAgingStep.cs create mode 100644 Dalamud/Interface/Internal/Windows/SelfTest/SelfTestStepResult.cs create mode 100644 Dalamud/Interface/Internal/Windows/SelfTest/SelfTestWindow.cs diff --git a/Dalamud/Interface/Internal/DalamudInterface.cs b/Dalamud/Interface/Internal/DalamudInterface.cs index 3afcbe331..82d328623 100644 --- a/Dalamud/Interface/Internal/DalamudInterface.cs +++ b/Dalamud/Interface/Internal/DalamudInterface.cs @@ -5,6 +5,7 @@ using System.Numerics; using System.Runtime.InteropServices; using Dalamud.Interface.Internal.Windows; +using Dalamud.Interface.Internal.Windows.SelfTest; using Dalamud.Interface.Windowing; using Dalamud.Logging; using Dalamud.Logging.Internal; @@ -36,6 +37,7 @@ namespace Dalamud.Interface.Internal private readonly PluginInstallerWindow pluginWindow; private readonly ScratchpadWindow scratchpadWindow; private readonly SettingsWindow settingsWindow; + private readonly SelfTestWindow selfTestWindow; private ulong frameCount = 0; @@ -67,6 +69,7 @@ namespace Dalamud.Interface.Internal this.pluginWindow = new PluginInstallerWindow(dalamud) { IsOpen = false }; this.scratchpadWindow = new ScratchpadWindow(dalamud) { IsOpen = false }; this.settingsWindow = new SettingsWindow(dalamud) { IsOpen = false }; + this.selfTestWindow = new SelfTestWindow(dalamud) { IsOpen = false }; this.windowSystem.AddWindow(this.changelogWindow); this.windowSystem.AddWindow(this.colorDemoWindow); @@ -79,6 +82,7 @@ namespace Dalamud.Interface.Internal this.windowSystem.AddWindow(this.pluginWindow); this.windowSystem.AddWindow(this.scratchpadWindow); this.windowSystem.AddWindow(this.settingsWindow); + this.windowSystem.AddWindow(this.selfTestWindow); this.dalamud.InterfaceManager.OnDraw += this.OnDraw; @@ -181,6 +185,11 @@ namespace Dalamud.Interface.Internal /// public void OpenSettings() => this.settingsWindow.IsOpen = true; + /// + /// Opens the . + /// + public void OpenSelfTest() => this.selfTestWindow.IsOpen = true; + #endregion #region Toggle @@ -253,6 +262,11 @@ namespace Dalamud.Interface.Internal /// public void ToggleSettingsWindow() => this.settingsWindow.Toggle(); + /// + /// Toggles the . + /// + public void ToggleSelfTestWindow() => this.selfTestWindow.Toggle(); + #endregion private void OnDraw() @@ -383,6 +397,13 @@ namespace Dalamud.Interface.Internal this.OpenColorsDemoWindow(); } + if (ImGui.MenuItem("Open Self-Test")) + { + this.OpenSelfTest(); + } + + ImGui.Separator(); + ImGui.MenuItem("Draw ImGui demo", string.Empty, ref this.isImGuiDrawDemoWindow); ImGui.Separator(); diff --git a/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/ActorTableAgingStep.cs b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/ActorTableAgingStep.cs new file mode 100644 index 000000000..4d927b010 --- /dev/null +++ b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/ActorTableAgingStep.cs @@ -0,0 +1,45 @@ +using Dalamud.Utility; +using ImGuiNET; + +namespace Dalamud.Interface.Internal.Windows.SelfTest.AgingSteps +{ + /// + /// Test setup for the Actor Table. + /// + internal class ActorTableAgingStep : IAgingStep + { + private int index = 0; + + /// + public string Name => "Test ActorTable"; + + /// + public SelfTestStepResult RunStep(Dalamud dalamud) + { + ImGui.Text("Checking actor table..."); + + if (this.index == dalamud.ClientState.Actors.Length - 1) + { + return SelfTestStepResult.Pass; + } + + var actor = dalamud.ClientState.Actors[this.index]; + this.index++; + + if (actor == null) + { + return SelfTestStepResult.Waiting; + } + + Util.ShowObject(actor); + + return SelfTestStepResult.Waiting; + } + + /// + public void CleanUp(Dalamud dalamud) + { + // ignored + } + } +} diff --git a/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/ChatAgingStep.cs b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/ChatAgingStep.cs new file mode 100644 index 000000000..6c58da6b4 --- /dev/null +++ b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/ChatAgingStep.cs @@ -0,0 +1,68 @@ +using Dalamud.Game.Text; +using Dalamud.Game.Text.SeStringHandling; +using ImGuiNET; + +namespace Dalamud.Interface.Internal.Windows.SelfTest.AgingSteps +{ + /// + /// Test setup for Chat. + /// + internal class ChatAgingStep : IAgingStep + { + private int step = 0; + private bool subscribed = false; + private bool hasPassed = false; + + /// + public string Name => "Test Chat"; + + /// + public SelfTestStepResult RunStep(Dalamud dalamud) + { + switch (this.step) + { + case 0: + dalamud.Framework.Gui.Chat.Print("Testing!"); + this.step++; + + break; + + case 1: + ImGui.Text("Type \"/e DALAMUD\" in chat..."); + + if (!this.subscribed) + { + this.subscribed = true; + dalamud.Framework.Gui.Chat.OnChatMessage += this.ChatOnOnChatMessage; + } + + if (this.hasPassed) + { + dalamud.Framework.Gui.Chat.OnChatMessage -= this.ChatOnOnChatMessage; + this.subscribed = false; + return SelfTestStepResult.Pass; + } + + break; + } + + return SelfTestStepResult.Waiting; + } + + /// + public void CleanUp(Dalamud dalamud) + { + dalamud.Framework.Gui.Chat.OnChatMessage -= this.ChatOnOnChatMessage; + this.subscribed = false; + } + + private void ChatOnOnChatMessage( + XivChatType type, uint senderid, ref SeString sender, ref SeString message, ref bool ishandled) + { + if (type == XivChatType.Echo && message.TextValue == "DALAMUD") + { + this.hasPassed = true; + } + } + } +} diff --git a/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/ConditionAgingStep.cs b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/ConditionAgingStep.cs new file mode 100644 index 000000000..2907d39a3 --- /dev/null +++ b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/ConditionAgingStep.cs @@ -0,0 +1,35 @@ +using Dalamud.Game.ClientState.Conditions; +using ImGuiNET; +using Serilog; + +namespace Dalamud.Interface.Internal.Windows.SelfTest.AgingSteps +{ + /// + /// Test setup for Condition. + /// + internal class ConditionAgingStep : IAgingStep + { + /// + public string Name => "Test Condition"; + + /// + public SelfTestStepResult RunStep(Dalamud dalamud) + { + if (!dalamud.ClientState.Condition.Any()) + { + Log.Error("No condition flags present."); + return SelfTestStepResult.Fail; + } + + ImGui.Text("Please jump..."); + + return dalamud.ClientState.Condition[ConditionFlag.Jumping] ? SelfTestStepResult.Pass : SelfTestStepResult.Waiting; + } + + /// + public void CleanUp(Dalamud dalamud) + { + // ignored + } + } +} diff --git a/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/EnterTerritoryAgingStep.cs b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/EnterTerritoryAgingStep.cs new file mode 100644 index 000000000..9db72c197 --- /dev/null +++ b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/EnterTerritoryAgingStep.cs @@ -0,0 +1,65 @@ +using ImGuiNET; + +namespace Dalamud.Interface.Internal.Windows.SelfTest.AgingSteps +{ + /// + /// Test setup for Territory Change. + /// + internal class EnterTerritoryAgingStep : IAgingStep + { + private readonly ushort territory; + private readonly string terriName; + private bool subscribed = false; + private bool hasPassed = false; + + /// + /// Initializes a new instance of the class. + /// + /// The territory to check for. + /// Name to show. + public EnterTerritoryAgingStep(ushort terri, string name) + { + this.terriName = name; + this.territory = terri; + } + + /// + public string Name => $"Enter Terri: {this.terriName}"; + + /// + public SelfTestStepResult RunStep(Dalamud dalamud) + { + ImGui.TextUnformatted(this.Name); + + if (!this.subscribed) + { + dalamud.ClientState.TerritoryChanged += this.ClientStateOnTerritoryChanged; + this.subscribed = true; + } + + if (this.hasPassed) + { + dalamud.ClientState.TerritoryChanged -= this.ClientStateOnTerritoryChanged; + this.subscribed = false; + return SelfTestStepResult.Pass; + } + + return SelfTestStepResult.Waiting; + } + + /// + public void CleanUp(Dalamud dalamud) + { + dalamud.ClientState.TerritoryChanged -= this.ClientStateOnTerritoryChanged; + this.subscribed = false; + } + + private void ClientStateOnTerritoryChanged(object sender, ushort e) + { + if (e == this.territory) + { + this.hasPassed = true; + } + } + } +} diff --git a/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/FateTableAgingStep.cs b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/FateTableAgingStep.cs new file mode 100644 index 000000000..1a34b5a58 --- /dev/null +++ b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/FateTableAgingStep.cs @@ -0,0 +1,45 @@ +using Dalamud.Utility; +using ImGuiNET; + +namespace Dalamud.Interface.Internal.Windows.SelfTest.AgingSteps +{ + /// + /// Test setup for the Fate Table. + /// + internal class FateTableAgingStep : IAgingStep + { + private int index = 0; + + /// + public string Name => "Test FateTable"; + + /// + public SelfTestStepResult RunStep(Dalamud dalamud) + { + ImGui.Text("Checking fate table..."); + + if (this.index == dalamud.ClientState.Fates.Length - 1) + { + return SelfTestStepResult.Pass; + } + + var actor = dalamud.ClientState.Fates[this.index]; + this.index++; + + if (actor == null) + { + return SelfTestStepResult.Waiting; + } + + Util.ShowObject(actor); + + return SelfTestStepResult.Waiting; + } + + /// + public void CleanUp(Dalamud dalamud) + { + // ignored + } + } +} diff --git a/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/GamepadStateAgingStep.cs b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/GamepadStateAgingStep.cs new file mode 100644 index 000000000..443d65843 --- /dev/null +++ b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/GamepadStateAgingStep.cs @@ -0,0 +1,35 @@ +using Dalamud.Game.ClientState.GamePad; +using ImGuiNET; + +namespace Dalamud.Interface.Internal.Windows.SelfTest.AgingSteps +{ + /// + /// Test setup for the Gamepad State. + /// + internal class GamepadStateAgingStep : IAgingStep + { + /// + public string Name => "Test GamePadState"; + + /// + public SelfTestStepResult RunStep(Dalamud dalamud) + { + ImGui.Text("Hold down North, East, L1"); + + if (dalamud.ClientState.GamepadState.Pressed(GamepadButtons.North) == 1 + && dalamud.ClientState.GamepadState.Pressed(GamepadButtons.East) == 1 + && dalamud.ClientState.GamepadState.Pressed(GamepadButtons.L1) == 1) + { + return SelfTestStepResult.Pass; + } + + return SelfTestStepResult.Waiting; + } + + /// + public void CleanUp(Dalamud dalamud) + { + // ignored + } + } +} diff --git a/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/HoverAgingStep.cs b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/HoverAgingStep.cs new file mode 100644 index 000000000..845a5d40d --- /dev/null +++ b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/HoverAgingStep.cs @@ -0,0 +1,58 @@ +using Dalamud.Game.Gui; +using ImGuiNET; + +namespace Dalamud.Interface.Internal.Windows.SelfTest.AgingSteps +{ + /// + /// Test setup for the Hover events. + /// + internal class HoverAgingStep : IAgingStep + { + private bool clearedItem = false; + private bool clearedAction = false; + + /// + public string Name => "Test Hover"; + + /// + public SelfTestStepResult RunStep(Dalamud dalamud) + { + var hoverItem = dalamud.Framework.Gui.HoveredItem; + var hoverAction = dalamud.Framework.Gui.HoveredAction; + + if (!this.clearedItem) + { + ImGui.Text("Hover WHM soul crystal..."); + + if (hoverItem == 4547) + { + this.clearedItem = true; + } + } + + if (!this.clearedAction) + { + ImGui.Text("Hover \"Open Linkshells\" action..."); + + if (hoverAction != null && hoverAction.ActionKind == HoverActionKind.MainCommand && + hoverAction.ActionID == 28) + { + this.clearedAction = true; + } + } + + if (this.clearedItem && this.clearedAction) + { + return SelfTestStepResult.Pass; + } + + return SelfTestStepResult.Waiting; + } + + /// + public void CleanUp(Dalamud dalamud) + { + // ignored + } + } +} diff --git a/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/IAgingStep.cs b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/IAgingStep.cs new file mode 100644 index 000000000..fb1683b40 --- /dev/null +++ b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/IAgingStep.cs @@ -0,0 +1,26 @@ +namespace Dalamud.Interface.Internal.Windows.SelfTest.AgingSteps +{ + /// + /// Interface for test implementations. + /// + internal interface IAgingStep + { + /// + /// Gets the name of the test. + /// + public string Name { get; } + + /// + /// Run the test step, once per frame it is active. + /// + /// Dalamud instance to act on. + /// The result of this frame, test is discarded once a result other than is returned. + public SelfTestStepResult RunStep(Dalamud dalamud); + + /// + /// Clean up this test. + /// + /// Dalamud instance to act on. + public void CleanUp(Dalamud dalamud); + } +} diff --git a/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/KeyStateAgingStep.cs b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/KeyStateAgingStep.cs new file mode 100644 index 000000000..b93ae3165 --- /dev/null +++ b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/KeyStateAgingStep.cs @@ -0,0 +1,37 @@ +using Dalamud.Game.ClientState.Keys; +using ImGuiNET; + +namespace Dalamud.Interface.Internal.Windows.SelfTest.AgingSteps +{ + /// + /// Test setup for the Key State. + /// + internal class KeyStateAgingStep : IAgingStep + { + /// + public string Name => "Test KeyState"; + + /// + public SelfTestStepResult RunStep(Dalamud dalamud) + { + ImGui.Text("Hold down D,A,L,M,U"); + + if (dalamud.ClientState.KeyState[VirtualKey.D] + && dalamud.ClientState.KeyState[VirtualKey.A] + && dalamud.ClientState.KeyState[VirtualKey.L] + && dalamud.ClientState.KeyState[VirtualKey.M] + && dalamud.ClientState.KeyState[VirtualKey.U]) + { + return SelfTestStepResult.Pass; + } + + return SelfTestStepResult.Waiting; + } + + /// + public void CleanUp(Dalamud dalamud) + { + // ignored + } + } +} diff --git a/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/LoginEventAgingStep.cs b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/LoginEventAgingStep.cs new file mode 100644 index 000000000..8a04febf9 --- /dev/null +++ b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/LoginEventAgingStep.cs @@ -0,0 +1,54 @@ +using System; + +using ImGuiNET; + +namespace Dalamud.Interface.Internal.Windows.SelfTest.AgingSteps +{ + /// + /// Test setup for the login events. + /// + internal class LoginEventAgingStep : IAgingStep + { + private bool isSubscribed = false; + private bool hasPassed = false; + + /// + public string Name => "Test Log-In"; + + /// + public SelfTestStepResult RunStep(Dalamud dalamud) + { + ImGui.Text("Log in now..."); + + if (!this.isSubscribed) + { + dalamud.ClientState.OnLogin += this.ClientStateOnOnLogin; + this.isSubscribed = true; + } + + if (this.hasPassed) + { + dalamud.ClientState.OnLogin -= this.ClientStateOnOnLogin; + this.isSubscribed = false; + return SelfTestStepResult.Pass; + } + + return SelfTestStepResult.Waiting; + } + + /// + public void CleanUp(Dalamud dalamud) + { + if (this.isSubscribed) + { + dalamud.ClientState.OnLogin -= this.ClientStateOnOnLogin; + this.isSubscribed = false; + } + } + + private void ClientStateOnOnLogin(object sender, EventArgs e) + { + this.hasPassed = true; + } + } +} diff --git a/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/LuminaAgingStep.cs b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/LuminaAgingStep.cs new file mode 100644 index 000000000..7a8ae0fd6 --- /dev/null +++ b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/LuminaAgingStep.cs @@ -0,0 +1,39 @@ +using System.Collections.Generic; +using System.Linq; + +using Dalamud.Utility; +using Lumina.Excel; + +namespace Dalamud.Interface.Internal.Windows.SelfTest.AgingSteps +{ + /// + /// Test setup for Lumina. + /// + /// ExcelRow to run test on. + internal class LuminaAgingStep : IAgingStep + where T : ExcelRow + { + private int step = 0; + private List rows; + + /// + public string Name => "Test Lumina"; + + /// + public SelfTestStepResult RunStep(Dalamud dalamud) + { + this.rows ??= dalamud.Data.GetExcelSheet().ToList(); + + Util.ShowObject(this.rows[this.step]); + + this.step++; + return this.step >= this.rows.Count ? SelfTestStepResult.Pass : SelfTestStepResult.Waiting; + } + + /// + public void CleanUp(Dalamud dalamud) + { + // ignored + } + } +} diff --git a/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/PartyFinderAgingStep.cs b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/PartyFinderAgingStep.cs new file mode 100644 index 000000000..c2172b9dc --- /dev/null +++ b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/PartyFinderAgingStep.cs @@ -0,0 +1,53 @@ +using Dalamud.Game.Gui.PartyFinder.Types; +using ImGuiNET; + +namespace Dalamud.Interface.Internal.Windows.SelfTest.AgingSteps +{ + /// + /// Test setup for Party Finder events. + /// + internal class PartyFinderAgingStep : IAgingStep + { + private bool subscribed = false; + private bool hasPassed = false; + + /// + public string Name => "Test Party Finder"; + + /// + public SelfTestStepResult RunStep(Dalamud dalamud) + { + if (!this.subscribed) + { + dalamud.Framework.Gui.PartyFinder.ReceiveListing += this.PartyFinderOnReceiveListing; + this.subscribed = true; + } + + if (this.hasPassed) + { + dalamud.Framework.Gui.PartyFinder.ReceiveListing -= this.PartyFinderOnReceiveListing; + this.subscribed = false; + return SelfTestStepResult.Pass; + } + + ImGui.Text("Open Party Finder"); + + return SelfTestStepResult.Waiting; + } + + /// + public void CleanUp(Dalamud dalamud) + { + if (this.subscribed) + { + dalamud.Framework.Gui.PartyFinder.ReceiveListing -= this.PartyFinderOnReceiveListing; + this.subscribed = false; + } + } + + private void PartyFinderOnReceiveListing(PartyFinderListing listing, PartyFinderListingEventArgs args) + { + this.hasPassed = true; + } + } +} diff --git a/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/TargetAgingStep.cs b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/TargetAgingStep.cs new file mode 100644 index 000000000..c2dde87a2 --- /dev/null +++ b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/TargetAgingStep.cs @@ -0,0 +1,73 @@ +using Dalamud.Game.ClientState.Actors.Types; +using Dalamud.Game.ClientState.Actors.Types.NonPlayer; +using ImGuiNET; + +namespace Dalamud.Interface.Internal.Windows.SelfTest.AgingSteps +{ + /// + /// Test setup for targets. + /// + internal class TargetAgingStep : IAgingStep + { + private int step = 0; + + /// + public string Name => "Test Target"; + + /// + public SelfTestStepResult RunStep(Dalamud dalamud) + { + switch (this.step) + { + case 0: + dalamud.ClientState.Targets.ClearCurrentTarget(); + dalamud.ClientState.Targets.ClearFocusTarget(); + + this.step++; + + break; + + case 1: + ImGui.Text("Target a player..."); + + var cTarget = dalamud.ClientState.Targets.CurrentTarget; + if (cTarget is PlayerCharacter) + { + this.step++; + } + + break; + + case 2: + ImGui.Text("Focus-Target a Battle NPC..."); + + var fTarget = dalamud.ClientState.Targets.FocusTarget; + if (fTarget is BattleNpc) + { + this.step++; + } + + break; + + case 3: + ImGui.Text("Soft-Target an EventObj..."); + + var sTarget = dalamud.ClientState.Targets.FocusTarget; + if (sTarget is EventObj) + { + return SelfTestStepResult.Pass; + } + + break; + } + + return SelfTestStepResult.Waiting; + } + + /// + public void CleanUp(Dalamud dalamud) + { + // ignored + } + } +} diff --git a/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/ToastAgingStep.cs b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/ToastAgingStep.cs new file mode 100644 index 000000000..548fe698a --- /dev/null +++ b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/ToastAgingStep.cs @@ -0,0 +1,26 @@ +namespace Dalamud.Interface.Internal.Windows.SelfTest.AgingSteps +{ + /// + /// Test setup for toasts. + /// + internal class ToastAgingStep : IAgingStep + { + /// + public string Name => "Test Toasts"; + + /// + public SelfTestStepResult RunStep(Dalamud dalamud) + { + dalamud.Framework.Gui.Toast.ShowNormal("Normal Toast"); + dalamud.Framework.Gui.Toast.ShowError("Error Toast"); + + return SelfTestStepResult.Pass; + } + + /// + public void CleanUp(Dalamud dalamud) + { + // ignored + } + } +} diff --git a/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/WaitFramesAgingStep.cs b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/WaitFramesAgingStep.cs new file mode 100644 index 000000000..bac881324 --- /dev/null +++ b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/WaitFramesAgingStep.cs @@ -0,0 +1,38 @@ +namespace Dalamud.Interface.Internal.Windows.SelfTest.AgingSteps +{ + /// + /// Test that waits N frames. + /// + internal class WaitFramesAgingStep : IAgingStep + { + private readonly int frames; + private int cFrames; + + /// + /// Initializes a new instance of the class. + /// + /// Amount of frames to wait. + public WaitFramesAgingStep(int frames) + { + this.frames = frames; + this.cFrames = frames; + } + + /// + public string Name => $"Wait {this.cFrames} frames"; + + /// + public SelfTestStepResult RunStep(Dalamud dalamud) + { + this.cFrames--; + + return this.cFrames <= 0 ? SelfTestStepResult.Pass : SelfTestStepResult.Waiting; + } + + /// + public void CleanUp(Dalamud dalamud) + { + this.cFrames = this.frames; + } + } +} diff --git a/Dalamud/Interface/Internal/Windows/SelfTest/SelfTestStepResult.cs b/Dalamud/Interface/Internal/Windows/SelfTest/SelfTestStepResult.cs new file mode 100644 index 000000000..70dddcab9 --- /dev/null +++ b/Dalamud/Interface/Internal/Windows/SelfTest/SelfTestStepResult.cs @@ -0,0 +1,28 @@ +namespace Dalamud.Interface.Internal.Windows.SelfTest +{ + /// + /// Enum declaring result states of tests. + /// + internal enum SelfTestStepResult + { + /// + /// Test was not ran. + /// + NotRan, + + /// + /// Test is waiting for completion. + /// + Waiting, + + /// + /// Test has failed. + /// + Fail, + + /// + /// Test has passed. + /// + Pass, + } +} diff --git a/Dalamud/Interface/Internal/Windows/SelfTest/SelfTestWindow.cs b/Dalamud/Interface/Internal/Windows/SelfTest/SelfTestWindow.cs new file mode 100644 index 000000000..cd22e6344 --- /dev/null +++ b/Dalamud/Interface/Internal/Windows/SelfTest/SelfTestWindow.cs @@ -0,0 +1,258 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Numerics; + +using Dalamud.Interface.Colors; +using Dalamud.Interface.Components; +using Dalamud.Interface.Internal.Windows.SelfTest.AgingSteps; +using Dalamud.Interface.Windowing; +using Dalamud.Logging.Internal; +using ImGuiNET; +using Lumina.Excel.GeneratedSheets; + +namespace Dalamud.Interface.Internal.Windows.SelfTest +{ + /// + /// Window for the Self-Test logic. + /// + internal class SelfTestWindow : Window + { + private static readonly ModuleLog Log = new("AGING"); + + private readonly Dalamud dalamud; + + private readonly List steps = + new() + { + new LoginEventAgingStep(), + new WaitFramesAgingStep(1000), + new EnterTerritoryAgingStep(148, "Central Shroud"), + new ActorTableAgingStep(), + new FateTableAgingStep(), + new ConditionAgingStep(), + new ToastAgingStep(), + new TargetAgingStep(), + new KeyStateAgingStep(), + new GamepadStateAgingStep(), + new ChatAgingStep(), + new HoverAgingStep(), + new LuminaAgingStep(), + new PartyFinderAgingStep(), + }; + + private readonly List<(SelfTestStepResult Result, TimeSpan? Duration)> stepResults = new(); + + private bool selfTestRunning = false; + private int currentStep = 0; + + private DateTimeOffset lastTestStart; + + /// + /// Initializes a new instance of the class. + /// + /// The dalamud instance to act on. + public SelfTestWindow(Dalamud dalamud) + : base("Dalamud Self-Test", ImGuiWindowFlags.NoScrollbar | ImGuiWindowFlags.NoScrollWithMouse) + { + this.dalamud = dalamud; + + this.Size = new Vector2(800, 800); + this.SizeCondition = ImGuiCond.FirstUseEver; + } + + /// + public override void Draw() + { + if (this.selfTestRunning) + { + if (ImGuiComponents.IconButton(FontAwesomeIcon.Stop)) + { + this.StopTests(); + } + + ImGui.SameLine(); + + if (ImGuiComponents.IconButton(FontAwesomeIcon.StepForward)) + { + this.stepResults.Add((SelfTestStepResult.NotRan, null)); + this.currentStep++; + this.lastTestStart = DateTimeOffset.Now; + + if (this.currentStep >= this.steps.Count) + { + this.StopTests(); + } + } + } + else + { + if (ImGuiComponents.IconButton(FontAwesomeIcon.Play)) + { + this.selfTestRunning = true; + this.currentStep = 0; + this.stepResults.Clear(); + this.lastTestStart = DateTimeOffset.Now; + } + } + + ImGui.SameLine(); + + ImGui.TextUnformatted($"Step: {this.currentStep} / {this.steps.Count}"); + + ImGuiHelpers.ScaledDummy(10); + + this.DrawResultTable(); + + ImGuiHelpers.ScaledDummy(10); + + if (this.currentStep >= this.steps.Count) + { + if (this.selfTestRunning) + { + this.StopTests(); + } + + if (this.stepResults.Any(x => x.Result == SelfTestStepResult.Fail)) + { + ImGui.TextColored(ImGuiColors.DalamudRed, "One or more checks failed!"); + } + else + { + ImGui.TextColored(ImGuiColors.HealerGreen, "All checks passed!"); + } + + return; + } + + if (!this.selfTestRunning) + { + return; + } + + ImGui.Separator(); + + var step = this.steps[this.currentStep]; + ImGui.TextUnformatted($"Current: {step.Name}"); + + ImGuiHelpers.ScaledDummy(10); + + SelfTestStepResult result; + try + { + result = step.RunStep(this.dalamud); + } + catch (Exception ex) + { + Log.Error(ex, $"Step failed: {step.Name}"); + result = SelfTestStepResult.Fail; + } + + ImGui.Separator(); + + if (result != SelfTestStepResult.Waiting) + { + var duration = DateTimeOffset.Now - this.lastTestStart; + this.currentStep++; + this.stepResults.Add((result, duration)); + + this.lastTestStart = DateTimeOffset.Now; + } + } + + private void DrawResultTable() + { + if (ImGui.BeginTable("agingResultTable", 4, ImGuiTableFlags.Borders)) + { + ImGui.TableSetupColumn("###index", ImGuiTableColumnFlags.WidthFixed, 12f); + ImGui.TableSetupColumn("Name"); + ImGui.TableSetupColumn("Result", ImGuiTableColumnFlags.WidthFixed, 40f); + ImGui.TableSetupColumn("Duration", ImGuiTableColumnFlags.WidthFixed, 90f); + + ImGui.TableHeadersRow(); + + for (var i = 0; i < this.steps.Count; i++) + { + var step = this.steps[i]; + ImGui.TableNextRow(); + + ImGui.TableSetColumnIndex(0); + ImGui.Text(i.ToString()); + + ImGui.TableSetColumnIndex(1); + ImGui.Text(step.Name); + + ImGui.TableSetColumnIndex(2); + ImGui.PushFont(Interface.Internal.InterfaceManager.MonoFont); + if (this.stepResults.Count > i) + { + var result = this.stepResults[i]; + + switch (result.Result) + { + case SelfTestStepResult.Pass: + ImGui.TextColored(ImGuiColors.HealerGreen, "PASS"); + break; + case SelfTestStepResult.Fail: + ImGui.TextColored(ImGuiColors.DalamudRed, "FAIL"); + break; + default: + ImGui.TextColored(ImGuiColors.DalamudGrey, "NR"); + break; + } + } + else + { + if (this.selfTestRunning && this.currentStep == i) + { + ImGui.TextColored(ImGuiColors.DalamudGrey, "WAIT"); + } + else + { + ImGui.TextColored(ImGuiColors.DalamudGrey, "NR"); + } + } + + ImGui.PopFont(); + + ImGui.TableSetColumnIndex(3); + if (this.stepResults.Count > i) + { + var (_, duration) = this.stepResults[i]; + + if (duration.HasValue) + { + ImGui.TextUnformatted(duration.Value.ToString("g")); + } + } + else + { + if (this.selfTestRunning && this.currentStep == i) + { + ImGui.TextUnformatted((DateTimeOffset.Now - this.lastTestStart).ToString("g")); + } + } + } + + ImGui.EndTable(); + } + } + + private void StopTests() + { + this.selfTestRunning = false; + + foreach (var agingStep in this.steps) + { + try + { + agingStep.CleanUp(this.dalamud); + } + catch (Exception ex) + { + Log.Error(ex, $"Could not clean up AgingStep: {agingStep.Name}"); + } + } + } + } +}