diff --git a/Assets/Pacore/Editor/Drawers/Blocks.meta b/Assets/Pacore/Editor/Drawers/Blocks.meta deleted file mode 100644 index a58444e..0000000 --- a/Assets/Pacore/Editor/Drawers/Blocks.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 9a1f5463ef6a4249af45548d72f211c6 -timeCreated: 1769189971 \ No newline at end of file diff --git a/Assets/Pacore/Editor/Drawers/Blocks/DisabledGUIBlock.cs b/Assets/Pacore/Editor/Drawers/Blocks/DisabledGUIBlock.cs deleted file mode 100644 index b1619d6..0000000 --- a/Assets/Pacore/Editor/Drawers/Blocks/DisabledGUIBlock.cs +++ /dev/null @@ -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; - } -} \ No newline at end of file diff --git a/Assets/Pacore/Editor/Drawers/Blocks/DisabledGUIBlock.cs.meta b/Assets/Pacore/Editor/Drawers/Blocks/DisabledGUIBlock.cs.meta deleted file mode 100644 index 71ead8e..0000000 --- a/Assets/Pacore/Editor/Drawers/Blocks/DisabledGUIBlock.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 3d8664e5ad044a248710d9b31044d2fc -timeCreated: 1769189984 \ No newline at end of file diff --git a/Assets/Pacore/Editor/Drawers/InspectorReadOnlyDrawer.cs b/Assets/Pacore/Editor/Drawers/InspectorReadOnlyDrawer.cs index 695a77f..be5e091 100644 --- a/Assets/Pacore/Editor/Drawers/InspectorReadOnlyDrawer.cs +++ b/Assets/Pacore/Editor/Drawers/InspectorReadOnlyDrawer.cs @@ -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; } } } diff --git a/Assets/Pacore/Editor/EditorWindows.meta b/Assets/Pacore/Editor/EditorWindows.meta new file mode 100644 index 0000000..61c1883 --- /dev/null +++ b/Assets/Pacore/Editor/EditorWindows.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: d9b025c89af342a3b3cfc696a32fdb2e +timeCreated: 1769285442 \ No newline at end of file diff --git a/Assets/Pacore/Editor/EditorWindows/ProfilerWindow.cs b/Assets/Pacore/Editor/EditorWindows/ProfilerWindow.cs new file mode 100644 index 0000000..adfc17e --- /dev/null +++ b/Assets/Pacore/Editor/EditorWindows/ProfilerWindow.cs @@ -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(); + + /* 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 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[] ordered = times // List + .GroupBy(time => time) // IEnumerable> + .OrderByDescending(time => time.Key) // IOrdererEnumerable> + .ToArray(); + + foreach (IGrouping 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> 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> snippet in snippets) + { + DrawProfilerSnippet(snippet.Key, snippet.Value); + } + EditorGUILayout.EndScrollView(); + } + } +} \ No newline at end of file diff --git a/Assets/Pacore/Editor/EditorWindows/ProfilerWindow.cs.meta b/Assets/Pacore/Editor/EditorWindows/ProfilerWindow.cs.meta new file mode 100644 index 0000000..85f960a --- /dev/null +++ b/Assets/Pacore/Editor/EditorWindows/ProfilerWindow.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 5bd8cdd7db4d4436978e97bda9cdc0cb +timeCreated: 1769285452 \ No newline at end of file diff --git a/Assets/TestMonoBehaviour.cs b/Assets/TestMonoBehaviour.cs index 6900a3a..4771ddb 100644 --- a/Assets/TestMonoBehaviour.cs +++ b/Assets/TestMonoBehaviour.cs @@ -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() {