From a14b05897744f9a9881c9d1b2e0212d82bc86236 Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Thu, 30 Mar 2023 20:49:10 +0800 Subject: [PATCH] update debug tools / add WorldPoolsMonitor --- src/Debug/Editor/EcsEditor.cs | 4 +- src/Debug/Systems/DebugMonitorBase.cs | 19 +++ src/Debug/Systems/DebugMonitorBase.cs.meta | 11 ++ src/Debug/Systems/DebugMonitorPrefs.cs | 24 ++-- src/Debug/Systems/PipelineDebugSystem.cs | 29 ++-- src/Debug/Systems/WorldDebugSystem.cs | 151 ++++++++++++++++++++- src/GameObjectRef.cs | 1 + 7 files changed, 213 insertions(+), 26 deletions(-) create mode 100644 src/Debug/Systems/DebugMonitorBase.cs create mode 100644 src/Debug/Systems/DebugMonitorBase.cs.meta diff --git a/src/Debug/Editor/EcsEditor.cs b/src/Debug/Editor/EcsEditor.cs index 29d0325..31102a8 100644 --- a/src/Debug/Editor/EcsEditor.cs +++ b/src/Debug/Editor/EcsEditor.cs @@ -5,11 +5,11 @@ namespace DCFApixels.DragonECS.Editors { public static class EcsEditor { - public static GUIStyle GetStyle(Color color) + public static GUIStyle GetStyle(Color color, float alphaMultiplier) { GUIStyle style = new GUIStyle(GUI.skin.box); Color componentColor = color; - componentColor.a = 0.15f; + componentColor.a *= alphaMultiplier; style.normal.background = CreateTexture(2, 2, componentColor); return style; diff --git a/src/Debug/Systems/DebugMonitorBase.cs b/src/Debug/Systems/DebugMonitorBase.cs new file mode 100644 index 0000000..1215b1b --- /dev/null +++ b/src/Debug/Systems/DebugMonitorBase.cs @@ -0,0 +1,19 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + + +namespace DCFApixels.DragonECS.Unity.Debug +{ + public class DebugMonitorBase : MonoBehaviour + { + internal string monitorName; + + + private void Awake() + { + DontDestroyOnLoad(this.gameObject); + gameObject.SetActive(false); + } + } +} diff --git a/src/Debug/Systems/DebugMonitorBase.cs.meta b/src/Debug/Systems/DebugMonitorBase.cs.meta new file mode 100644 index 0000000..c35ff94 --- /dev/null +++ b/src/Debug/Systems/DebugMonitorBase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6b7b4bd406553d64589aa4e085d4ff28 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/Debug/Systems/DebugMonitorPrefs.cs b/src/Debug/Systems/DebugMonitorPrefs.cs index 9bcc5c3..a05ade7 100644 --- a/src/Debug/Systems/DebugMonitorPrefs.cs +++ b/src/Debug/Systems/DebugMonitorPrefs.cs @@ -6,19 +6,17 @@ namespace DCFApixels.DragonECS.Editors [FilePath("DragonECS/DebugMonitorPrefs.prefs", FilePathAttribute.Location.ProjectFolder)] public class DebugMonitorPrefs : ScriptableSingleton { - private bool _isShowHidden = false; - public bool _isShowInterfaces = false; - - public bool IsShowHidden + private bool _isShowInterfaces = false; + public bool IsShowInterfaces { - get => IsShowHidden1; set + get => _isShowInterfaces; set { - IsShowHidden1 = value; + _isShowInterfaces = value; Save(false); } } - - public bool IsShowHidden1 + private bool _isShowHidden = false; + public bool IsShowHidden { get => _isShowHidden; set { @@ -26,6 +24,16 @@ namespace DCFApixels.DragonECS.Editors Save(false); } } + + private bool _poolsToggle = false; + public bool PoolsToggle + { + get => _poolsToggle; set + { + _poolsToggle = value; + Save(false); + } + } } } #endif diff --git a/src/Debug/Systems/PipelineDebugSystem.cs b/src/Debug/Systems/PipelineDebugSystem.cs index 4dc1bb4..a0a12ee 100644 --- a/src/Debug/Systems/PipelineDebugSystem.cs +++ b/src/Debug/Systems/PipelineDebugSystem.cs @@ -1,4 +1,5 @@ -using System.Reflection; +using DCFApixels.DragonECS.Unity.Debug; +using System.Reflection; using UnityEngine; @@ -7,27 +8,25 @@ namespace DCFApixels.DragonECS [DebugHide, DebugColor(DebugColor.Gray)] public class PipelineDebugSystem : IEcsPreInitSystem { - private string _name; - public PipelineDebugSystem(string name = "Systems") + private string _monitorName; + public PipelineDebugSystem(string monitorName = "Pipeline") { - _name = name; + _monitorName = monitorName; } void IEcsPreInitSystem.PreInit(EcsPipeline pipeline) { - SystemsDebugMonitor monitor = new GameObject(EcsConsts.DEBUG_PREFIX + _name).AddComponent(); + SystemsDebugMonitor monitor = new GameObject(EcsConsts.DEBUG_PREFIX + _monitorName).AddComponent(); monitor.source = this; monitor.pipeline = pipeline; - monitor.pipelineName = _name; - Object.DontDestroyOnLoad(monitor.gameObject); + monitor.monitorName = _monitorName; } } - public class SystemsDebugMonitor : MonoBehaviour + public class SystemsDebugMonitor : DebugMonitorBase { internal PipelineDebugSystem source; internal EcsPipeline pipeline; - internal string pipelineName; } #if UNITY_EDITOR @@ -63,7 +62,7 @@ namespace DCFApixels.DragonECS GUILayout.Label("[Systems]", _headerStyle); - DebugMonitorPrefs.instance._isShowInterfaces = EditorGUILayout.Toggle("Show Interfaces", DebugMonitorPrefs.instance._isShowInterfaces); + DebugMonitorPrefs.instance.IsShowInterfaces = EditorGUILayout.Toggle("Show Interfaces", DebugMonitorPrefs.instance.IsShowInterfaces); DebugMonitorPrefs.instance.IsShowHidden = EditorGUILayout.Toggle("Show Hidden", DebugMonitorPrefs.instance.IsShowHidden); GUILayout.BeginVertical(); @@ -76,7 +75,7 @@ namespace DCFApixels.DragonECS GUILayout.Label("[Runners]", _headerStyle); - GUILayout.BeginVertical(EcsEditor.GetStyle(Color.black)); + GUILayout.BeginVertical(EcsEditor.GetStyle(Color.black, 0.2f)); foreach (var item in Target.pipeline.AllRunners) { DrawRunner(item.Value); @@ -89,7 +88,7 @@ namespace DCFApixels.DragonECS if(system is SystemsBlockMarkerSystem markerSystem) { GUILayout.EndVertical(); - GUILayout.BeginVertical(EcsEditor.GetStyle(Color.black)); + GUILayout.BeginVertical(EcsEditor.GetStyle(Color.black, 0.2f)); GUILayout.BeginHorizontal(); GUILayout.Label("<"); @@ -107,8 +106,8 @@ namespace DCFApixels.DragonECS string name = type.Name; Color color = (GetAttribute(type) ?? _fakeDebugColorAttribute).GetUnityColor(); - GUILayout.BeginVertical(EcsEditor.GetStyle(color)); - if (DebugMonitorPrefs.instance._isShowInterfaces) + GUILayout.BeginVertical(EcsEditor.GetStyle(color, 0.2f)); + if (DebugMonitorPrefs.instance.IsShowInterfaces) { GUILayout.Label(string.Join(", ", type.GetInterfaces().Select(o => o.Name)), _interfacesStyle); } @@ -123,7 +122,7 @@ namespace DCFApixels.DragonECS return; Color color = (GetAttribute(type) ?? _fakeDebugColorAttribute).GetUnityColor(); - GUILayout.BeginVertical(EcsEditor.GetStyle(color)); + GUILayout.BeginVertical(EcsEditor.GetStyle(color, 0.2f)); GUILayout.Label(type.Name, EditorStyles.boldLabel); GUILayout.Label(string.Join(", ", runner.Targets.Cast().Select(o => o.GetType().Name))); GUILayout.EndVertical(); diff --git a/src/Debug/Systems/WorldDebugSystem.cs b/src/Debug/Systems/WorldDebugSystem.cs index cd7ea21..9b02f61 100644 --- a/src/Debug/Systems/WorldDebugSystem.cs +++ b/src/Debug/Systems/WorldDebugSystem.cs @@ -1,3 +1,4 @@ +using DCFApixels.DragonECS.Unity.Debug; using System.Collections; using System.Collections.Generic; using UnityEngine; @@ -6,15 +7,163 @@ namespace DCFApixels.DragonECS { public class WorldDebugSystem : IEcsRunSystem { + private string _monitorName; private IEcsWorld _ecsWorld; - public WorldDebugSystem(IEcsWorld ecsWorld) + public WorldDebugSystem(IEcsWorld ecsWorld, string monitorName = "World") { + _monitorName = monitorName; _ecsWorld = ecsWorld; + WorldDebugMonitor monitor = new GameObject(EcsConsts.DEBUG_PREFIX + _monitorName).AddComponent(); + WorldPoolsMonitor poolsmonitor = new GameObject(EcsConsts.DEBUG_PREFIX + _monitorName).AddComponent(); + + monitor.source = this; + monitor.world = _ecsWorld; + monitor.monitorName = _monitorName; + + poolsmonitor.source = this; + poolsmonitor.world = _ecsWorld; + poolsmonitor.monitorName = _monitorName; } public void Run(EcsPipeline pipeline) { } } + + public class WorldDebugMonitor : DebugMonitorBase + { + internal WorldDebugSystem source; + internal IEcsWorld world; + } + +#if UNITY_EDITOR + namespace Editors + { + using UnityEditor; + + [CustomEditor(typeof(WorldDebugMonitor))] + public class WorldDebugMonitorEditor : Editor + { + private WorldDebugMonitor Target => (WorldDebugMonitor)target; + + + + } + } +#endif + + + + + public class WorldPoolsMonitor : DebugMonitorBase + { + internal WorldDebugSystem source; + internal IEcsWorld world; + } + +#if UNITY_EDITOR + namespace Editors + { + using System.Linq; + using UnityEditor; + using System.Reflection; + + [CustomEditor(typeof(WorldPoolsMonitor))] + public class WorldPoolsMonitorEditor : Editor + { + private static Vector2 _poolBlockMinSize = new Vector2(80, 160); + private static Vector2 _poolProgressBasrSize = _poolBlockMinSize * new Vector2(1f, 0.8f); + + private WorldPoolsMonitor Target => (WorldPoolsMonitor)target; + + private Vector2 _scroll; + + public override void OnInspectorGUI() + { + _scroll = GUILayout.BeginScrollView(_scroll, GUILayout.Height(800f)); + var pools = Target.world.GetAllPools().ToArray().Where(o => !(o is EcsNullPool)); + + GUILayout.Label("", GUILayout.ExpandWidth(true)); + + float width = GUILayoutUtility.GetLastRect().width; + + Vector3 newPoolBlockSize = _poolBlockMinSize; + int widthCount = Mathf.Max(1, Mathf.Min((Mathf.FloorToInt(width / _poolBlockMinSize.x)), pools.Count())); + newPoolBlockSize.x = width / widthCount; + + int x = -1, y = 0; + foreach (var pool in pools) + { + if(++x >= widthCount) + { + x = 0; + y++; + } + + DrawPoolBlock(pool, new Rect(newPoolBlockSize.x * x, newPoolBlockSize.y * y, newPoolBlockSize.x, newPoolBlockSize.y)); + } + GUILayout.EndScrollView(); + } + + + private void DrawPoolBlock(IEcsPool pool, Rect position) + { + Color defaultContentColor = GUI.contentColor; + GUI.contentColor = Color.black * 0.925f; + + position = AddMargin(position, 1f, 1f); + + EditorGUI.DrawRect(position, Color.black* 0.16f); + + Rect progressBar = new Rect(Vector2.zero, _poolProgressBasrSize); + progressBar.width = position.width; + progressBar.center = position.center - Vector2.up * _poolBlockMinSize.y * 0.09f; + + + Color mainColor = new Color(0.3f, 1f, 0f, 1f); + var debugColor = pool.DataType.GetCustomAttribute(); + if (debugColor != null) + { + mainColor = debugColor.GetUnityColor(); + } + Color backgroundColor = mainColor * 0.3f + Color.white * 0.2f; + + EditorGUI.DrawRect(progressBar, backgroundColor); + + progressBar.yMin = progressBar.yMax - ((float)pool.EntitiesCount / pool.Capacity) * progressBar.height; + + GUIStyle textStyle0 = EditorStyles.miniBoldLabel; + textStyle0.alignment = TextAnchor.MiddleCenter; + + Color foregroundColor = mainColor; + EditorGUI.DrawRect(progressBar, foregroundColor); + GUI.Label(progressBar, pool.EntitiesCount.ToString(), textStyle0); + + GUIStyle textStyle1 = EditorStyles.miniBoldLabel; + textStyle1.alignment = TextAnchor.UpperCenter; + GUI.Label(AddMargin(position, 3f, 3f), "Total\r\n"+ pool.Capacity, textStyle1); + + GUI.contentColor = defaultContentColor; + GUIStyle textStyle2 = EditorStyles.miniBoldLabel; + textStyle2.alignment = TextAnchor.LowerCenter; + GUI.Label(AddMargin(position, 3f, 3f), pool.DataType.Name, textStyle2); + + } + + private Rect AddMargin(Rect rect, Vector2 value) + { + return AddMargin(rect, value.x, value.y); + } + private Rect AddMargin(Rect rect, float x, float y) + { + rect.yMax -= y; + rect.yMin += y; + rect.xMax -= x; + rect.xMin += x; + return rect; + } + } + } +#endif } diff --git a/src/GameObjectRef.cs b/src/GameObjectRef.cs index b337baa..7e475a7 100644 --- a/src/GameObjectRef.cs +++ b/src/GameObjectRef.cs @@ -6,6 +6,7 @@ using UnityEditor; namespace DCFApixels.DragonECS { + [DebugColor(DebugColor.Cyan)] public struct GameObjectRef { public GameObject gameObject;