Convert PluginStatWindow to ImRaii (#2268)

Currently the Hooks tab asserts because of a missing ImGui.EndTabItem. Instead of just adding that, I took the opportunity to convert everything to use ImRaii instead.
This commit is contained in:
foophoof 2025-05-02 05:05:42 +01:00 committed by GitHub
parent 85b77226e9
commit 09f519ce6f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

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