This commit is contained in:
goat 2020-06-05 14:36:36 +02:00
commit eb66ce881c
9 changed files with 170 additions and 56 deletions

View file

@ -151,6 +151,8 @@ namespace Dalamud {
IsReady = true; IsReady = true;
}); });
this.conditionDebugWindow = new ConditionDebugWindow( this );
} }
public void Start() { public void Start() {
@ -209,12 +211,15 @@ namespace Dalamud {
private bool isImguiDrawPluginWindow = false; private bool isImguiDrawPluginWindow = false;
private bool isImguiDrawCreditsWindow = false; private bool isImguiDrawCreditsWindow = false;
private bool isImguiDrawSettingsWindow = false; private bool isImguiDrawSettingsWindow = false;
private bool isImguiDrawPluginStatWindow = false;
private DalamudLogWindow logWindow; private DalamudLogWindow logWindow;
private DalamudDataWindow dataWindow; private DalamudDataWindow dataWindow;
private DalamudCreditsWindow creditsWindow; private DalamudCreditsWindow creditsWindow;
private DalamudSettingsWindow settingsWindow; private DalamudSettingsWindow settingsWindow;
private PluginInstallerWindow pluginWindow; private PluginInstallerWindow pluginWindow;
private ConditionDebugWindow conditionDebugWindow;
private DalamudPluginStatWindow pluginStatWindow;
private void BuildDalamudUi() private void BuildDalamudUi()
{ {
@ -274,6 +279,16 @@ namespace Dalamud {
ImGui.EndMenu(); ImGui.EndMenu();
} }
if( ImGui.BeginMenu( "Game" ) )
{
if( ImGui.MenuItem( "Condition Debug" ) )
{
this.conditionDebugWindow.Enabled = !this.conditionDebugWindow.Enabled;
}
ImGui.EndMenu();
}
if (ImGui.BeginMenu("Plugins")) if (ImGui.BeginMenu("Plugins"))
{ {
if (ImGui.MenuItem("Open Plugin installer")) if (ImGui.MenuItem("Open Plugin installer"))
@ -281,6 +296,12 @@ namespace Dalamud {
this.pluginWindow = new PluginInstallerWindow(this.PluginManager, this.PluginRepository, this.StartInfo.GameVersion); this.pluginWindow = new PluginInstallerWindow(this.PluginManager, this.PluginRepository, this.StartInfo.GameVersion);
this.isImguiDrawPluginWindow = true; this.isImguiDrawPluginWindow = true;
} }
if (ImGui.MenuItem("Open Plugin Stats")) {
if (!this.isImguiDrawPluginStatWindow) {
this.pluginStatWindow = new DalamudPluginStatWindow(this.PluginManager);
this.isImguiDrawPluginStatWindow = true;
}
}
if (ImGui.MenuItem("Print plugin info")) { if (ImGui.MenuItem("Print plugin info")) {
foreach (var plugin in this.PluginManager.Plugins) { foreach (var plugin in this.PluginManager.Plugins) {
// TODO: some more here, state maybe? // TODO: some more here, state maybe?
@ -378,6 +399,19 @@ namespace Dalamud {
if (this.isImguiDrawDemoWindow) if (this.isImguiDrawDemoWindow)
ImGui.ShowDemoWindow(); ImGui.ShowDemoWindow();
if( this.conditionDebugWindow.Enabled )
{
this.conditionDebugWindow.Draw();
}
if (this.isImguiDrawPluginStatWindow) {
this.isImguiDrawPluginStatWindow = this.pluginStatWindow != null && this.pluginStatWindow.Draw();
if (!this.isImguiDrawPluginStatWindow) {
this.pluginStatWindow?.Dispose();
this.pluginStatWindow = null;
}
}
} }
#endregion #endregion

View file

@ -85,34 +85,12 @@ namespace Dalamud.Game.ClientState.Actors {
} }
} }
private class ActorTableEnumerator : IEnumerator<Actor> {
private readonly ActorTable table;
private int currentIndex;
public ActorTableEnumerator(ActorTable table) {
this.table = table;
}
public bool MoveNext() {
this.currentIndex++;
return this.currentIndex != this.table.Length;
}
public void Reset() {
this.currentIndex = 0;
}
public Actor Current => this.table[this.currentIndex];
object IEnumerator.Current => Current;
// Required by IEnumerator<T> even though we have nothing we want to dispose here.
public void Dispose() {}
}
public IEnumerator<Actor> GetEnumerator() { public IEnumerator<Actor> GetEnumerator() {
return new ActorTableEnumerator(this); for (int i=0;i<Length;i++){
if (this[i] != null) {
yield return this[i];
}
}
} }
IEnumerator IEnumerable.GetEnumerator() { IEnumerator IEnumerable.GetEnumerator() {

View file

@ -65,5 +65,10 @@ namespace Dalamud.Game.ClientState.Actors.Types {
/// The Y distance from the local player in yalms. /// The Y distance from the local player in yalms.
/// </summary> /// </summary>
public byte YalmDistanceY => this.actorStruct.YalmDistanceFromPlayerY; public byte YalmDistanceY => this.actorStruct.YalmDistanceFromPlayerY;
/// <summary>
/// The target of the actor
/// </summary>
public virtual int TargetActorID => 0;
} }
} }

View file

@ -22,5 +22,11 @@ namespace Dalamud.Game.ClientState.Actors.Types.NonPlayer {
/// The ID of this BattleNpc's owner. /// The ID of this BattleNpc's owner.
/// </summary> /// </summary>
public int OwnerId => this.actorStruct.OwnerId; public int OwnerId => this.actorStruct.OwnerId;
/// <summary>
/// Target of the Battle NPC
/// </summary>
public override int TargetActorID => this.actorStruct.BattleNpcTargetActorId;
} }
} }

View file

@ -29,5 +29,11 @@ namespace Dalamud.Game.ClientState.Actors.Types {
/// The Free Company tag of this player. /// The Free Company tag of this player.
/// </summary> /// </summary>
public string CompanyTag => Encoding.UTF8.GetString(this.actorStruct.CompanyTag).Substring(2).Replace("\0", ""); public string CompanyTag => Encoding.UTF8.GetString(this.actorStruct.CompanyTag).Substring(2).Replace("\0", "");
/// <summary>
/// Target of the PlayerCharacter
/// </summary>
public override int TargetActorID => this.actorStruct.PlayerCharacterTargetActorId;
} }
} }

