diff --git a/Dalamud/Interface/Internal/Windows/PluginStatWindow.cs b/Dalamud/Interface/Internal/Windows/PluginStatWindow.cs index eeafa98e7..397262ed0 100644 --- a/Dalamud/Interface/Internal/Windows/PluginStatWindow.cs +++ b/Dalamud/Interface/Internal/Windows/PluginStatWindow.cs @@ -8,6 +8,7 @@ using Dalamud.Hooking.Internal; using Dalamud.Interface.Components; using Dalamud.Interface.ImGuiNotification; using Dalamud.Interface.ImGuiNotification.Internal; +using Dalamud.Interface.Utility.Raii; using Dalamud.Interface.Windowing; using Dalamud.Plugin.Internal; using Dalamud.Plugin.Internal.Types; @@ -44,51 +45,54 @@ internal class PluginStatWindow : Window { var pluginManager = Service.Get(); - if (!ImGui.BeginTabBar("Stat Tabs")) + using var tabBar = ImRaii.TabBar("Stat Tabs"); + if (!tabBar) return; - if (ImGui.BeginTabItem("Draw times")) + using (var tabItem = ImRaii.TabItem("Draw times")) { - var doStats = UiBuilder.DoStats; - - if (ImGui.Checkbox("Enable Draw Time Tracking", ref doStats)) + if (tabItem) { - UiBuilder.DoStats = doStats; - } + var doStats = UiBuilder.DoStats; - if (doStats) - { - ImGui.SameLine(); - if (ImGui.Button("Reset")) + if (ImGui.Checkbox("Enable Draw Time Tracking", ref doStats)) { - foreach (var plugin in pluginManager.InstalledPlugins) - { - if (plugin.DalamudInterface != null) - { - plugin.DalamudInterface.LocalUiBuilder.LastDrawTime = -1; - plugin.DalamudInterface.LocalUiBuilder.MaxDrawTime = -1; - plugin.DalamudInterface.LocalUiBuilder.DrawTimeHistory.Clear(); - } - } + UiBuilder.DoStats = doStats; } - var loadedPlugins = pluginManager.InstalledPlugins.Where(plugin => plugin.State == PluginState.Loaded); - var totalLast = loadedPlugins.Sum(plugin => plugin.DalamudInterface?.LocalUiBuilder.LastDrawTime ?? 0); - var totalAverage = loadedPlugins.Sum(plugin => plugin.DalamudInterface?.LocalUiBuilder.DrawTimeHistory.DefaultIfEmpty().Average() ?? 0); + if (doStats) + { + ImGui.SameLine(); + if (ImGui.Button("Reset")) + { + foreach (var plugin in pluginManager.InstalledPlugins) + { + if (plugin.DalamudInterface != null) + { + plugin.DalamudInterface.LocalUiBuilder.LastDrawTime = -1; + plugin.DalamudInterface.LocalUiBuilder.MaxDrawTime = -1; + plugin.DalamudInterface.LocalUiBuilder.DrawTimeHistory.Clear(); + } + } + } - ImGuiComponents.TextWithLabel("Total Last", $"{totalLast / 10000f:F4}ms", "All last draw times added together"); - ImGui.SameLine(); - ImGuiComponents.TextWithLabel("Total Average", $"{totalAverage / 10000f:F4}ms", "All average draw times added together"); - ImGui.SameLine(); - ImGuiComponents.TextWithLabel("Collective Average", $"{(loadedPlugins.Any() ? totalAverage / loadedPlugins.Count() / 10000f : 0):F4}ms", "Average of all average draw times"); + var loadedPlugins = pluginManager.InstalledPlugins.Where(plugin => plugin.State == PluginState.Loaded); + var totalLast = loadedPlugins.Sum(plugin => plugin.DalamudInterface?.LocalUiBuilder.LastDrawTime ?? 0); + var totalAverage = loadedPlugins.Sum(plugin => plugin.DalamudInterface?.LocalUiBuilder.DrawTimeHistory.DefaultIfEmpty().Average() ?? 0); - ImGui.InputTextWithHint( - "###PluginStatWindow_DrawSearch", - "Search", - ref this.drawSearchText, - 500); + ImGuiComponents.TextWithLabel("Total Last", $"{totalLast / 10000f:F4}ms", "All last draw times added together"); + ImGui.SameLine(); + ImGuiComponents.TextWithLabel("Total Average", $"{totalAverage / 10000f:F4}ms", "All average draw times added together"); + ImGui.SameLine(); + ImGuiComponents.TextWithLabel("Collective Average", $"{(loadedPlugins.Any() ? totalAverage / loadedPlugins.Count() / 10000f : 0):F4}ms", "Average of all average draw times"); - if (ImGui.BeginTable( + ImGui.InputTextWithHint( + "###PluginStatWindow_DrawSearch", + "Search", + ref this.drawSearchText, + 500); + + using var table = ImRaii.Table( "##PluginStatsDrawTimes", 4, ImGuiTableFlags.RowBg @@ -97,99 +101,100 @@ internal class PluginStatWindow : Window | ImGuiTableFlags.Resizable | ImGuiTableFlags.ScrollY | ImGuiTableFlags.Reorderable - | ImGuiTableFlags.Hideable)) - { - ImGui.TableSetupScrollFreeze(0, 1); - ImGui.TableSetupColumn("Plugin"); - ImGui.TableSetupColumn("Last", ImGuiTableColumnFlags.NoSort); // Changes too fast to sort - ImGui.TableSetupColumn("Longest"); - ImGui.TableSetupColumn("Average"); - ImGui.TableHeadersRow(); + | ImGuiTableFlags.Hideable); - var sortSpecs = ImGui.TableGetSortSpecs(); - loadedPlugins = sortSpecs.Specs.ColumnIndex switch + if (table) { - 0 => sortSpecs.Specs.SortDirection == ImGuiSortDirection.Ascending - ? loadedPlugins.OrderBy(plugin => plugin.Name) - : loadedPlugins.OrderByDescending(plugin => plugin.Name), - 2 => sortSpecs.Specs.SortDirection == ImGuiSortDirection.Ascending - ? loadedPlugins.OrderBy(plugin => plugin.DalamudInterface?.LocalUiBuilder.MaxDrawTime ?? 0) - : loadedPlugins.OrderByDescending(plugin => plugin.DalamudInterface?.LocalUiBuilder.MaxDrawTime ?? 0), - 3 => sortSpecs.Specs.SortDirection == ImGuiSortDirection.Ascending - ? loadedPlugins.OrderBy(plugin => plugin.DalamudInterface?.LocalUiBuilder.DrawTimeHistory.DefaultIfEmpty().Average() ?? 0) - : loadedPlugins.OrderByDescending(plugin => plugin.DalamudInterface?.LocalUiBuilder.DrawTimeHistory.DefaultIfEmpty().Average() ?? 0), - _ => loadedPlugins, - }; + ImGui.TableSetupScrollFreeze(0, 1); + ImGui.TableSetupColumn("Plugin"); + ImGui.TableSetupColumn("Last", ImGuiTableColumnFlags.NoSort); // Changes too fast to sort + ImGui.TableSetupColumn("Longest"); + ImGui.TableSetupColumn("Average"); + ImGui.TableHeadersRow(); - foreach (var plugin in loadedPlugins) - { - if (!this.drawSearchText.IsNullOrEmpty() - && !plugin.Manifest.Name.Contains(this.drawSearchText, StringComparison.OrdinalIgnoreCase)) + var sortSpecs = ImGui.TableGetSortSpecs(); + loadedPlugins = sortSpecs.Specs.ColumnIndex switch { - continue; - } + 0 => sortSpecs.Specs.SortDirection == ImGuiSortDirection.Ascending + ? loadedPlugins.OrderBy(plugin => plugin.Name) + : loadedPlugins.OrderByDescending(plugin => plugin.Name), + 2 => sortSpecs.Specs.SortDirection == ImGuiSortDirection.Ascending + ? loadedPlugins.OrderBy(plugin => plugin.DalamudInterface?.LocalUiBuilder.MaxDrawTime ?? 0) + : loadedPlugins.OrderByDescending(plugin => plugin.DalamudInterface?.LocalUiBuilder.MaxDrawTime ?? 0), + 3 => sortSpecs.Specs.SortDirection == ImGuiSortDirection.Ascending + ? loadedPlugins.OrderBy(plugin => plugin.DalamudInterface?.LocalUiBuilder.DrawTimeHistory.DefaultIfEmpty().Average() ?? 0) + : loadedPlugins.OrderByDescending(plugin => plugin.DalamudInterface?.LocalUiBuilder.DrawTimeHistory.DefaultIfEmpty().Average() ?? 0), + _ => loadedPlugins, + }; - ImGui.TableNextRow(); - - ImGui.TableNextColumn(); - ImGui.Text(plugin.Manifest.Name); - - if (plugin.DalamudInterface != null) + foreach (var plugin in loadedPlugins) { - ImGui.TableNextColumn(); - ImGui.Text($"{plugin.DalamudInterface.LocalUiBuilder.LastDrawTime / 10000f:F4}ms"); + if (!this.drawSearchText.IsNullOrEmpty() + && !plugin.Manifest.Name.Contains(this.drawSearchText, StringComparison.OrdinalIgnoreCase)) + { + continue; + } + + ImGui.TableNextRow(); ImGui.TableNextColumn(); - ImGui.Text($"{plugin.DalamudInterface.LocalUiBuilder.MaxDrawTime / 10000f:F4}ms"); + ImGui.Text(plugin.Manifest.Name); - ImGui.TableNextColumn(); - ImGui.Text(plugin.DalamudInterface.LocalUiBuilder.DrawTimeHistory.Count > 0 - ? $"{plugin.DalamudInterface.LocalUiBuilder.DrawTimeHistory.Average() / 10000f:F4}ms" - : "-"); + if (plugin.DalamudInterface != null) + { + ImGui.TableNextColumn(); + ImGui.Text($"{plugin.DalamudInterface.LocalUiBuilder.LastDrawTime / 10000f:F4}ms"); + + ImGui.TableNextColumn(); + ImGui.Text($"{plugin.DalamudInterface.LocalUiBuilder.MaxDrawTime / 10000f:F4}ms"); + + ImGui.TableNextColumn(); + ImGui.Text(plugin.DalamudInterface.LocalUiBuilder.DrawTimeHistory.Count > 0 + ? $"{plugin.DalamudInterface.LocalUiBuilder.DrawTimeHistory.Average() / 10000f:F4}ms" + : "-"); + } } } - - ImGui.EndTable(); } } - - ImGui.EndTabItem(); } - if (ImGui.BeginTabItem("Framework times")) + using (var tabItem = ImRaii.TabItem("Framework times")) { - var doStats = Framework.StatsEnabled; - - if (ImGui.Checkbox("Enable Framework Update Tracking", ref doStats)) + if (tabItem) { - Framework.StatsEnabled = doStats; - } + var doStats = Framework.StatsEnabled; - if (doStats) - { - ImGui.SameLine(); - if (ImGui.Button("Reset")) + if (ImGui.Checkbox("Enable Framework Update Tracking", ref doStats)) { - Framework.StatsHistory.Clear(); + Framework.StatsEnabled = doStats; } - var statsHistory = Framework.StatsHistory.ToArray(); - var totalLast = statsHistory.Sum(stats => stats.Value.LastOrDefault()); - var totalAverage = statsHistory.Sum(stats => stats.Value.DefaultIfEmpty().Average()); + if (doStats) + { + ImGui.SameLine(); + if (ImGui.Button("Reset")) + { + Framework.StatsHistory.Clear(); + } - ImGuiComponents.TextWithLabel("Total Last", $"{totalLast:F4}ms", "All last update times added together"); - ImGui.SameLine(); - ImGuiComponents.TextWithLabel("Total Average", $"{totalAverage:F4}ms", "All average update times added together"); - ImGui.SameLine(); - ImGuiComponents.TextWithLabel("Collective Average", $"{(statsHistory.Any() ? totalAverage / statsHistory.Length : 0):F4}ms", "Average of all average update times"); + var statsHistory = Framework.StatsHistory.ToArray(); + var totalLast = statsHistory.Sum(stats => stats.Value.LastOrDefault()); + var totalAverage = statsHistory.Sum(stats => stats.Value.DefaultIfEmpty().Average()); - ImGui.InputTextWithHint( - "###PluginStatWindow_FrameworkSearch", - "Search", - ref this.frameworkSearchText, - 500); + ImGuiComponents.TextWithLabel("Total Last", $"{totalLast:F4}ms", "All last update times added together"); + ImGui.SameLine(); + ImGuiComponents.TextWithLabel("Total Average", $"{totalAverage:F4}ms", "All average update times added together"); + ImGui.SameLine(); + ImGuiComponents.TextWithLabel("Collective Average", $"{(statsHistory.Any() ? totalAverage / statsHistory.Length : 0):F4}ms", "Average of all average update times"); - if (ImGui.BeginTable( + ImGui.InputTextWithHint( + "###PluginStatWindow_FrameworkSearch", + "Search", + ref this.frameworkSearchText, + 500); + + using var table = ImRaii.Table( "##PluginStatsFrameworkTimes", 4, ImGuiTableFlags.RowBg @@ -198,77 +203,77 @@ internal class PluginStatWindow : Window | ImGuiTableFlags.Resizable | ImGuiTableFlags.ScrollY | ImGuiTableFlags.Reorderable - | ImGuiTableFlags.Hideable)) - { - ImGui.TableSetupScrollFreeze(0, 1); - ImGui.TableSetupColumn("Method", ImGuiTableColumnFlags.None, 250); - ImGui.TableSetupColumn("Last", ImGuiTableColumnFlags.NoSort, 50); // Changes too fast to sort - ImGui.TableSetupColumn("Longest", ImGuiTableColumnFlags.None, 50); - ImGui.TableSetupColumn("Average", ImGuiTableColumnFlags.None, 50); - ImGui.TableHeadersRow(); - - var sortSpecs = ImGui.TableGetSortSpecs(); - statsHistory = sortSpecs.Specs.ColumnIndex switch + | ImGuiTableFlags.Hideable); + if (table) { - 0 => sortSpecs.Specs.SortDirection == ImGuiSortDirection.Ascending - ? statsHistory.OrderBy(handler => handler.Key).ToArray() - : statsHistory.OrderByDescending(handler => handler.Key).ToArray(), - 2 => sortSpecs.Specs.SortDirection == ImGuiSortDirection.Ascending - ? statsHistory.OrderBy(handler => handler.Value.DefaultIfEmpty().Max()).ToArray() - : statsHistory.OrderByDescending(handler => handler.Value.DefaultIfEmpty().Max()).ToArray(), - 3 => sortSpecs.Specs.SortDirection == ImGuiSortDirection.Ascending - ? statsHistory.OrderBy(handler => handler.Value.DefaultIfEmpty().Average()).ToArray() - : statsHistory.OrderByDescending(handler => handler.Value.DefaultIfEmpty().Average()).ToArray(), - _ => statsHistory, - }; + ImGui.TableSetupScrollFreeze(0, 1); + ImGui.TableSetupColumn("Method", ImGuiTableColumnFlags.None, 250); + ImGui.TableSetupColumn("Last", ImGuiTableColumnFlags.NoSort, 50); // Changes too fast to sort + ImGui.TableSetupColumn("Longest", ImGuiTableColumnFlags.None, 50); + ImGui.TableSetupColumn("Average", ImGuiTableColumnFlags.None, 50); + ImGui.TableHeadersRow(); - foreach (var handlerHistory in statsHistory) - { - if (!handlerHistory.Value.Any()) + var sortSpecs = ImGui.TableGetSortSpecs(); + statsHistory = sortSpecs.Specs.ColumnIndex switch { - continue; - } + 0 => sortSpecs.Specs.SortDirection == ImGuiSortDirection.Ascending + ? statsHistory.OrderBy(handler => handler.Key).ToArray() + : statsHistory.OrderByDescending(handler => handler.Key).ToArray(), + 2 => sortSpecs.Specs.SortDirection == ImGuiSortDirection.Ascending + ? statsHistory.OrderBy(handler => handler.Value.DefaultIfEmpty().Max()).ToArray() + : statsHistory.OrderByDescending(handler => handler.Value.DefaultIfEmpty().Max()).ToArray(), + 3 => sortSpecs.Specs.SortDirection == ImGuiSortDirection.Ascending + ? statsHistory.OrderBy(handler => handler.Value.DefaultIfEmpty().Average()).ToArray() + : statsHistory.OrderByDescending(handler => handler.Value.DefaultIfEmpty().Average()).ToArray(), + _ => statsHistory, + }; - if (!this.frameworkSearchText.IsNullOrEmpty() - && handlerHistory.Key != null - && !handlerHistory.Key.Contains(this.frameworkSearchText, StringComparison.OrdinalIgnoreCase)) + foreach (var handlerHistory in statsHistory) { - continue; + if (!handlerHistory.Value.Any()) + { + continue; + } + + if (!this.frameworkSearchText.IsNullOrEmpty() + && handlerHistory.Key != null + && !handlerHistory.Key.Contains(this.frameworkSearchText, StringComparison.OrdinalIgnoreCase)) + { + continue; + } + + ImGui.TableNextRow(); + + ImGui.TableNextColumn(); + ImGui.Text($"{handlerHistory.Key}"); + + ImGui.TableNextColumn(); + ImGui.Text($"{handlerHistory.Value.Last():F4}ms"); + + ImGui.TableNextColumn(); + ImGui.Text($"{handlerHistory.Value.Max():F4}ms"); + + ImGui.TableNextColumn(); + ImGui.Text($"{handlerHistory.Value.Average():F4}ms"); } - - ImGui.TableNextRow(); - - ImGui.TableNextColumn(); - ImGui.Text($"{handlerHistory.Key}"); - - ImGui.TableNextColumn(); - ImGui.Text($"{handlerHistory.Value.Last():F4}ms"); - - ImGui.TableNextColumn(); - ImGui.Text($"{handlerHistory.Value.Max():F4}ms"); - - ImGui.TableNextColumn(); - ImGui.Text($"{handlerHistory.Value.Average():F4}ms"); } - - ImGui.EndTable(); } } - - ImGui.EndTabItem(); } - if (ImGui.BeginTabItem("Hooks")) + using (var tabItem = ImRaii.TabItem("Hooks")) { - ImGui.Checkbox("Show Dalamud Hooks", ref this.showDalamudHooks); + if (tabItem) + { + ImGui.Checkbox("Show Dalamud Hooks", ref this.showDalamudHooks); - ImGui.InputTextWithHint( - "###PluginStatWindow_HookSearch", - "Search", - ref this.hookSearchText, - 500); + ImGui.InputTextWithHint( + "###PluginStatWindow_HookSearch", + "Search", + ref this.hookSearchText, + 500); - if (ImGui.BeginTable( + using var table = ImRaii.Table( "##PluginStatsHooks", 4, ImGuiTableFlags.RowBg @@ -276,80 +281,78 @@ internal class PluginStatWindow : Window | ImGuiTableFlags.Resizable | ImGuiTableFlags.ScrollY | ImGuiTableFlags.Reorderable - | ImGuiTableFlags.Hideable)) - { - ImGui.TableSetupScrollFreeze(0, 1); - ImGui.TableSetupColumn("Detour Method", ImGuiTableColumnFlags.None, 250); - ImGui.TableSetupColumn("Address", ImGuiTableColumnFlags.None, 100); - ImGui.TableSetupColumn("Status", ImGuiTableColumnFlags.None, 40); - ImGui.TableSetupColumn("Backend", ImGuiTableColumnFlags.None, 40); - ImGui.TableHeadersRow(); - - foreach (var (guid, trackedHook) in HookManager.TrackedHooks) + | ImGuiTableFlags.Hideable); + if (table) { - try + ImGui.TableSetupScrollFreeze(0, 1); + ImGui.TableSetupColumn("Detour Method", ImGuiTableColumnFlags.None, 250); + ImGui.TableSetupColumn("Address", ImGuiTableColumnFlags.None, 100); + ImGui.TableSetupColumn("Status", ImGuiTableColumnFlags.None, 40); + ImGui.TableSetupColumn("Backend", ImGuiTableColumnFlags.None, 40); + ImGui.TableHeadersRow(); + + foreach (var (guid, trackedHook) in HookManager.TrackedHooks) { - if (!this.showDalamudHooks && trackedHook.Assembly == Assembly.GetExecutingAssembly()) - continue; - - if (!this.hookSearchText.IsNullOrEmpty()) + try { - if ((trackedHook.Delegate.Target == null || !trackedHook.Delegate.Target.ToString().Contains(this.hookSearchText, StringComparison.OrdinalIgnoreCase)) - && !trackedHook.Delegate.Method.Name.Contains(this.hookSearchText, StringComparison.OrdinalIgnoreCase)) + if (!this.showDalamudHooks && trackedHook.Assembly == Assembly.GetExecutingAssembly()) continue; - } - ImGui.TableNextRow(); - - ImGui.TableNextColumn(); - - ImGui.Text($"{trackedHook.Delegate.Target} :: {trackedHook.Delegate.Method.Name}"); - ImGui.TextDisabled(trackedHook.Assembly.FullName); - ImGui.TableNextColumn(); - if (!trackedHook.Hook.IsDisposed) - { - if (ImGui.Selectable($"{trackedHook.Hook.Address.ToInt64():X}")) + if (!this.hookSearchText.IsNullOrEmpty()) { - ImGui.SetClipboardText($"{trackedHook.Hook.Address.ToInt64():X}"); - Service.Get().AddNotification($"{trackedHook.Hook.Address.ToInt64():X}", "Copied to clipboard", NotificationType.Success); + if ((trackedHook.Delegate.Target == null || !trackedHook.Delegate.Target.ToString().Contains(this.hookSearchText, StringComparison.OrdinalIgnoreCase)) + && !trackedHook.Delegate.Method.Name.Contains(this.hookSearchText, StringComparison.OrdinalIgnoreCase)) + continue; } - var processMemoryOffset = trackedHook.InProcessMemory; - if (processMemoryOffset.HasValue) + ImGui.TableNextRow(); + + ImGui.TableNextColumn(); + + ImGui.Text($"{trackedHook.Delegate.Target} :: {trackedHook.Delegate.Method.Name}"); + ImGui.TextDisabled(trackedHook.Assembly.FullName); + ImGui.TableNextColumn(); + if (!trackedHook.Hook.IsDisposed) { - if (ImGui.Selectable($"ffxiv_dx11.exe+{processMemoryOffset:X}")) + if (ImGui.Selectable($"{trackedHook.Hook.Address.ToInt64():X}")) { - ImGui.SetClipboardText($"ffxiv_dx11.exe+{processMemoryOffset:X}"); - Service.Get().AddNotification($"ffxiv_dx11.exe+{processMemoryOffset:X}", "Copied to clipboard", NotificationType.Success); + ImGui.SetClipboardText($"{trackedHook.Hook.Address.ToInt64():X}"); + Service.Get().AddNotification($"{trackedHook.Hook.Address.ToInt64():X}", "Copied to clipboard", NotificationType.Success); + } + + var processMemoryOffset = trackedHook.InProcessMemory; + if (processMemoryOffset.HasValue) + { + if (ImGui.Selectable($"ffxiv_dx11.exe+{processMemoryOffset:X}")) + { + ImGui.SetClipboardText($"ffxiv_dx11.exe+{processMemoryOffset:X}"); + Service.Get().AddNotification($"ffxiv_dx11.exe+{processMemoryOffset:X}", "Copied to clipboard", NotificationType.Success); + } } } + + ImGui.TableNextColumn(); + + if (trackedHook.Hook.IsDisposed) + { + ImGui.Text("Disposed"); + } + else + { + ImGui.Text(trackedHook.Hook.IsEnabled ? "Enabled" : "Disabled"); + } + + ImGui.TableNextColumn(); + + ImGui.Text(trackedHook.Hook.BackendName); } - - ImGui.TableNextColumn(); - - if (trackedHook.Hook.IsDisposed) + catch (Exception ex) { - ImGui.Text("Disposed"); + Log.Error(ex, "Error drawing hooks in plugin stats"); } - else - { - ImGui.Text(trackedHook.Hook.IsEnabled ? "Enabled" : "Disabled"); - } - - ImGui.TableNextColumn(); - - ImGui.Text(trackedHook.Hook.BackendName); - } - catch (Exception ex) - { - Log.Error(ex, "Error drawing hooks in plugin stats"); } } - - ImGui.EndTable(); } } - - ImGui.EndTabBar(); } }