Added ProfilerWindow

This commit is contained in:
2026-01-24 20:00:19 +00:00
8 changed files with 125 additions and 22 deletions

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 9a1f5463ef6a4249af45548d72f211c6
timeCreated: 1769189971

View File

@@ -1,11 +0,0 @@
using UnityEngine;
using System;
namespace PashaBibko.Pacore.Editor.Drawers
{
public sealed class DisabledGUIBlock : IDisposable
{
public DisabledGUIBlock() => GUI.enabled = false;
public void Dispose() => GUI.enabled = true;
}
}

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 3d8664e5ad044a248710d9b31044d2fc
timeCreated: 1769189984

View File

@@ -11,11 +11,12 @@ namespace PashaBibko.Pacore.Editor.Drawers
{
if (attribute is InspectorReadOnlyAttribute readOnlyAttribute)
{
using (new DisabledGUIBlock())
{
label.text = readOnlyAttribute.Name ?? label.text; // Uses custom name if it exists
EditorGUI.PropertyField(position, property, label);
}
GUI.enabled = false;
label.text = readOnlyAttribute.Name ?? label.text; // Uses custom name if it exists
EditorGUI.PropertyField(position, property, label);
GUI.enabled = true;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: d9b025c89af342a3b3cfc696a32fdb2e
timeCreated: 1769285442

View File

@@ -0,0 +1,97 @@
using System.Collections.Generic;
using PashaBibko.Pacore.DevTools;
using System.Linq;
using UnityEditor;
using UnityEngine;
namespace Pacore.Editor.EditorWindows
{
public class ProfilerWindow : EditorWindow
{
private double LastRepaint = double.MinValue;
private Vector2 ScrollPosition;
[MenuItem("Pacore/Profiler")]
public static void OpenWindow() => GetWindow<ProfilerWindow>();
/* Makes sure the window is repainted often to show latest info */
private void OnDisable() => EditorApplication.update -= CheckForRepaint;
private void OnEnable() => EditorApplication.update += CheckForRepaint;
private void CheckForRepaint()
{
/* Triggers a repaint when it has been over 1 second since last repaint */
double now = EditorApplication.timeSinceStartup;
if (now - LastRepaint > 1f)
{
LastRepaint = now;
Repaint();
}
}
private static void DrawEmptyProfiler()
{
GUILayout.BeginVertical(style: "box");
GUILayout.Label(text: "No profiler snippets found", EditorStyles.boldLabel);
GUILayout.Label(text: "Try running the game to collect profile samples");
GUILayout.EndVertical();
}
private static void DrawProfilerSnippet(string name, List<long> times)
{
GUILayout.BeginVertical(style: "box");
GUILayout.BeginHorizontal();
GUILayout.Label(text: name, EditorStyles.boldLabel);
GUILayout.EndHorizontal();
float averageMs = times.Sum() / (float)times.Count;
GUILayout.Label("Average time: " + averageMs);
IGrouping<long, long>[] ordered = times // List<long>
.GroupBy(time => time) // IEnumerable<IGrouping<long, long>>
.OrderByDescending(time => time.Key) // IOrdererEnumerable<IGrouping<long, long>>
.ToArray();
foreach (IGrouping<long, long> group in ordered)
{
string text = group.Count() > 1
? $"- {group.Key}ms {group.Count()}x"
: $"- {group.Key}ms";
GUILayout.Label(text, EditorStyles.label);
}
GUILayout.EndVertical();
}
/* Draws the different snippets to the screen */
private void OnGUI()
{
GUILayout.Space(5); // Stops the window rendering right at the top
IReadOnlyDictionary<string, List<long>> snippets = CodeProfiler.GetProfilerSnippets();
/* If there are no snippets, draws an inspector with instructions */
if (snippets.Count == 0)
{
DrawEmptyProfiler();
return;
}
/* Draws a quick overview of all snippets found */
GUILayout.BeginVertical(style: "box");
GUILayout.Label(text: $"[{snippets.Count}] different profiler snippets found");
GUILayout.EndVertical();
/* Draws each profiler snippet */
ScrollPosition = EditorGUILayout.BeginScrollView(ScrollPosition);
foreach (KeyValuePair<string, List<long>> snippet in snippets)
{
DrawProfilerSnippet(snippet.Key, snippet.Value);
}
EditorGUILayout.EndScrollView();
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 5bd8cdd7db4d4436978e97bda9cdc0cb
timeCreated: 1769285452

View File

@@ -1,4 +1,6 @@
using System.Threading;
using PashaBibko.Pacore.Attributes;
using PashaBibko.Pacore.DevTools;
using UnityEngine;
[CreateInstanceOnStart] public class TestMonoBehaviour : MonoBehaviour
@@ -12,6 +14,20 @@ using UnityEngine;
private void OnTestChange() => LogTestValue();
private void Update()
{
using (CodeProfiler.Start("Test Snippet"))
{
SpinWait sw = new();
int count = Random.Range(1, 50);
for (int i = 0; i < count; i++)
{
sw.SpinOnce();
}
}
}
[InspectorCallable(nameof(LogSpawnableType))]
public void LogSpawnableType()
{