View file

@ -73,37 +73,14 @@ namespace Dalamud.Game.ClientState
} }
} }
private class PartyListEnumerator : IEnumerator<PartyMember> public IEnumerator<PartyMember> GetEnumerator() {
{ for (var i = 0; i < Length; i++) {
private readonly PartyList party; if (this[i] != null) {
private int currentIndex; yield return this[i];
}
public PartyListEnumerator(PartyList list)
{
this.party = list;
} }
public bool MoveNext()
{
this.currentIndex++;
return this.currentIndex != this.party.Length;
}
public void Reset()
{
this.currentIndex = 0;
}
public PartyMember Current => this.party[this.currentIndex];
object IEnumerator.Current => Current;
// Required by IEnumerator<T> even though we have nothing we want to dispose here.
public void Dispose() {}
} }
public IEnumerator<PartyMember> GetEnumerator() => new PartyListEnumerator(this);
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
public int Length => !this.isReady ? 0 : Marshal.ReadByte(partyListBegin + 0xF0); public int Length => !this.isReady ? 0 : Marshal.ReadByte(partyListBegin + 0xF0);

View file

@ -30,7 +30,8 @@ namespace Dalamud.Game.ClientState.Structs
[FieldOffset(0x17B8)] [MarshalAs(UnmanagedType.ByValArray, SizeConst = 28)] public byte[] Customize; [FieldOffset(0x17B8)] [MarshalAs(UnmanagedType.ByValArray, SizeConst = 28)] public byte[] Customize;
[FieldOffset(0x17F8)] public int TargetActorId; [FieldOffset(0x1F0)] public int PlayerCharacterTargetActorId;
[FieldOffset(0x17F8)] public int BattleNpcTargetActorId;
// This field can't be correctly aligned, so we have to cut it manually. // This field can't be correctly aligned, so we have to cut it manually.
[FieldOffset(0x17d0)] [MarshalAs(UnmanagedType.ByValArray, SizeConst = 7)] [FieldOffset(0x17d0)] [MarshalAs(UnmanagedType.ByValArray, SizeConst = 7)]

View file

