Profiler and LocalToWorldThreadedSystem
Added a simple profiler Testing LocalToWorldSystem with Parallel execution for root nodes
This commit is contained in:
@@ -8,7 +8,7 @@ using Nerfed.Runtime.Util;
|
||||
namespace Nerfed.Editor.Systems
|
||||
{
|
||||
// Window that draws entities.
|
||||
internal class EditorHierarchyWindow : MoonTools.ECS.DebugSystem
|
||||
internal class EditorHierarchyWindow : MoonTools.ECS.System
|
||||
{
|
||||
private const ImGuiTreeNodeFlags baseFlags = ImGuiTreeNodeFlags.OpenOnArrow | ImGuiTreeNodeFlags.OpenOnDoubleClick | ImGuiTreeNodeFlags.SpanAvailWidth;
|
||||
|
||||
|
123
Nerfed.Editor/Systems/EditorProfilerWindow.cs
Normal file
123
Nerfed.Editor/Systems/EditorProfilerWindow.cs
Normal file
@@ -0,0 +1,123 @@
|
||||
using ImGuiNET;
|
||||
using MoonTools.ECS;
|
||||
using Nerfed.Runtime;
|
||||
using System;
|
||||
|
||||
namespace Nerfed.Editor.Systems
|
||||
{
|
||||
internal class EditorProfilerWindow : MoonTools.ECS.System
|
||||
{
|
||||
const ImGuiTableFlags tableFlags = ImGuiTableFlags.Resizable | ImGuiTableFlags.BordersOuter | ImGuiTableFlags.NoBordersInBody | ImGuiTableFlags.ScrollY | ImGuiTableFlags.ScrollX;
|
||||
const ImGuiTreeNodeFlags treeNodeFlags = ImGuiTreeNodeFlags.SpanAllColumns;
|
||||
const ImGuiTreeNodeFlags treeNodeLeafFlags = ImGuiTreeNodeFlags.SpanAllColumns | ImGuiTreeNodeFlags.Leaf | ImGuiTreeNodeFlags.NoTreePushOnOpen;
|
||||
|
||||
int frame = 0;
|
||||
|
||||
public EditorProfilerWindow(World world) : base(world)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Update(TimeSpan delta)
|
||||
{
|
||||
if (Profiler.frames.Count <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ImGui.Begin("Profiler");
|
||||
|
||||
ImGui.BeginChild("Toolbar", new System.Numerics.Vector2(0, 0), ImGuiChildFlags.AutoResizeY);
|
||||
if (ImGui.RadioButton("Recording", Profiler.recording))
|
||||
{
|
||||
Profiler.recording = !Profiler.recording;
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
|
||||
if (Profiler.recording)
|
||||
{
|
||||
frame = Profiler.frames.Count - 1;
|
||||
}
|
||||
if (ImGui.SliderInt(string.Empty, ref frame, 0, Profiler.frames.Count - 1))
|
||||
{
|
||||
Profiler.recording = false;
|
||||
}
|
||||
|
||||
Profiler.FrameData frameData = Profiler.frames.ElementAt(frame);
|
||||
double ms = frameData.ElapsedMilliseconds();
|
||||
double s = 1000;
|
||||
ImGui.Text($"Frame: {frameData.frame} ({ms:0.000} ms | {(s / ms):0} fps)");
|
||||
ImGui.EndChild();
|
||||
|
||||
ImGui.BeginChild("Hierachy", new System.Numerics.Vector2(150, 0), ImGuiChildFlags.ResizeX);
|
||||
|
||||
if (ImGui.BeginTable("ProfilerData", 2, tableFlags, new System.Numerics.Vector2(0, 0)))
|
||||
{
|
||||
ImGui.TableSetupColumn("name", ImGuiTableColumnFlags.WidthStretch, 0.8f, 0);
|
||||
ImGui.TableSetupColumn("ms", ImGuiTableColumnFlags.WidthStretch, 0.2f, 1);
|
||||
ImGui.TableSetupScrollFreeze(0, 1); // Make row always visible
|
||||
ImGui.TableHeadersRow();
|
||||
|
||||
foreach (Profiler.ProfileRecord record in frameData.records)
|
||||
{
|
||||
ImGui.TableNextRow();
|
||||
ImGui.TableNextColumn();
|
||||
string indentation = new string(' ', record.depth); // Indentation based on depth
|
||||
ImGui.Text($"{indentation}{record.label}");
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.Text($"{record.ElapsedMilliseconds():0.000}");
|
||||
}
|
||||
|
||||
ImGui.EndTable();
|
||||
}
|
||||
|
||||
ImGui.EndChild();
|
||||
|
||||
ImGui.SameLine();
|
||||
|
||||
ImGui.BeginChild("Combined", new System.Numerics.Vector2(0, 0));
|
||||
|
||||
// Gather combined data.
|
||||
Dictionary<string, double> combinedRecordData = new Dictionary<string, double>(128);
|
||||
foreach (Profiler.ProfileRecord record in frameData.records)
|
||||
{
|
||||
if (combinedRecordData.TryGetValue(record.label, out double totalMs))
|
||||
{
|
||||
combinedRecordData[record.label] = totalMs + record.ElapsedMilliseconds();
|
||||
}
|
||||
else
|
||||
{
|
||||
combinedRecordData.Add(record.label, record.ElapsedMilliseconds());
|
||||
}
|
||||
}
|
||||
IOrderedEnumerable<KeyValuePair<string, double>> orderedCombinedData = combinedRecordData.OrderByDescending(x => x.Value);
|
||||
|
||||
if (ImGui.BeginTable("ProfilerCombinedData", 2, tableFlags, new System.Numerics.Vector2(0, 0)))
|
||||
{
|
||||
ImGui.TableSetupColumn("name", ImGuiTableColumnFlags.WidthStretch, 0.8f, 0);
|
||||
ImGui.TableSetupColumn("ms", ImGuiTableColumnFlags.WidthStretch, 0.2f, 1);
|
||||
ImGui.TableSetupScrollFreeze(0, 1); // Make row always visible
|
||||
ImGui.TableHeadersRow();
|
||||
|
||||
foreach (KeyValuePair<string, double> combinedData in orderedCombinedData)
|
||||
{
|
||||
ImGui.TableNextRow();
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.Text($"{combinedData.Key}");
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.Text($"{combinedData.Value:0.000}");
|
||||
}
|
||||
|
||||
ImGui.EndTable();
|
||||
}
|
||||
|
||||
ImGui.EndChild();
|
||||
ImGui.End();
|
||||
}
|
||||
|
||||
private void Draw()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user