@ -0,0 +1,87 @@
using System;
using System.Linq;
using Dalamud.Plugin;
using ImGuiNET;
namespace Dalamud.Interface {
class DalamudPluginStatWindow : IDisposable {
private PluginManager pm;
public DalamudPluginStatWindow(PluginManager pm) {
this.pm = pm;
}
public bool Draw() {
bool doDraw = true;
ImGui.PushID("DalamudPluginStatWindow");
ImGui.Begin("Plugin Statistics", ref doDraw);
ImGui.BeginTabBar("Stat Tabs");
if (ImGui.BeginTabItem("Draw times")) {
bool doStats = UiBuilder.DoStats;
if (ImGui.Checkbox("Enable Draw Time Tracking", ref doStats)) {
UiBuilder.DoStats = doStats;
}
if (doStats) {
ImGui.SameLine();
if (ImGui.Button("Reset")) {
foreach (var a in this.pm.Plugins) {
a.PluginInterface.UiBuilder.lastDrawTime = -1;
a.PluginInterface.UiBuilder.maxDrawTime = -1;
a.PluginInterface.UiBuilder.drawTimeHistory.Clear();
}
}
ImGui.Columns(4);
ImGui.SetColumnWidth(0, 180f);
ImGui.SetColumnWidth(1, 100f);
ImGui.SetColumnWidth(2, 100f);
ImGui.SetColumnWidth(3, 100f);
ImGui.Text("Plugin");
ImGui.NextColumn();
ImGui.Text("Last");
ImGui.NextColumn();
ImGui.Text("Longest");
ImGui.NextColumn();
ImGui.Text("Average");
ImGui.NextColumn();
ImGui.Separator();
foreach (var a in this.pm.Plugins) {
ImGui.Text(a.Definition.Name);
ImGui.NextColumn();
ImGui.Text($"{a.PluginInterface.UiBuilder.lastDrawTime/10000f:F4}ms");
ImGui.NextColumn();
ImGui.Text($"{a.PluginInterface.UiBuilder.maxDrawTime/10000f:F4}ms");
ImGui.NextColumn();
if (a.PluginInterface.UiBuilder.drawTimeHistory.Count > 0) {
ImGui.Text($"{a.PluginInterface.UiBuilder.drawTimeHistory.Average()/10000f:F4}ms");
} else {
ImGui.Text("-");
}
ImGui.NextColumn();
}
ImGui.Columns(1);
}
}
ImGui.EndTabBar();
ImGui.End();
ImGui.PopID();
return doDraw;
}
public void Dispose() {
}
}
}

View file

@ -32,6 +32,15 @@ namespace Dalamud.Interface
public event RawDX11Scene.BuildUIDelegate OnBuildUi; public event RawDX11Scene.BuildUIDelegate OnBuildUi;
private readonly InterfaceManager interfaceManager; private readonly InterfaceManager interfaceManager;
#if DEBUG
internal static bool DoStats { get; set; } = true;
#else
internal static bool DoStats { get; set; } = false;
#endif
private System.Diagnostics.Stopwatch stopwatch;
internal long lastDrawTime = -1;
internal long maxDrawTime = -1;
internal List<long> drawTimeHistory = new List<long>();
/// <summary> /// <summary>
/// Create a new UiBuilder and register it. You do not have to call this manually. /// Create a new UiBuilder and register it. You do not have to call this manually.
@ -43,6 +52,7 @@ namespace Dalamud.Interface
this.interfaceManager = interfaceManager; this.interfaceManager = interfaceManager;
this.interfaceManager.OnDraw += OnDraw; this.interfaceManager.OnDraw += OnDraw;
this.stopwatch = new System.Diagnostics.Stopwatch();
} }
/// <summary> /// <summary>
@ -109,6 +119,9 @@ namespace Dalamud.Interface
private void OnDraw() { private void OnDraw() {
ImGui.PushID(this.namespaceName); ImGui.PushID(this.namespaceName);
if (DoStats) {
this.stopwatch.Restart();
}
if (this.hasErrorWindow && ImGui.Begin(string.Format("{0} Error", this.namespaceName), ref this.hasErrorWindow, if (this.hasErrorWindow && ImGui.Begin(string.Format("{0} Error", this.namespaceName), ref this.hasErrorWindow,
ImGuiWindowFlags.NoCollapse | ImGuiWindowFlags.NoResize)) { ImGuiWindowFlags.NoCollapse | ImGuiWindowFlags.NoResize)) {
@ -132,6 +145,13 @@ namespace Dalamud.Interface
this.hasErrorWindow = true; this.hasErrorWindow = true;
} }
if (DoStats) {
this.stopwatch.Stop();
this.lastDrawTime = this.stopwatch.ElapsedTicks;
this.maxDrawTime = Math.Max(this.lastDrawTime, this.maxDrawTime);
this.drawTimeHistory.Add(lastDrawTime);
while (drawTimeHistory.Count > 100) drawTimeHistory.RemoveAt(0);
}
ImGui.PopID(); ImGui.PopID();
} }
} }