From ac618173079e649e0444d04609782de5873f4079 Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Tue, 30 May 2023 18:31:03 +0800 Subject: [PATCH 01/50] update --- src/Debug/Systems/DebugModule.cs | 2 +- src/Debug/Systems/PipelineDebugSystem.cs | 6 +++--- src/Extensions/Runners.cs | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Debug/Systems/DebugModule.cs b/src/Debug/Systems/DebugModule.cs index f64f978..9fb7311 100644 --- a/src/Debug/Systems/DebugModule.cs +++ b/src/Debug/Systems/DebugModule.cs @@ -9,7 +9,7 @@ _worlds = worlds; } - void IEcsModule.ImportSystems(EcsPipeline.Builder b) + void IEcsModule.Import(EcsPipeline.Builder b) { b.Layers.Insert(EcsConsts.POST_END_LAYER, DEBUG_LAYER); b.Add(new PipelineDebugSystem(), DEBUG_LAYER); diff --git a/src/Debug/Systems/PipelineDebugSystem.cs b/src/Debug/Systems/PipelineDebugSystem.cs index 465a7e3..dc609ef 100644 --- a/src/Debug/Systems/PipelineDebugSystem.cs +++ b/src/Debug/Systems/PipelineDebugSystem.cs @@ -112,7 +112,7 @@ namespace DCFApixels.DragonECS GUILayout.EndVertical(); } - private void DrawSystem(IEcsSystem system) + private void DrawSystem(IEcsProcess system) { if (system is SystemsLayerMarkerSystem markerSystem) { @@ -181,9 +181,9 @@ namespace DCFApixels.DragonECS private Dictionary _processeIndexes = new Dictionary(); private PipelineProcessesDebugMonitor Target => (PipelineProcessesDebugMonitor)target; - private Type systemInterfaceType = typeof(IEcsSystem); + private Type systemInterfaceType = typeof(IEcsProcess); - private IEcsSystem[] _systems; + private IEcsProcess[] _systems; private void Init() { if (_isInit) diff --git a/src/Extensions/Runners.cs b/src/Extensions/Runners.cs index 94a5731..52277d5 100644 --- a/src/Extensions/Runners.cs +++ b/src/Extensions/Runners.cs @@ -2,7 +2,7 @@ namespace DCFApixels.DragonECS { - public interface IEcsLateRunProcess : IEcsSystem + public interface IEcsLateRunProcess : IEcsProcess { public void LateRun(EcsPipeline pipeline); } @@ -13,7 +13,7 @@ namespace DCFApixels.DragonECS systems.GetRunner().LateRun(systems); } } - public interface IEcsFixedRunProcess : IEcsSystem + public interface IEcsFixedRunProcess : IEcsProcess { public void FixedRun(EcsPipeline pipeline); } From 45cbf45d138b07fdc1bf4f4a2c3868e156298e5e Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Tue, 6 Jun 2023 17:52:12 +0800 Subject: [PATCH 02/50] update --- src/Extensions/EcsEntityConnect.cs | 9 +++++++++ src/Utils/DebugColorAttributeExt.cs | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/Extensions/EcsEntityConnect.cs b/src/Extensions/EcsEntityConnect.cs index ddd2041..e7cff20 100644 --- a/src/Extensions/EcsEntityConnect.cs +++ b/src/Extensions/EcsEntityConnect.cs @@ -83,7 +83,9 @@ namespace DCFApixels.DragonECS namespace Editors { + using System.Collections.Generic; using UnityEditor; + [CustomEditor(typeof(EcsEntityConnect))] public class EcsEntityEditor : Editor { @@ -136,6 +138,13 @@ namespace DCFApixels.DragonECS EditorUtility.SetDirty(item); } } + + if (Target.IsAlive) + { + List comps = new List(); + Target.World.GetComponents(Target.Entity.ID, comps); + GUILayout.TextArea(string.Join("\r\n", comps)); + } } } } diff --git a/src/Utils/DebugColorAttributeExt.cs b/src/Utils/DebugColorAttributeExt.cs index c9d8ad5..86de672 100644 --- a/src/Utils/DebugColorAttributeExt.cs +++ b/src/Utils/DebugColorAttributeExt.cs @@ -6,7 +6,7 @@ namespace DCFApixels.DragonECS { public static Color GetUnityColor(this DebugColorAttribute self) { - return new Color(self.rn, self.gn, self.bn); + return new Color(self.r / 255f, self.g / 255f, self.b / 255f); } public static Color32 GetUnityColor32(this DebugColorAttribute self) { From 0080246ca898fa8e035b81d9248259ee98a6f27e Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Wed, 7 Jun 2023 13:58:47 +0800 Subject: [PATCH 03/50] udpate AutoDelFixed --- src/Extensions/Systems.cs | 58 +++++++++++++++------------------------ 1 file changed, 22 insertions(+), 36 deletions(-) diff --git a/src/Extensions/Systems.cs b/src/Extensions/Systems.cs index 4296026..686a940 100644 --- a/src/Extensions/Systems.cs +++ b/src/Extensions/Systems.cs @@ -1,55 +1,41 @@ -namespace DCFApixels.DragonECS +using DCFApixels.DragonECS.Internal; +using System.Collections.Generic; + +namespace DCFApixels.DragonECS { [DebugHide, DebugColor(DebugColor.Grey)] - public class DeleteOneFrameComponentFixedSystem : IEcsFixedRunProcess, IEcsInject - where TWorld : EcsWorld - where TComponent : struct, IEcsComponent + public class DeleteOneFrameComponentFixedSystem : IEcsFixedRunProcess, IEcsInject + where TComponent : struct, IEcsComponent { - private TWorld _world; - public void Inject(TWorld obj) => _world = obj; - private sealed class Subject : EcsSubject { public EcsPool pool; - public Subject(Builder b) - { - pool = b.Include(); - } + public Subject(Builder b) => pool = b.Include(); } + List _worlds = new List(); + public void Inject(EcsWorld obj) => _worlds.Add(obj); public void FixedRun(EcsPipeline pipeline) { - foreach (var e in _world.Where(out Subject s)) + for (int i = 0, iMax = _worlds.Count; i < iMax; i++) { - //try - //{ - s.pool.Del(e); - //} - //catch (System.Exception) - //{ - // - // throw; - //} + EcsWorld world = _worlds[i]; + if (world.IsComponentTypeDeclared()) + { + foreach (var e in world.Where(out Subject s)) + s.pool.Del(e); + } } } } - - public static class DeleteOneFrameComponentFixedSystemExt + public static class DeleteOneFrameComponentFixedSystemExtensions { - private const string AUTO_DEL_FIXED_LAYER = nameof(AUTO_DEL_FIXED_LAYER); - public static EcsPipeline.Builder AutoDelFixed(this EcsPipeline.Builder b) - where TWorld : EcsWorld + private const string AUTO_DEL_LAYER = nameof(AUTO_DEL_LAYER); + public static EcsPipeline.Builder AutoDelFixed(this EcsPipeline.Builder b, string layerName = AUTO_DEL_LAYER) where TComponent : struct, IEcsComponent { - b.Layers.Insert(EcsConsts.POST_END_LAYER, AUTO_DEL_FIXED_LAYER); - b.AddUnique(new DeleteOneFrameComponentFixedSystem(), AUTO_DEL_FIXED_LAYER); - return b; - } - /// for EcsDefaultWorld - public static EcsPipeline.Builder AutoDelFixed(this EcsPipeline.Builder b) - where TComponent : struct, IEcsComponent - { - b.Layers.Insert(EcsConsts.POST_END_LAYER, AUTO_DEL_FIXED_LAYER); - b.AddUnique(new DeleteOneFrameComponentFixedSystem(), AUTO_DEL_FIXED_LAYER); + if (AUTO_DEL_LAYER == layerName) + b.Layers.Insert(EcsConsts.POST_END_LAYER, AUTO_DEL_LAYER); + b.AddUnique(new DeleteOneFrameComponentSystem(), layerName); return b; } } From 1ca8510e5a92d9dfac1cb01b98b85a59343380f4 Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Sat, 10 Jun 2023 20:02:21 +0800 Subject: [PATCH 04/50] update --- src/Extensions/Runners.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Extensions/Runners.cs b/src/Extensions/Runners.cs index 52277d5..942136a 100644 --- a/src/Extensions/Runners.cs +++ b/src/Extensions/Runners.cs @@ -52,7 +52,7 @@ namespace DCFApixels.DragonECS _markers = new EcsProfilerMarker[targets.Length]; for (int i = 0; i < targets.Length; i++) { - _markers[i] = new EcsProfilerMarker(EcsDebug.RegisterMark($"EcsRunner.{targets[i].GetType().Name}.{nameof(LateRun)}")); + _markers[i] = new EcsProfilerMarker($"EcsRunner.{targets[i].GetType().Name}.{nameof(LateRun)}"); } } #endif @@ -82,7 +82,7 @@ namespace DCFApixels.DragonECS _markers = new EcsProfilerMarker[targets.Length]; for (int i = 0; i < targets.Length; i++) { - _markers[i] = new EcsProfilerMarker(EcsDebug.RegisterMark($"EcsRunner.{targets[i].GetType().Name}.{nameof(FixedRun)}")); + _markers[i] = new EcsProfilerMarker($"EcsRunner.{targets[i].GetType().Name}.{nameof(FixedRun)}"); } } #endif From b6db1dfe3f07b6bc115f62bb77082bf3aae28ba3 Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Mon, 12 Jun 2023 22:17:49 +0800 Subject: [PATCH 05/50] update --- src/Debug/DebugService/UnityDebugService.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Debug/DebugService/UnityDebugService.cs b/src/Debug/DebugService/UnityDebugService.cs index 90605e1..e54115d 100644 --- a/src/Debug/DebugService/UnityDebugService.cs +++ b/src/Debug/DebugService/UnityDebugService.cs @@ -33,22 +33,22 @@ namespace DCFApixels.DragonECS Debug.Log(v); } - public override void ProfileMarkBegin(int id) + public override void ProfilerMarkBegin(int id) { _profilerMarkers[id].Begin(); } - public override void ProfileMarkEnd(int id) + public override void ProfilerMarkEnd(int id) { _profilerMarkers[id].End(); } - protected override void OnDelMark(int id) + protected override void OnDelProfilerMark(int id) { _profilerMarkers[id] = default; } - protected override void OnNewMark(int id, string name) + protected override void OnNewProfilerMark(int id, string name) { if (id >= _profilerMarkers.Length) Array.Resize(ref _profilerMarkers, _profilerMarkers.Length << 1); _profilerMarkers[id] = new ProfilerMarker(ProfilerCategory.Scripts, name); From 171bdb429cb9ee5c20d074b4dd97a14a228373a4 Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Fri, 16 Jun 2023 11:54:41 +0800 Subject: [PATCH 06/50] update debug tools --- src/Debug/Systems/PipelineDebugSystem.cs | 7 +++- src/EntityTemplate/EntityTemplateEditor.cs | 5 ++- src/EntityTemplate/TemplateComponent.cs | 7 ++-- src/Extensions/Runners.cs | 43 ++++++++++++++++++++++ src/Utils/DebugColorAttributeExt.cs | 9 +++++ 5 files changed, 64 insertions(+), 7 deletions(-) diff --git a/src/Debug/Systems/PipelineDebugSystem.cs b/src/Debug/Systems/PipelineDebugSystem.cs index dc609ef..273a103 100644 --- a/src/Debug/Systems/PipelineDebugSystem.cs +++ b/src/Debug/Systems/PipelineDebugSystem.cs @@ -133,7 +133,8 @@ namespace DCFApixels.DragonECS return; string name = EcsEditor.GetGenericName(type); - Color color = (GetAttribute(type) ?? _fakeDebugColorAttribute).GetUnityColor(); + //Color color = (GetAttribute(type) ?? _fakeDebugColorAttribute).GetUnityColor(); + Color color = EcsDebugUtility.GetColorRGB(type).ToUnityColor(); GUILayout.BeginVertical(EcsEditor.GetStyle(color, 0.2f)); if (DebugMonitorPrefs.instance.IsShowInterfaces) @@ -150,7 +151,9 @@ namespace DCFApixels.DragonECS if (CheckIsHidden(type)) return; - Color color = (GetAttribute(type) ?? _fakeDebugColorAttribute).GetUnityColor(); + //Color color = (GetAttribute(type) ?? _fakeDebugColorAttribute).GetUnityColor(); + Color color = EcsDebugUtility.GetColorRGB(type).ToUnityColor(); + GUILayout.BeginVertical(EcsEditor.GetStyle(color, 0.2f)); GUILayout.Label(EcsEditor.GetGenericName(type), EditorStyles.boldLabel); GUILayout.Label(string.Join(", ", runner.Targets.Cast().Select(o => o.GetType().Name)), systemsListStyle); diff --git a/src/EntityTemplate/EntityTemplateEditor.cs b/src/EntityTemplate/EntityTemplateEditor.cs index 78f66c3..35d073f 100644 --- a/src/EntityTemplate/EntityTemplateEditor.cs +++ b/src/EntityTemplate/EntityTemplateEditor.cs @@ -169,8 +169,9 @@ namespace DCFApixels.DragonECS Type type = browsable.GetType(); string name = browsableName == null ? type.Name : GetLastPathComponent(browsableName.Name); string description = customInitializer != null ? customInitializer.Description : initializerType.GetCustomAttribute()?.description; - Color panelColor = customInitializer != null ? customInitializer.Color : initializerType.GetCustomAttribute()?.GetUnityColor() ?? Color.black; - + // Color panelColor = customInitializer != null ? customInitializer.Color : initializerType.GetCustomAttribute()?.GetUnityColor() ?? Color.black; + Color panelColor = customInitializer != null ? customInitializer.Color : EcsDebugUtility.GetColorRGB(initializerType).ToUnityColor(); + GUILayout.BeginHorizontal(); GUILayout.BeginVertical(EcsEditor.GetStyle(panelColor, 0.2f)); diff --git a/src/EntityTemplate/TemplateComponent.cs b/src/EntityTemplate/TemplateComponent.cs index a2486c7..f9cb3c2 100644 --- a/src/EntityTemplate/TemplateComponent.cs +++ b/src/EntityTemplate/TemplateComponent.cs @@ -38,9 +38,10 @@ namespace DCFApixels.DragonECS #region Get meta internal static Color GetColor(Type type) { - var atr = type.GetCustomAttribute(); - if (atr == null) return Color.black; - return atr.GetUnityColor(); + //var atr = type.GetCustomAttribute(); + //if (atr == null) return Color.black; + //return atr.GetUnityColor(); + return EcsDebugUtility.GetColorRGB(type).ToUnityColor(); } internal static string GetName(Type type) { diff --git a/src/Extensions/Runners.cs b/src/Extensions/Runners.cs index 942136a..992136a 100644 --- a/src/Extensions/Runners.cs +++ b/src/Extensions/Runners.cs @@ -2,6 +2,18 @@ namespace DCFApixels.DragonECS { + public interface IEcsGizmosProcess : IEcsProcess + { + public void DrawGizmos(EcsPipeline pipeline); + } + public static class IEcsGizmosProcessExtensions + { + public static void DrawGizmos(this EcsPipeline systems) + { + systems.GetRunner().DrawGizmos(systems); + } + } + public interface IEcsLateRunProcess : IEcsProcess { public void LateRun(EcsPipeline pipeline); @@ -27,6 +39,37 @@ namespace DCFApixels.DragonECS namespace Internal { + [DebugColor(DebugColor.Orange)] + public class EcsLateGizmosSystemRunner : EcsRunner, IEcsGizmosProcess + { +#if DEBUG && !DISABLE_DEBUG + private EcsProfilerMarker[] _markers; +#endif + public void DrawGizmos(EcsPipeline pipeline) + { +#if DEBUG && !DISABLE_DEBUG + for (int i = 0; i < targets.Length; i++) + { + using (_markers[i].Auto()) + targets[i].DrawGizmos(pipeline); + } +#else + foreach (var item in targets) item.DrawGizmos(pipeline); +#endif + } + +#if DEBUG && !DISABLE_DEBUG + protected override void OnSetup() + { + _markers = new EcsProfilerMarker[targets.Length]; + for (int i = 0; i < targets.Length; i++) + { + _markers[i] = new EcsProfilerMarker($"{targets[i].GetType().Name}.{nameof(DrawGizmos)}"); + } + } +#endif + } + [DebugColor(DebugColor.Orange)] public class EcsLateRunSystemRunner : EcsRunner, IEcsLateRunProcess { diff --git a/src/Utils/DebugColorAttributeExt.cs b/src/Utils/DebugColorAttributeExt.cs index 86de672..a47c9df 100644 --- a/src/Utils/DebugColorAttributeExt.cs +++ b/src/Utils/DebugColorAttributeExt.cs @@ -12,5 +12,14 @@ namespace DCFApixels.DragonECS { return new Color32(self.r, self.g, self.b, 255); } + + public static Color ToUnityColor(this (byte, byte, byte) self) + { + return new Color(self.Item1 / 255f, self.Item2 / 255f, self.Item3 / 255f); + } + public static Color32 ToUnityColor32(this (byte, byte, byte) self) + { + return new Color32(self.Item1, self.Item2, self.Item3, 255); + } } } From 4e17385e302cf3af19643ca681403ec7911658a4 Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Thu, 22 Jun 2023 12:53:12 +0800 Subject: [PATCH 07/50] update --- src/Fetures/UnityWorldProvider.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Fetures/UnityWorldProvider.cs b/src/Fetures/UnityWorldProvider.cs index db141ad..ed67222 100644 --- a/src/Fetures/UnityWorldProvider.cs +++ b/src/Fetures/UnityWorldProvider.cs @@ -3,7 +3,6 @@ namespace DCFApixels.DragonECS { public static class UnityWorldProvider - where TWorld : EcsWorld { private static TWorld _world; From e728cacfc928f4ce06dca4ee2d3e4d4f7fdaf665 Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Thu, 22 Jun 2023 14:30:03 +0800 Subject: [PATCH 08/50] rename Subject to Aspect --- src/Extensions/EcsEntityConnect.cs | 8 ++++---- src/Extensions/Systems.cs | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Extensions/EcsEntityConnect.cs b/src/Extensions/EcsEntityConnect.cs index e7cff20..a32f320 100644 --- a/src/Extensions/EcsEntityConnect.cs +++ b/src/Extensions/EcsEntityConnect.cs @@ -5,10 +5,10 @@ namespace DCFApixels.DragonECS { public class EcsEntityConnect : MonoBehaviour { - private sealed class Subject : EcsSubject + private sealed class Aspect : EcsAspect { public readonly EcsPool unityGameObjects; - public Subject(Builder b) + public Aspect(Builder b) { unityGameObjects = b.Include(); } @@ -49,7 +49,7 @@ namespace DCFApixels.DragonECS { if(_entity.TryGetID(out int oldE) && _world != null) { - var s = _world.GetSubject(); + var s = _world.GetAspect(); s.unityGameObjects.Del(oldE); } _world = null; @@ -58,7 +58,7 @@ namespace DCFApixels.DragonECS { _entity = entity; _world = _entity.World; - var s = _world.GetSubject(); + var s = _world.GetAspect(); if (!s.unityGameObjects.Has(newE)) s.unityGameObjects.Add(newE) = new UnityGameObject(gameObject); if (applyTemplates) diff --git a/src/Extensions/Systems.cs b/src/Extensions/Systems.cs index 686a940..0c8f39d 100644 --- a/src/Extensions/Systems.cs +++ b/src/Extensions/Systems.cs @@ -7,10 +7,10 @@ namespace DCFApixels.DragonECS public class DeleteOneFrameComponentFixedSystem : IEcsFixedRunProcess, IEcsInject where TComponent : struct, IEcsComponent { - private sealed class Subject : EcsSubject + private sealed class Aspect : EcsAspect { public EcsPool pool; - public Subject(Builder b) => pool = b.Include(); + public Aspect(Builder b) => pool = b.Include(); } List _worlds = new List(); public void Inject(EcsWorld obj) => _worlds.Add(obj); @@ -21,8 +21,8 @@ namespace DCFApixels.DragonECS EcsWorld world = _worlds[i]; if (world.IsComponentTypeDeclared()) { - foreach (var e in world.Where(out Subject s)) - s.pool.Del(e); + foreach (var e in world.Where(out Aspect a)) + a.pool.Del(e); } } } From cadf7abbd332ae896d0194d27e897f41032cd2da Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Thu, 22 Jun 2023 14:40:26 +0800 Subject: [PATCH 09/50] refactoring --- src/Debug/Editor/DebugMonitorPrefs.cs | 1 - src/Debug/Editor/EcsEditor.cs | 2 +- src/Debug/Systems/PipelineDebugSystem.cs | 8 +-- src/Debug/Systems/WorldDebugSystem.cs | 80 +++++++++++----------- src/EcsUnityConsts.cs | 2 +- src/EntityTemplate/EntityTemplate.cs | 2 +- src/EntityTemplate/EntityTemplateEditor.cs | 12 ++-- src/EntityTemplate/ITemplate.cs | 6 +- src/EntityTemplate/TemplateComponent.cs | 9 ++- src/Extensions/EcsEntityConnect.cs | 10 +-- src/Extensions/UnityGameObject.cs | 2 +- src/Utils/BitMask.cs | 2 +- 12 files changed, 65 insertions(+), 71 deletions(-) diff --git a/src/Debug/Editor/DebugMonitorPrefs.cs b/src/Debug/Editor/DebugMonitorPrefs.cs index 276f963..b502b93 100644 --- a/src/Debug/Editor/DebugMonitorPrefs.cs +++ b/src/Debug/Editor/DebugMonitorPrefs.cs @@ -1,6 +1,5 @@ #if UNITY_EDITOR using UnityEditor; -using UnityEngine; namespace DCFApixels.DragonECS.Editors { diff --git a/src/Debug/Editor/EcsEditor.cs b/src/Debug/Editor/EcsEditor.cs index 3bbd300..9266277 100644 --- a/src/Debug/Editor/EcsEditor.cs +++ b/src/Debug/Editor/EcsEditor.cs @@ -9,7 +9,7 @@ namespace DCFApixels.DragonECS.Editors [InitializeOnLoad] public static class EcsEditor { - static EcsEditor() + static EcsEditor() { colorBoxeStyles = new SparseArray(); } diff --git a/src/Debug/Systems/PipelineDebugSystem.cs b/src/Debug/Systems/PipelineDebugSystem.cs index 273a103..35b089b 100644 --- a/src/Debug/Systems/PipelineDebugSystem.cs +++ b/src/Debug/Systems/PipelineDebugSystem.cs @@ -204,7 +204,7 @@ namespace DCFApixels.DragonECS { foreach (var intr in system.GetType().GetInterfaces()) { - if(systemInterfaceType.IsAssignableFrom(intr) && systemInterfaceType != intr && (showHidden || intr.GetCustomAttribute() == null)) + if (systemInterfaceType.IsAssignableFrom(intr) && systemInterfaceType != intr && (showHidden || intr.GetCustomAttribute() == null)) { ProcessData data; if (!_processeIndexes.TryGetValue(intr, out int index)) @@ -217,7 +217,7 @@ namespace DCFApixels.DragonECS data.name = EcsEditor.GetGenericName(intr); data.interfaceType = intr; - data.systemsBitMask = new BitMask(_systems.Length); + data.systemsBitMask = new BitMask(_systems.Length); } data = _processesList[index]; data.systemsBitMask[i] = true; @@ -266,7 +266,7 @@ namespace DCFApixels.DragonECS rect.y = _nameCellSize.y; rect.width = _nameCellSize.x; rect.height = _cellsize.x; - rect.y -= _cellsize.y; + rect.y -= _cellsize.y; for (int i = 0; i < _processesList.Count; i++) { lineRect = rect; @@ -301,7 +301,7 @@ namespace DCFApixels.DragonECS lineRect.width = rectView.width; GUI.Label(lineRect, "", i % 2 == 1 ? whiteStyle : blackStyle); - // GUIContent label = new GUIContent(name, i + " " + name); + // GUIContent label = new GUIContent(name, i + " " + name); label.text = name; label.tooltip = i + " " + name; GUI.Label(rect, label, EditorStyles.miniBoldLabel); diff --git a/src/Debug/Systems/WorldDebugSystem.cs b/src/Debug/Systems/WorldDebugSystem.cs index 7b92448..fee56cb 100644 --- a/src/Debug/Systems/WorldDebugSystem.cs +++ b/src/Debug/Systems/WorldDebugSystem.cs @@ -1,12 +1,10 @@ using DCFApixels.DragonECS.Unity.Debug; -using System.Collections; -using System.Collections.Generic; using UnityEngine; namespace DCFApixels.DragonECS { [DebugHide, DebugColor(DebugColor.Gray)] - public class WorldDebugSystem : IEcsRunProcess + public class WorldDebugSystem : IEcsRunProcess { private string _monitorName; private EcsWorld _ecsWorld; @@ -72,8 +70,8 @@ namespace DCFApixels.DragonECS namespace Editors { using System.Linq; - using UnityEditor; using System.Reflection; + using UnityEditor; [CustomEditor(typeof(WorldPoolsMonitor))] public class WorldPoolsMonitorEditor : Editor @@ -87,30 +85,30 @@ namespace DCFApixels.DragonECS public override void OnInspectorGUI() { - _scroll = GUILayout.BeginScrollView(_scroll, GUILayout.Height(800f)); + _scroll = GUILayout.BeginScrollView(_scroll, GUILayout.Height(800f)); - var pools = Target.world.AllPools.ToArray().Where(o => !o.IsNullOrDummy()).OfType(); - - 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(); + var pools = Target.world.AllPools.ToArray().Where(o => !o.IsNullOrDummy()).OfType(); + + 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(); } @@ -121,16 +119,16 @@ namespace DCFApixels.DragonECS Color defaultContentColor = GUI.contentColor; GUI.contentColor = Color.black * 0.925f; - + position = AddMargin(position, 1f, 1f); - - EditorGUI.DrawRect(position, Color.black* 0.16f); - + + 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.ComponentType.GetCustomAttribute(); if (debugColor != null) @@ -138,22 +136,22 @@ namespace DCFApixels.DragonECS mainColor = debugColor.GetUnityColor(); } Color backgroundColor = mainColor * 0.3f + Color.white * 0.2f; - + EditorGUI.DrawRect(progressBar, backgroundColor); - + progressBar.yMin = progressBar.yMax - ((float)count / capacity) * progressBar.height; - + GUIStyle textStyle0 = new GUIStyle(EditorStyles.miniBoldLabel); textStyle0.alignment = TextAnchor.MiddleCenter; - + Color foregroundColor = mainColor; EditorGUI.DrawRect(progressBar, foregroundColor); GUI.Label(progressBar, count.ToString(), textStyle0); - + GUIStyle textStyle1 = new GUIStyle(EditorStyles.miniBoldLabel); textStyle1.alignment = TextAnchor.UpperCenter; - GUI.Label(AddMargin(position, 3f, 3f), "Total\r\n"+ capacity, textStyle1); - + GUI.Label(AddMargin(position, 3f, 3f), "Total\r\n" + capacity, textStyle1); + GUI.contentColor = defaultContentColor; GUIStyle textStyle2 = new GUIStyle(EditorStyles.miniBoldLabel); textStyle2.wordWrap = true; @@ -161,7 +159,7 @@ namespace DCFApixels.DragonECS string name = EcsEditor.GetGenericName(pool.ComponentType); GUIContent label = new GUIContent(name, $"{name} e:{count}"); GUI.Label(AddMargin(position, -10f, 3f), label, textStyle2); - + } private Rect AddMargin(Rect rect, Vector2 value) diff --git a/src/EcsUnityConsts.cs b/src/EcsUnityConsts.cs index 5196c2e..72a6350 100644 --- a/src/EcsUnityConsts.cs +++ b/src/EcsUnityConsts.cs @@ -1,6 +1,6 @@ namespace DCFApixels.DragonECS { - public static class EcsUnityConsts + public static class EcsUnityConsts { public const string INFO_MARK = "[i]"; } diff --git a/src/EntityTemplate/EntityTemplate.cs b/src/EntityTemplate/EntityTemplate.cs index 837cae8..12a437f 100644 --- a/src/EntityTemplate/EntityTemplate.cs +++ b/src/EntityTemplate/EntityTemplate.cs @@ -21,7 +21,7 @@ namespace DCFApixels.DragonECS { if (item is ITemplateComponentGizmos g) g.OnGizmos(transform, ITemplateComponentGizmos.Mode.Always); - } + } } private void OnDrawGizmosSelected() { diff --git a/src/EntityTemplate/EntityTemplateEditor.cs b/src/EntityTemplate/EntityTemplateEditor.cs index 35d073f..c300991 100644 --- a/src/EntityTemplate/EntityTemplateEditor.cs +++ b/src/EntityTemplate/EntityTemplateEditor.cs @@ -9,7 +9,7 @@ namespace DCFApixels.DragonECS using UnityEditor; using UnityEngine; - public abstract class EntityTemplateEditorBase: Editor + public abstract class EntityTemplateEditorBase : Editor { private static readonly Rect RemoveButtonRect = new Rect(0f, 0f, 15f, 15f); private static readonly Rect TooltipIconRect = new Rect(0f, 0f, 15f, 15f); @@ -31,7 +31,7 @@ namespace DCFApixels.DragonECS removeButtonStyle = new GUIStyle(EditorStyles.linkLabel); removeButtonStyle.alignment = TextAnchor.MiddleCenter; - + removeButtonStyle.normal = tmpstylebase.normal; removeButtonStyle.hover = tmpStyle.normal; removeButtonStyle.active = tmpStyle.normal; @@ -44,7 +44,7 @@ namespace DCFApixels.DragonECS genericMenu = new GenericMenu(); var dummies = TemplateBrowsableTypeCache.Dummies; - foreach ( var dummy in dummies ) + foreach (var dummy in dummies) { string name, description; if (dummy is ITemplateComponentName browsableName) @@ -137,7 +137,7 @@ namespace DCFApixels.DragonECS private void DrawComponentData(SerializedProperty componentRefProp, int index) { ITemplateComponent browsable = componentRefProp.managedReferenceValue as ITemplateComponent; - if(browsable == null) + if (browsable == null) { DrawDamagedComponent(componentRefProp, index); return; @@ -173,7 +173,7 @@ namespace DCFApixels.DragonECS Color panelColor = customInitializer != null ? customInitializer.Color : EcsDebugUtility.GetColorRGB(initializerType).ToUnityColor(); GUILayout.BeginHorizontal(); - + GUILayout.BeginVertical(EcsEditor.GetStyle(panelColor, 0.2f)); EditorGUI.BeginChangeCheck(); @@ -198,7 +198,7 @@ namespace DCFApixels.DragonECS GUILayout.EndVertical(); GUILayout.Label("", GUILayout.Width(removeButtonRect.width)); - + if (GUI.Button(removeButtonRect, "x", removeButtonStyle)) OnRemoveComponentAt(index); diff --git a/src/EntityTemplate/ITemplate.cs b/src/EntityTemplate/ITemplate.cs index c331ec0..9a45baa 100644 --- a/src/EntityTemplate/ITemplate.cs +++ b/src/EntityTemplate/ITemplate.cs @@ -1,6 +1,4 @@ -using UnityEngine; - -namespace DCFApixels.DragonECS +namespace DCFApixels.DragonECS { public interface ITemplate { @@ -9,7 +7,7 @@ namespace DCFApixels.DragonECS public interface ITemplateInternal : ITemplate { - // internal ITemplateBrowsable[] Components { get; set; } + // internal ITemplateBrowsable[] Components { get; set; } internal string ComponentsPropertyName { get; } } diff --git a/src/EntityTemplate/TemplateComponent.cs b/src/EntityTemplate/TemplateComponent.cs index f9cb3c2..9837e67 100644 --- a/src/EntityTemplate/TemplateComponent.cs +++ b/src/EntityTemplate/TemplateComponent.cs @@ -1,5 +1,4 @@ -using DCFApixels.DragonECS.Editors; -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Reflection; @@ -51,7 +50,7 @@ namespace DCFApixels.DragonECS int iBacktick = friendlyName.IndexOf('`'); if (iBacktick > 0) friendlyName = friendlyName.Remove(iBacktick); - + friendlyName += "/" + friendlyName; friendlyName += "<"; Type[] typeParameters = type.GetGenericArguments(); @@ -122,7 +121,7 @@ namespace DCFApixels.DragonECS Type interfaceType = typeof(ITemplateComponent); foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) { - var targetTypes = assembly.GetTypes().Where(type => !type.IsGenericType && (type.IsValueType|| type.IsClass) && type.GetCustomAttribute() != null); + var targetTypes = assembly.GetTypes().Where(type => !type.IsGenericType && (type.IsValueType || type.IsClass) && type.GetCustomAttribute() != null); types.AddRange(targetTypes.Where(type => interfaceType.IsAssignableFrom(type))); @@ -130,7 +129,7 @@ namespace DCFApixels.DragonECS { if (t.IsSubclassOf(typeof(TemplateComponentInitializer<>))) { - if(t.GetCustomAttribute() != null) + if (t.GetCustomAttribute() != null) types.Add(t); } } diff --git a/src/Extensions/EcsEntityConnect.cs b/src/Extensions/EcsEntityConnect.cs index a32f320..7ffe3c4 100644 --- a/src/Extensions/EcsEntityConnect.cs +++ b/src/Extensions/EcsEntityConnect.cs @@ -47,7 +47,7 @@ namespace DCFApixels.DragonECS public void ConnectWith(entlong entity, bool applyTemplates = false) { - if(_entity.TryGetID(out int oldE) && _world != null) + if (_entity.TryGetID(out int oldE) && _world != null) { var s = _world.GetAspect(); s.unityGameObjects.Del(oldE); @@ -115,8 +115,8 @@ namespace DCFApixels.DragonECS GUILayout.Box("Connected", _greenStyle, GUILayout.ExpandWidth(true)); else GUILayout.Box("Not connected", _redStyle, GUILayout.ExpandWidth(true)); - - if(Target.Entity.TryGetID(out int id)) + + if (Target.Entity.TryGetID(out int id)) EditorGUILayout.IntField(id); else EditorGUILayout.IntField(0); @@ -124,10 +124,10 @@ namespace DCFApixels.DragonECS base.OnInspectorGUI(); - if(GUILayout.Button("Autoset Templates")) + if (GUILayout.Button("Autoset Templates")) { Target.SetTemplates_Editor(Target.GetComponents()); - + EditorUtility.SetDirty(target); } if (GUILayout.Button("Autoset Templates Cascade")) diff --git a/src/Extensions/UnityGameObject.cs b/src/Extensions/UnityGameObject.cs index aaa8025..b1b9614 100644 --- a/src/Extensions/UnityGameObject.cs +++ b/src/Extensions/UnityGameObject.cs @@ -65,7 +65,7 @@ namespace DCFApixels.DragonECS entlong result = self.GetEntityLong(self.NewEmptyEntity()); GameObject newGameObject = new GameObject(name); newGameObject.AddComponent().ConnectWith(result); - // self.GetPool().Add(result.id) = + // self.GetPool().Add(result.id) = #if UNITY_EDITOR if (icon != GameObjectIcon.NONE) { diff --git a/src/Utils/BitMask.cs b/src/Utils/BitMask.cs index 7096bfe..17c9b07 100644 --- a/src/Utils/BitMask.cs +++ b/src/Utils/BitMask.cs @@ -25,7 +25,7 @@ namespace DCFApixels.DragonECS.Editors [MethodImpl(MethodImplOptions.AggressiveInlining)] set { - if(value) + if (value) _data[index >> OFFSET] |= (1 << (index & MOD_MASK)); else _data[index >> OFFSET] &= ~(1 << (index & MOD_MASK)); From 5b3bce5476430e9b327cfec10c6082380181c757 Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Wed, 28 Jun 2023 15:08:09 +0800 Subject: [PATCH 10/50] update --- src/EntityTemplate/EntityTemplate.cs | 11 ++- src/EntityTemplate/TemplateComponent.cs | 7 +- src/Extensions/EcsEntityConnect.cs | 108 ++++++++++++------------ src/Extensions/EcsEntityConnect.cs.meta | 2 +- src/Extensions/UnityComponents.cs | 57 ++++++------- 5 files changed, 98 insertions(+), 87 deletions(-) diff --git a/src/EntityTemplate/EntityTemplate.cs b/src/EntityTemplate/EntityTemplate.cs index 12a437f..26cc481 100644 --- a/src/EntityTemplate/EntityTemplate.cs +++ b/src/EntityTemplate/EntityTemplate.cs @@ -13,7 +13,16 @@ namespace DCFApixels.DragonECS foreach (var item in _components) item.Add(world, entityID); } - + private void OnValidate() + { + if (_components == null) return; + foreach (var item in _components) + { + if (item is ITemplateComponentOnValidate g) + g.OnValidate(gameObject); + } + + } private void OnDrawGizmos() { if (_components == null) return; diff --git a/src/EntityTemplate/TemplateComponent.cs b/src/EntityTemplate/TemplateComponent.cs index 9837e67..16b02fa 100644 --- a/src/EntityTemplate/TemplateComponent.cs +++ b/src/EntityTemplate/TemplateComponent.cs @@ -23,6 +23,10 @@ namespace DCFApixels.DragonECS Selected } } + public interface ITemplateComponentOnValidate + { + public void OnValidate(GameObject gameObject); + } [Serializable] public abstract class TemplateComponentInitializerBase @@ -73,7 +77,7 @@ namespace DCFApixels.DragonECS #endregion } [Serializable] - public abstract class TemplateComponentInitializer : TemplateComponentInitializerBase, ITemplateComponentName, ITemplateComponentGizmos + public abstract class TemplateComponentInitializer : TemplateComponentInitializerBase, ITemplateComponentName, ITemplateComponentGizmos, ITemplateComponentOnValidate { private static string _autoname = GetName(typeof(T)); private static Color _autoColor = GetColor(typeof(T)); @@ -94,6 +98,7 @@ namespace DCFApixels.DragonECS public abstract void Add(EcsWorld w, int e); public virtual void OnGizmos(Transform transform, ITemplateComponentGizmos.Mode mode) { } + public virtual void OnValidate(GameObject gameObject) { } } internal static class ITemplateBrowsableExt diff --git a/src/Extensions/EcsEntityConnect.cs b/src/Extensions/EcsEntityConnect.cs index 7ffe3c4..97d1ea7 100644 --- a/src/Extensions/EcsEntityConnect.cs +++ b/src/Extensions/EcsEntityConnect.cs @@ -78,75 +78,75 @@ namespace DCFApixels.DragonECS t.Apply(_world, entityID); } } +} + + #if UNITY_EDITOR - namespace Editors +namespace DCFApixels.DragonECS.Editors +{ + using System.Collections.Generic; + using UnityEditor; + + [CustomEditor(typeof(EcsEntityConnect))] + public class EcsEntityEditor : Editor { - using System.Collections.Generic; - using UnityEditor; + private EcsEntityConnect Target => (EcsEntityConnect)target; + private GUIStyle _greenStyle; + private GUIStyle _redStyle; - [CustomEditor(typeof(EcsEntityConnect))] - public class EcsEntityEditor : Editor + private bool _isInit = false; + + private void Init() { - private EcsEntityConnect Target => (EcsEntityConnect)target; - private GUIStyle _greenStyle; - private GUIStyle _redStyle; + if (_isInit) + return; + _greenStyle = EcsEditor.GetStyle(new Color32(75, 255, 0, 100)); + _redStyle = EcsEditor.GetStyle(new Color32(255, 0, 75, 100)); - private bool _isInit = false; + _isInit = true; + } - private void Init() + public override void OnInspectorGUI() + { + Init(); + if (Target.IsAlive) + GUILayout.Box("Connected", _greenStyle, GUILayout.ExpandWidth(true)); + else + GUILayout.Box("Not connected", _redStyle, GUILayout.ExpandWidth(true)); + + if (Target.Entity.TryGetID(out int id)) + EditorGUILayout.IntField(id); + else + EditorGUILayout.IntField(0); + GUILayout.Label(Target.Entity.ToString()); + + base.OnInspectorGUI(); + + if (GUILayout.Button("Autoset Templates")) { - if (_isInit) - return; + Target.SetTemplates_Editor(Target.GetComponents()); - _greenStyle = EcsEditor.GetStyle(new Color32(75, 255, 0, 100)); - _redStyle = EcsEditor.GetStyle(new Color32(255, 0, 75, 100)); - - - _isInit = true; + EditorUtility.SetDirty(target); + } + if (GUILayout.Button("Autoset Templates Cascade")) + { + foreach (var item in Target.GetComponentsInChildren()) + { + item.SetTemplates_Editor(item.GetComponents()); + EditorUtility.SetDirty(item); + } } - public override void OnInspectorGUI() + if (Target.IsAlive) { - Init(); - if (Target.IsAlive) - GUILayout.Box("Connected", _greenStyle, GUILayout.ExpandWidth(true)); - else - GUILayout.Box("Not connected", _redStyle, GUILayout.ExpandWidth(true)); - - if (Target.Entity.TryGetID(out int id)) - EditorGUILayout.IntField(id); - else - EditorGUILayout.IntField(0); - GUILayout.Label(Target.Entity.ToString()); - - base.OnInspectorGUI(); - - if (GUILayout.Button("Autoset Templates")) - { - Target.SetTemplates_Editor(Target.GetComponents()); - - EditorUtility.SetDirty(target); - } - if (GUILayout.Button("Autoset Templates Cascade")) - { - foreach (var item in Target.GetComponentsInChildren()) - { - item.SetTemplates_Editor(item.GetComponents()); - EditorUtility.SetDirty(item); - } - } - - if (Target.IsAlive) - { - List comps = new List(); - Target.World.GetComponents(Target.Entity.ID, comps); - GUILayout.TextArea(string.Join("\r\n", comps)); - } + List comps = new List(); + Target.World.GetComponents(Target.Entity.ID, comps); + GUILayout.TextArea(string.Join("\r\n", comps)); } } } -#endif } +#endif \ No newline at end of file diff --git a/src/Extensions/EcsEntityConnect.cs.meta b/src/Extensions/EcsEntityConnect.cs.meta index aff4433..302c05e 100644 --- a/src/Extensions/EcsEntityConnect.cs.meta +++ b/src/Extensions/EcsEntityConnect.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: cdc92b01ccc1e684f955830aa7cea7d4 +guid: 495156623a7b1e94087f916ba42745e6 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/src/Extensions/UnityComponents.cs b/src/Extensions/UnityComponents.cs index 5f539ba..120219a 100644 --- a/src/Extensions/UnityComponents.cs +++ b/src/Extensions/UnityComponents.cs @@ -2,97 +2,94 @@ using System.Collections; using System.Collections.Generic; using UnityEngine; -using UnityEngine.Scripting.APIUpdating; namespace DCFApixels.DragonECS { [Serializable] [DebugColor(255 / 3, 255, 0)] public struct UnityComponent : IEcsComponent, IEnumerable//IntelliSense hack - where T : class + where T : Component { public T obj; - IEnumerator IEnumerable.GetEnumerator() => throw new NotImplementedException(); //IntelliSense hack IEnumerator IEnumerable.GetEnumerator() => throw new NotImplementedException(); //IntelliSense hack } - [Serializable] - [MovedFrom(false, "Client", null, "RefRigitBodyInitializer")] - public sealed class UnityComponentRigitBodyInitializer : TemplateComponentInitializer> + + public class UnityComponentInitializer : TemplateComponentInitializer> where T : Component + { + public override string Name => "UnityComponent/" + typeof(T).Name; + public sealed override void Add(EcsWorld w, int e) => w.GetPool>().Add(e) = component; + public override void OnValidate(GameObject gameObject) + { + if (component.obj == null) + component.obj = gameObject.GetComponent(); + } + } + + + [Serializable] + public sealed class UnityComponentRigitBodyInitializer : UnityComponentInitializer { - public override void Add(EcsWorld w, int e) => w.GetPool>().Add(e) = component; } [Serializable] - [MovedFrom(false, "Client", null, "RefAnimatorInitializer")] - public sealed class UnityComponentAnimatorInitializer : TemplateComponentInitializer> + public sealed class UnityComponentAnimatorInitializer : UnityComponentInitializer { - public override void Add(EcsWorld w, int e) => w.GetPool>().Add(e) = component; } [Serializable] - public sealed class UnityComponentCharacterControllerInitializer : TemplateComponentInitializer> + public sealed class UnityComponentCharacterControllerInitializer : UnityComponentInitializer { - public override void Add(EcsWorld w, int e) => w.GetPool>().Add(e) = component; } #region Colliders [Serializable] - public sealed class UnityComponentColliderInitializer : TemplateComponentInitializer> + public sealed class UnityComponentColliderInitializer : UnityComponentInitializer { public override string Name => "UnityComponent/Collider/" + nameof(Collider); - public override void Add(EcsWorld w, int e) => w.GetPool>().Add(e) = component; } [Serializable] - public sealed class UnityComponentBoxColliderInitializer : TemplateComponentInitializer> + public sealed class UnityComponentBoxColliderInitializer : UnityComponentInitializer { public override string Name => "UnityComponent/Collider/" + nameof(BoxCollider); - public override void Add(EcsWorld w, int e) => w.GetPool>().Add(e) = component; } [Serializable] - public sealed class UnityComponentSphereColliderInitializer : TemplateComponentInitializer> + public sealed class UnityComponentSphereColliderInitializer : UnityComponentInitializer { public override string Name => "UnityComponent/Collider/" + nameof(SphereCollider); - public override void Add(EcsWorld w, int e) => w.GetPool>().Add(e) = component; } [Serializable] - public sealed class UnityComponentCapsuleColliderInitializer : TemplateComponentInitializer> + public sealed class UnityComponentCapsuleColliderInitializer : UnityComponentInitializer { public override string Name => "UnityComponent/Collider/" + nameof(CapsuleCollider); - public override void Add(EcsWorld w, int e) => w.GetPool>().Add(e) = component; } [Serializable] - public sealed class UnityComponentMeshColliderInitializer : TemplateComponentInitializer> + public sealed class UnityComponentMeshColliderInitializer : UnityComponentInitializer { public override string Name => "UnityComponent/Collider/" + nameof(MeshCollider); - public override void Add(EcsWorld w, int e) => w.GetPool>().Add(e) = component; } #endregion #region Joints [Serializable] - public sealed class UnityComponentJointInitializer : TemplateComponentInitializer> + public sealed class UnityComponentJointInitializer : UnityComponentInitializer { public override string Name => "UnityComponent/Joint/" + nameof(Joint); - public override void Add(EcsWorld w, int e) => w.GetPool>().Add(e) = component; } [Serializable] - public sealed class UnityComponentFixedJointInitializer : TemplateComponentInitializer> + public sealed class UnityComponentFixedJointInitializer : UnityComponentInitializer { public override string Name => "UnityComponent/Joint/" + nameof(FixedJoint); - public override void Add(EcsWorld w, int e) => w.GetPool>().Add(e) = component; } [Serializable] - public sealed class UnityComponentCharacterJointInitializer : TemplateComponentInitializer> + public sealed class UnityComponentCharacterJointInitializer : UnityComponentInitializer { public override string Name => "UnityComponent/Joint/" + nameof(CharacterJoint); - public override void Add(EcsWorld w, int e) => w.GetPool>().Add(e) = component; } [Serializable] - public sealed class UnityComponentConfigurableJointInitializer : TemplateComponentInitializer> + public sealed class UnityComponentConfigurableJointInitializer : UnityComponentInitializer { public override string Name => "UnityComponent/Joint/" + nameof(ConfigurableJoint); - public override void Add(EcsWorld w, int e) => w.GetPool>().Add(e) = component; } #endregion } From 2a4978c907cf8b4267cb6ba5661634c24afdf564 Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Thu, 29 Jun 2023 14:26:01 +0800 Subject: [PATCH 11/50] update --- src/{Fetures.meta => Connectors.meta} | 2 +- src/Connectors/EcsDefaultWorldProvider.cs | 19 ++++++ .../EcsDefaultWorldProvider.cs.meta} | 2 +- .../EcsEntityConnect.cs | 10 +-- .../EcsEntityConnect.cs.meta | 0 src/Connectors/EcsWorldProvider.cs | 66 +++++++++++++++++++ src/Connectors/EcsWorldProvider.cs.meta | 11 ++++ src/Debug/Editor/EcsEditor.cs | 48 ++++++++++++-- src/Extensions/UnityComponents.cs | 7 +- src/Extensions/UnityGameObject.cs | 6 +- src/Fetures/UnityWorldProvider.cs | 28 -------- 11 files changed, 149 insertions(+), 50 deletions(-) rename src/{Fetures.meta => Connectors.meta} (77%) create mode 100644 src/Connectors/EcsDefaultWorldProvider.cs rename src/{Fetures/UnityWorldProvider.cs.meta => Connectors/EcsDefaultWorldProvider.cs.meta} (83%) rename src/{Extensions => Connectors}/EcsEntityConnect.cs (89%) rename src/{Extensions => Connectors}/EcsEntityConnect.cs.meta (100%) create mode 100644 src/Connectors/EcsWorldProvider.cs create mode 100644 src/Connectors/EcsWorldProvider.cs.meta delete mode 100644 src/Fetures/UnityWorldProvider.cs diff --git a/src/Fetures.meta b/src/Connectors.meta similarity index 77% rename from src/Fetures.meta rename to src/Connectors.meta index c6ada3a..93be778 100644 --- a/src/Fetures.meta +++ b/src/Connectors.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: a20b387d9272da846b2a1206bfb6d53a +guid: 2b32116c3998f6742a35e492a88176be folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/src/Connectors/EcsDefaultWorldProvider.cs b/src/Connectors/EcsDefaultWorldProvider.cs new file mode 100644 index 0000000..40b1351 --- /dev/null +++ b/src/Connectors/EcsDefaultWorldProvider.cs @@ -0,0 +1,19 @@ +using UnityEngine; + +namespace DCFApixels.DragonECS +{ + [CreateAssetMenu(fileName = nameof(EcsDefaultWorldProvider), menuName = EcsConsts.FRAMEWORK_NAME + "/WorldProviders/" + nameof(EcsDefaultWorldProvider), order = 1)] + public class EcsDefaultWorldProvider : EcsWorldProvider + { + private static EcsDefaultWorldProvider _single; + public static EcsDefaultWorldProvider Single + { + get + { + if (_single == null) + _single = FindOrCreateSingle(); + return _single; + } + } + } +} diff --git a/src/Fetures/UnityWorldProvider.cs.meta b/src/Connectors/EcsDefaultWorldProvider.cs.meta similarity index 83% rename from src/Fetures/UnityWorldProvider.cs.meta rename to src/Connectors/EcsDefaultWorldProvider.cs.meta index 107dcbc..a5fb423 100644 --- a/src/Fetures/UnityWorldProvider.cs.meta +++ b/src/Connectors/EcsDefaultWorldProvider.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: d0af8ddc3edb89242a26c1d308a18c87 +guid: 15b6f990a7e05b34a937a9a850d7c68c MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/src/Extensions/EcsEntityConnect.cs b/src/Connectors/EcsEntityConnect.cs similarity index 89% rename from src/Extensions/EcsEntityConnect.cs rename to src/Connectors/EcsEntityConnect.cs index 97d1ea7..ba4d384 100644 --- a/src/Extensions/EcsEntityConnect.cs +++ b/src/Connectors/EcsEntityConnect.cs @@ -93,8 +93,6 @@ namespace DCFApixels.DragonECS.Editors public class EcsEntityEditor : Editor { private EcsEntityConnect Target => (EcsEntityConnect)target; - private GUIStyle _greenStyle; - private GUIStyle _redStyle; private bool _isInit = false; @@ -103,19 +101,13 @@ namespace DCFApixels.DragonECS.Editors if (_isInit) return; - _greenStyle = EcsEditor.GetStyle(new Color32(75, 255, 0, 100)); - _redStyle = EcsEditor.GetStyle(new Color32(255, 0, 75, 100)); - _isInit = true; } public override void OnInspectorGUI() { Init(); - if (Target.IsAlive) - GUILayout.Box("Connected", _greenStyle, GUILayout.ExpandWidth(true)); - else - GUILayout.Box("Not connected", _redStyle, GUILayout.ExpandWidth(true)); + EcsGUI.Layout.DrawConnectStatus(Target.IsAlive); if (Target.Entity.TryGetID(out int id)) EditorGUILayout.IntField(id); diff --git a/src/Extensions/EcsEntityConnect.cs.meta b/src/Connectors/EcsEntityConnect.cs.meta similarity index 100% rename from src/Extensions/EcsEntityConnect.cs.meta rename to src/Connectors/EcsEntityConnect.cs.meta diff --git a/src/Connectors/EcsWorldProvider.cs b/src/Connectors/EcsWorldProvider.cs new file mode 100644 index 0000000..3217499 --- /dev/null +++ b/src/Connectors/EcsWorldProvider.cs @@ -0,0 +1,66 @@ +using System; +using UnityEngine; +#if UNITY_EDITOR +using UnityEditor; +#endif + +namespace DCFApixels.DragonECS +{ + [Serializable] + public abstract class EcsWorldProviderBase : ScriptableObject + { + public abstract EcsWorld WorldRaw { get; } + public abstract EcsWorld GetRaw(Func builder = null); + } + [Serializable] + public abstract class EcsWorldProvider : EcsWorldProviderBase where TWorld : EcsWorld + { + private static TWorld _world; + public sealed override EcsWorld WorldRaw => _world; + public override EcsWorld GetRaw(Func builder = null) + { + if (_world == null || _world.IsDestroyed) + { + if (builder != null) + _world = (TWorld)builder(); + else + _world = (TWorld)Activator.CreateInstance(typeof(TWorld)); + OnWorldCreated(_world); + } + return _world; + } + public TWorld Get(Func builder = null) + { + if (_world == null || _world.IsDestroyed) + { + if(builder != null) + _world = builder(); + else + _world = (TWorld)Activator.CreateInstance(typeof(TWorld)); + OnWorldCreated(_world); + } + return _world; + } + protected virtual void OnWorldCreated(TWorld world) { } + + protected static TProvider FindOrCreateSingle() where TProvider : EcsWorldProvider + { + string name = typeof(TProvider).Name + "Single"; + TProvider instance = Resources.Load(name); + if (instance == null) + { + instance = CreateInstance(); +#if UNITY_EDITOR + if (AssetDatabase.IsValidFolder("Assets/Resources/") == false) + { + System.IO.Directory.CreateDirectory(Application.dataPath + "/Resources/"); + AssetDatabase.Refresh(); + } + AssetDatabase.CreateAsset(instance, "Assets/Resources/" + name + ".asset"); + AssetDatabase.Refresh(); +#endif + } + return instance; + } + } +} \ No newline at end of file diff --git a/src/Connectors/EcsWorldProvider.cs.meta b/src/Connectors/EcsWorldProvider.cs.meta new file mode 100644 index 0000000..0929240 --- /dev/null +++ b/src/Connectors/EcsWorldProvider.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b041a062a2a5b2643bec37be4fad79f1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/Debug/Editor/EcsEditor.cs b/src/Debug/Editor/EcsEditor.cs index 9266277..4fb00c7 100644 --- a/src/Debug/Editor/EcsEditor.cs +++ b/src/Debug/Editor/EcsEditor.cs @@ -6,6 +6,44 @@ using UnityEngine; namespace DCFApixels.DragonECS.Editors { + public static class EcsGUI + { + private static GUIStyle _greenStyle; + private static GUIStyle _redStyle; + + private static bool _isInit = false; + private static void Init() + { + if (_isInit) + return; + + _greenStyle = EcsEditor.GetStyle(new Color32(75, 255, 0, 100)); + _redStyle = EcsEditor.GetStyle(new Color32(255, 0, 75, 100)); + _isInit = true; + } + + public static void DrawConnectStatus(Rect position, bool status) + { + Init(); + if (status) + GUI.Box(position, "Connected", _greenStyle); + else + GUI.Box(position, "Not connected", _redStyle); + } + + + public static class Layout + { + public static void DrawConnectStatus(bool status, params GUILayoutOption[] options) + { + Init(); + if (status) + GUILayout.Box("Connected", _greenStyle, GUILayout.ExpandWidth(true)); + else + GUILayout.Box("Not connected", _redStyle, GUILayout.ExpandWidth(true)); + } + } + } [InitializeOnLoad] public static class EcsEditor { @@ -40,10 +78,11 @@ namespace DCFApixels.DragonECS.Editors { GUIStyle result = new GUIStyle(GUI.skin.box); Color componentColor = color32; - result.normal.background = CreateTexture(2, 2, componentColor); - result.active.background = CreateTexture(2, 2, componentColor); - result.hover.background = CreateTexture(2, 2, componentColor); - result.focused.background = CreateTexture(2, 2, componentColor); + Texture2D texture2D = CreateTexture(2, 2, componentColor); + result.hover.background = texture2D; + result.focused.background = texture2D; + result.active.background = texture2D; + result.normal.background = texture2D; return result; } private static Texture2D CreateTexture(int width, int height, Color color) @@ -58,7 +97,6 @@ namespace DCFApixels.DragonECS.Editors return result; } - public static string GetGenericName(Type type) => EcsDebugUtility.GetGenericTypeName(type); public static string GetName() => GetName(typeof(T)); diff --git a/src/Extensions/UnityComponents.cs b/src/Extensions/UnityComponents.cs index 120219a..603f036 100644 --- a/src/Extensions/UnityComponents.cs +++ b/src/Extensions/UnityComponents.cs @@ -7,10 +7,11 @@ namespace DCFApixels.DragonECS { [Serializable] [DebugColor(255 / 3, 255, 0)] - public struct UnityComponent : IEcsComponent, IEnumerable//IntelliSense hack + public readonly struct UnityComponent : IEcsComponent, IEnumerable//IntelliSense hack where T : Component { - public T obj; + public readonly T obj; + public UnityComponent(T obj) => this.obj = obj; IEnumerator IEnumerable.GetEnumerator() => throw new NotImplementedException(); //IntelliSense hack IEnumerator IEnumerable.GetEnumerator() => throw new NotImplementedException(); //IntelliSense hack } @@ -23,7 +24,7 @@ namespace DCFApixels.DragonECS public override void OnValidate(GameObject gameObject) { if (component.obj == null) - component.obj = gameObject.GetComponent(); + component = new UnityComponent(gameObject.GetComponent()); } } diff --git a/src/Extensions/UnityGameObject.cs b/src/Extensions/UnityGameObject.cs index b1b9614..83959b4 100644 --- a/src/Extensions/UnityGameObject.cs +++ b/src/Extensions/UnityGameObject.cs @@ -7,10 +7,10 @@ using UnityEditor; namespace DCFApixels.DragonECS { [DebugColor(DebugColor.Cyan)] - public struct UnityGameObject : IEcsComponent + public readonly struct UnityGameObject : IEcsComponent { - public GameObject gameObject; - public Transform transform; + public readonly GameObject gameObject; + public readonly Transform transform; public string Name { diff --git a/src/Fetures/UnityWorldProvider.cs b/src/Fetures/UnityWorldProvider.cs deleted file mode 100644 index ed67222..0000000 --- a/src/Fetures/UnityWorldProvider.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System; - -namespace DCFApixels.DragonECS -{ - public static class UnityWorldProvider - { - private static TWorld _world; - - public static TWorld Get(Func builder) - { - if (builder == null) - throw new ArgumentNullException(); - - if (_world == null) - _world = builder(); - - return _world; - } - - public static TWorld Get() - { - if (_world == null) - _world = (TWorld)Activator.CreateInstance(typeof(TWorld)); - return _world; - } - } - -} From bb73fbcdfe7bcfc04231290486e187e52d43bca2 Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Fri, 30 Jun 2023 01:13:49 +0800 Subject: [PATCH 12/50] update --- src/Debug/Systems/PipelineDebugSystem.cs | 4 ++-- src/EntityTemplate/EntityTemplateEditor.cs | 2 +- src/EntityTemplate/TemplateComponent.cs | 2 +- src/Extensions/UnityComponents.cs | 6 +++--- src/Utils/DebugColorAttributeExt.cs | 12 ++++++------ 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/Debug/Systems/PipelineDebugSystem.cs b/src/Debug/Systems/PipelineDebugSystem.cs index 35b089b..c76d447 100644 --- a/src/Debug/Systems/PipelineDebugSystem.cs +++ b/src/Debug/Systems/PipelineDebugSystem.cs @@ -134,7 +134,7 @@ namespace DCFApixels.DragonECS string name = EcsEditor.GetGenericName(type); //Color color = (GetAttribute(type) ?? _fakeDebugColorAttribute).GetUnityColor(); - Color color = EcsDebugUtility.GetColorRGB(type).ToUnityColor(); + Color color = EcsDebugUtility.GetColor(type).ToUnityColor(); GUILayout.BeginVertical(EcsEditor.GetStyle(color, 0.2f)); if (DebugMonitorPrefs.instance.IsShowInterfaces) @@ -152,7 +152,7 @@ namespace DCFApixels.DragonECS return; //Color color = (GetAttribute(type) ?? _fakeDebugColorAttribute).GetUnityColor(); - Color color = EcsDebugUtility.GetColorRGB(type).ToUnityColor(); + Color color = EcsDebugUtility.GetColor(type).ToUnityColor(); GUILayout.BeginVertical(EcsEditor.GetStyle(color, 0.2f)); GUILayout.Label(EcsEditor.GetGenericName(type), EditorStyles.boldLabel); diff --git a/src/EntityTemplate/EntityTemplateEditor.cs b/src/EntityTemplate/EntityTemplateEditor.cs index c300991..95f379b 100644 --- a/src/EntityTemplate/EntityTemplateEditor.cs +++ b/src/EntityTemplate/EntityTemplateEditor.cs @@ -170,7 +170,7 @@ namespace DCFApixels.DragonECS string name = browsableName == null ? type.Name : GetLastPathComponent(browsableName.Name); string description = customInitializer != null ? customInitializer.Description : initializerType.GetCustomAttribute()?.description; // Color panelColor = customInitializer != null ? customInitializer.Color : initializerType.GetCustomAttribute()?.GetUnityColor() ?? Color.black; - Color panelColor = customInitializer != null ? customInitializer.Color : EcsDebugUtility.GetColorRGB(initializerType).ToUnityColor(); + Color panelColor = customInitializer != null ? customInitializer.Color : EcsDebugUtility.GetColor(initializerType).ToUnityColor(); GUILayout.BeginHorizontal(); diff --git a/src/EntityTemplate/TemplateComponent.cs b/src/EntityTemplate/TemplateComponent.cs index 16b02fa..2022ae8 100644 --- a/src/EntityTemplate/TemplateComponent.cs +++ b/src/EntityTemplate/TemplateComponent.cs @@ -44,7 +44,7 @@ namespace DCFApixels.DragonECS //var atr = type.GetCustomAttribute(); //if (atr == null) return Color.black; //return atr.GetUnityColor(); - return EcsDebugUtility.GetColorRGB(type).ToUnityColor(); + return EcsDebugUtility.GetColor(type).ToUnityColor(); } internal static string GetName(Type type) { diff --git a/src/Extensions/UnityComponents.cs b/src/Extensions/UnityComponents.cs index 603f036..39c006f 100644 --- a/src/Extensions/UnityComponents.cs +++ b/src/Extensions/UnityComponents.cs @@ -7,10 +7,10 @@ namespace DCFApixels.DragonECS { [Serializable] [DebugColor(255 / 3, 255, 0)] - public readonly struct UnityComponent : IEcsComponent, IEnumerable//IntelliSense hack + public struct UnityComponent : IEcsComponent, IEnumerable//IntelliSense hack where T : Component { - public readonly T obj; + public T obj; public UnityComponent(T obj) => this.obj = obj; IEnumerator IEnumerable.GetEnumerator() => throw new NotImplementedException(); //IntelliSense hack IEnumerator IEnumerable.GetEnumerator() => throw new NotImplementedException(); //IntelliSense hack @@ -24,7 +24,7 @@ namespace DCFApixels.DragonECS public override void OnValidate(GameObject gameObject) { if (component.obj == null) - component = new UnityComponent(gameObject.GetComponent()); + component.obj = gameObject.GetComponent(); } } diff --git a/src/Utils/DebugColorAttributeExt.cs b/src/Utils/DebugColorAttributeExt.cs index a47c9df..29c8da0 100644 --- a/src/Utils/DebugColorAttributeExt.cs +++ b/src/Utils/DebugColorAttributeExt.cs @@ -6,20 +6,20 @@ namespace DCFApixels.DragonECS { public static Color GetUnityColor(this DebugColorAttribute self) { - return new Color(self.r / 255f, self.g / 255f, self.b / 255f); + return self.color.ToUnityColor(); } public static Color32 GetUnityColor32(this DebugColorAttribute self) { - return new Color32(self.r, self.g, self.b, 255); + return self.color.ToUnityColor32(); } - public static Color ToUnityColor(this (byte, byte, byte) self) + public static Color ToUnityColor(this DebugColor self) { - return new Color(self.Item1 / 255f, self.Item2 / 255f, self.Item3 / 255f); + return new Color(self.r / 255f, self.g / 255f, self.b / 255f, self.a / 255f); } - public static Color32 ToUnityColor32(this (byte, byte, byte) self) + public static Color32 ToUnityColor32(this DebugColor self) { - return new Color32(self.Item1, self.Item2, self.Item3, 255); + return new Color32(self.r, self.g, self.b, self.a); } } } From f8c95fbd989f9771bb547646c4edef34aaa3f803 Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Fri, 30 Jun 2023 01:17:49 +0800 Subject: [PATCH 13/50] update --- src/Debug/DebugService/UnityDebugService.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Debug/DebugService/UnityDebugService.cs b/src/Debug/DebugService/UnityDebugService.cs index e54115d..8d220c0 100644 --- a/src/Debug/DebugService/UnityDebugService.cs +++ b/src/Debug/DebugService/UnityDebugService.cs @@ -32,6 +32,10 @@ namespace DCFApixels.DragonECS } Debug.Log(v); } + public override void Break() + { + Debug.Break(); + } public override void ProfilerMarkBegin(int id) { @@ -53,6 +57,5 @@ namespace DCFApixels.DragonECS if (id >= _profilerMarkers.Length) Array.Resize(ref _profilerMarkers, _profilerMarkers.Length << 1); _profilerMarkers[id] = new ProfilerMarker(ProfilerCategory.Scripts, name); } - } } From 762ba241da45ecbd9873e22374291f683eac1b64 Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Mon, 17 Jul 2023 15:56:04 +0800 Subject: [PATCH 14/50] simple refactoring --- src/Debug/Editor/EcsEditor.cs | 15 +++++++++++++++ src/EntityTemplate/TemplateComponent.cs | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/Debug/Editor/EcsEditor.cs b/src/Debug/Editor/EcsEditor.cs index 4fb00c7..51ff38e 100644 --- a/src/Debug/Editor/EcsEditor.cs +++ b/src/Debug/Editor/EcsEditor.cs @@ -1,7 +1,9 @@ #if UNITY_EDITOR using System; +using System.Reflection; using System.Runtime.InteropServices; using UnityEditor; +using UnityEditor.UI; using UnityEngine; namespace DCFApixels.DragonECS.Editors @@ -136,5 +138,18 @@ namespace DCFApixels.DragonECS.Editors } #endregion } + + public static class ReflectionExtensions + { + public static bool TryGetAttribute(this MemberInfo self, out T attrbiute) where T : Attribute + { + attrbiute = self.GetCustomAttribute(); + return attrbiute != null; + } + public static bool HasAttribute(this MemberInfo self) where T : Attribute + { + return self.GetCustomAttribute() != null; + } + } } #endif diff --git a/src/EntityTemplate/TemplateComponent.cs b/src/EntityTemplate/TemplateComponent.cs index 2022ae8..54bb644 100644 --- a/src/EntityTemplate/TemplateComponent.cs +++ b/src/EntityTemplate/TemplateComponent.cs @@ -134,7 +134,7 @@ namespace DCFApixels.DragonECS { if (t.IsSubclassOf(typeof(TemplateComponentInitializer<>))) { - if (t.GetCustomAttribute() != null) + if (t.HasAttribute()) types.Add(t); } } From 0862067ddde44883732b156a98f10e73bf6c3de5 Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Mon, 26 Feb 2024 12:34:09 +0800 Subject: [PATCH 15/50] fix debug service --- src/Debug/DebugService/UnityDebugService.cs | 31 +++++++++++++-------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/src/Debug/DebugService/UnityDebugService.cs b/src/Debug/DebugService/UnityDebugService.cs index 8d220c0..361d821 100644 --- a/src/Debug/DebugService/UnityDebugService.cs +++ b/src/Debug/DebugService/UnityDebugService.cs @@ -6,14 +6,22 @@ namespace DCFApixels.DragonECS { public class UnityDebugService : DebugService { - public static void Init() => Set(); - private ProfilerMarker[] _profilerMarkers = new ProfilerMarker[64]; + public static void Activate() + { + Set(); + } public override void Print(string tag, object v) { string log; - if (!string.IsNullOrEmpty(tag)) + if (v is Exception e) + { + Debug.LogException(e); + } + + bool hasTag = string.IsNullOrEmpty(tag) == false; + if (hasTag) { log = $".[{tag}] {v}"; string taglower = tag.ToLower(); @@ -36,25 +44,24 @@ namespace DCFApixels.DragonECS { Debug.Break(); } - - public override void ProfilerMarkBegin(int id) + public sealed override void ProfilerMarkBegin(int id) { _profilerMarkers[id].Begin(); } - - public override void ProfilerMarkEnd(int id) + public sealed override void ProfilerMarkEnd(int id) { _profilerMarkers[id].End(); } - - protected override void OnDelProfilerMark(int id) + protected sealed override void OnDelProfilerMark(int id) { _profilerMarkers[id] = default; } - - protected override void OnNewProfilerMark(int id, string name) + protected sealed override void OnNewProfilerMark(int id, string name) { - if (id >= _profilerMarkers.Length) Array.Resize(ref _profilerMarkers, _profilerMarkers.Length << 1); + if (id >= _profilerMarkers.Length) + { + Array.Resize(ref _profilerMarkers, _profilerMarkers.Length << 1); + } _profilerMarkers[id] = new ProfilerMarker(ProfilerCategory.Scripts, name); } } From ebfaf5bc98204a60f48815cba8fa06e1a682c8fa Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Sun, 3 Mar 2024 03:51:49 +0800 Subject: [PATCH 16/50] Update --- src/{Extensions.meta => Buildin.meta} | 2 +- src/Buildin/EcsDefaultWorldProvider.cs | 21 + .../EcsDefaultWorldProvider.cs.meta | 0 .../EcsDefaultWorldSingletonProvider.cs | 23 + .../EcsDefaultWorldSingletonProvider.cs.meta} | 2 +- .../UnityComponents.cs | 68 ++- .../UnityComponents.cs.meta | 2 +- .../UnityGameCyclieProcesses.cs} | 57 +- .../UnityGameCyclieProcesses.cs.meta} | 2 +- .../UnityGameObject.cs | 8 +- .../UnityGameObject.cs.meta | 2 +- src/Connectors/EcsDefaultWorldProvider.cs | 19 - src/Connectors/EcsEntityConnect.cs | 139 ++++- src/Connectors/EcsWorldProvider.cs | 108 +++- src/Debug/DebugService/UnityDebugService.cs | 1 + src/Debug/Editor/DebugMonitorPrefs.cs | 2 +- src/Debug/Editor/EcsEditor.cs | 49 +- src/Debug/Systems/PipelineDebugSystem.cs | 545 +++++++++--------- src/Debug/Systems/WorldDebugSystem.cs | 167 +++--- src/EntityTemplate/Editor.meta | 8 + .../Editor/EntityTemplateEditor.cs | 251 ++++++++ .../{ => Editor}/EntityTemplateEditor.cs.meta | 0 src/EntityTemplate/EntityTemplate.cs | 49 -- src/EntityTemplate/EntityTemplateEditor.cs | 260 --------- src/EntityTemplate/EntityTemplatePreset.cs | 29 - src/EntityTemplate/ITemplate.cs | 23 - src/EntityTemplate/ITemplateNode.cs | 57 ++ ...Template.cs.meta => ITemplateNode.cs.meta} | 0 src/EntityTemplate/TemplateComponent.cs | 151 ----- src/EntityTemplate/Templates.meta | 8 + .../Templates/ComponentTemplateBase.cs | 157 +++++ .../ComponentTemplateBase.cs.meta} | 2 +- .../Templates/MonoEntityTemplate.cs | 65 +++ .../Templates/MonoEntityTemplate.cs.meta} | 2 +- .../Templates/ScriptableEntityTemplate.cs | 50 ++ .../ScriptableEntityTemplate.cs.meta | 11 + src/Extensions/Systems.cs | 42 -- src/Extensions/Systems.cs.meta | 11 - src/Utils/BitMask.cs | 13 +- src/Utils/DebugColorAttributeExt.cs | 25 - src/Utils/MetaColorExstensions.cs | 16 + ...t.cs.meta => MetaColorExstensions.cs.meta} | 0 src/Utils/SparseArray.cs | 2 +- 43 files changed, 1344 insertions(+), 1105 deletions(-) rename src/{Extensions.meta => Buildin.meta} (77%) create mode 100644 src/Buildin/EcsDefaultWorldProvider.cs rename src/{Connectors => Buildin}/EcsDefaultWorldProvider.cs.meta (100%) create mode 100644 src/Buildin/EcsDefaultWorldSingletonProvider.cs rename src/{EntityTemplate/EntityTemplatePreset.cs.meta => Buildin/EcsDefaultWorldSingletonProvider.cs.meta} (83%) rename src/{Extensions => Buildin}/UnityComponents.cs (53%) rename src/{Extensions => Buildin}/UnityComponents.cs.meta (83%) rename src/{Extensions/Runners.cs => Buildin/UnityGameCyclieProcesses.cs} (58%) rename src/{EntityTemplate/TemplateComponent.cs.meta => Buildin/UnityGameCyclieProcesses.cs.meta} (83%) rename src/{Extensions => Buildin}/UnityGameObject.cs (90%) rename src/{Extensions => Buildin}/UnityGameObject.cs.meta (83%) delete mode 100644 src/Connectors/EcsDefaultWorldProvider.cs create mode 100644 src/EntityTemplate/Editor.meta create mode 100644 src/EntityTemplate/Editor/EntityTemplateEditor.cs rename src/EntityTemplate/{ => Editor}/EntityTemplateEditor.cs.meta (100%) delete mode 100644 src/EntityTemplate/EntityTemplate.cs delete mode 100644 src/EntityTemplate/EntityTemplateEditor.cs delete mode 100644 src/EntityTemplate/EntityTemplatePreset.cs delete mode 100644 src/EntityTemplate/ITemplate.cs create mode 100644 src/EntityTemplate/ITemplateNode.cs rename src/EntityTemplate/{ITemplate.cs.meta => ITemplateNode.cs.meta} (100%) delete mode 100644 src/EntityTemplate/TemplateComponent.cs create mode 100644 src/EntityTemplate/Templates.meta create mode 100644 src/EntityTemplate/Templates/ComponentTemplateBase.cs rename src/EntityTemplate/{EntityTemplate.cs.meta => Templates/ComponentTemplateBase.cs.meta} (83%) create mode 100644 src/EntityTemplate/Templates/MonoEntityTemplate.cs rename src/{Extensions/Runners.cs.meta => EntityTemplate/Templates/MonoEntityTemplate.cs.meta} (83%) create mode 100644 src/EntityTemplate/Templates/ScriptableEntityTemplate.cs create mode 100644 src/EntityTemplate/Templates/ScriptableEntityTemplate.cs.meta delete mode 100644 src/Extensions/Systems.cs delete mode 100644 src/Extensions/Systems.cs.meta delete mode 100644 src/Utils/DebugColorAttributeExt.cs create mode 100644 src/Utils/MetaColorExstensions.cs rename src/Utils/{DebugColorAttributeExt.cs.meta => MetaColorExstensions.cs.meta} (100%) diff --git a/src/Extensions.meta b/src/Buildin.meta similarity index 77% rename from src/Extensions.meta rename to src/Buildin.meta index 4a9e845..e8b4de6 100644 --- a/src/Extensions.meta +++ b/src/Buildin.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 37d966ee996491b4d923ae68af4b67cd +guid: f2b9c91714b4752468a3a5691cbf5237 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/src/Buildin/EcsDefaultWorldProvider.cs b/src/Buildin/EcsDefaultWorldProvider.cs new file mode 100644 index 0000000..35d4f40 --- /dev/null +++ b/src/Buildin/EcsDefaultWorldProvider.cs @@ -0,0 +1,21 @@ +using UnityEngine; + +namespace DCFApixels.DragonECS +{ + [CreateAssetMenu(fileName = nameof(EcsDefaultWorldProvider), menuName = EcsConsts.FRAMEWORK_NAME + "/WorldProviders/" + nameof(EcsDefaultWorldProvider), order = 1)] + public class EcsDefaultWorldProvider : EcsWorldProvider + { + //private static EcsDefaultWorldProvider _singleInstance; + //public static EcsDefaultWorldProvider SingletonInstance + //{ + // get + // { + // if (_singleInstance == null) + // { + // _singleInstance = FindOrCreateSingleton(); + // } + // return _singleInstance; + // } + //} + } +} diff --git a/src/Connectors/EcsDefaultWorldProvider.cs.meta b/src/Buildin/EcsDefaultWorldProvider.cs.meta similarity index 100% rename from src/Connectors/EcsDefaultWorldProvider.cs.meta rename to src/Buildin/EcsDefaultWorldProvider.cs.meta diff --git a/src/Buildin/EcsDefaultWorldSingletonProvider.cs b/src/Buildin/EcsDefaultWorldSingletonProvider.cs new file mode 100644 index 0000000..956c326 --- /dev/null +++ b/src/Buildin/EcsDefaultWorldSingletonProvider.cs @@ -0,0 +1,23 @@ +namespace DCFApixels.DragonECS +{ + public class EcsDefaultWorldSingletonProvider : EcsWorldProvider + { + private static EcsDefaultWorldSingletonProvider _instance; + public static EcsDefaultWorldSingletonProvider Instance + { + get + { + if (_instance == null) + { + _instance = FindOrCreateSingleton("DefaultSingletonProvider"); + } + return _instance; + } + } + + protected override EcsDefaultWorld BuildWorld() + { + return new EcsDefaultWorld(); + } + } +} diff --git a/src/EntityTemplate/EntityTemplatePreset.cs.meta b/src/Buildin/EcsDefaultWorldSingletonProvider.cs.meta similarity index 83% rename from src/EntityTemplate/EntityTemplatePreset.cs.meta rename to src/Buildin/EcsDefaultWorldSingletonProvider.cs.meta index 10e7c2d..ee5180f 100644 --- a/src/EntityTemplate/EntityTemplatePreset.cs.meta +++ b/src/Buildin/EcsDefaultWorldSingletonProvider.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 54d84d8749e68c044b4f13a512808a67 +guid: 7592c6e5a68845c4abeac089e561d8c7 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/src/Extensions/UnityComponents.cs b/src/Buildin/UnityComponents.cs similarity index 53% rename from src/Extensions/UnityComponents.cs rename to src/Buildin/UnityComponents.cs index 39c006f..c645acb 100644 --- a/src/Extensions/UnityComponents.cs +++ b/src/Buildin/UnityComponents.cs @@ -6,89 +6,93 @@ using UnityEngine; namespace DCFApixels.DragonECS { [Serializable] - [DebugColor(255 / 3, 255, 0)] + [MetaColor(255 / 3, 255, 0)] public struct UnityComponent : IEcsComponent, IEnumerable//IntelliSense hack where T : Component { public T obj; - public UnityComponent(T obj) => this.obj = obj; + public UnityComponent(T obj) + { + this.obj = obj; + } IEnumerator IEnumerable.GetEnumerator() => throw new NotImplementedException(); //IntelliSense hack IEnumerator IEnumerable.GetEnumerator() => throw new NotImplementedException(); //IntelliSense hack } - - public class UnityComponentInitializer : TemplateComponentInitializer> where T : Component + #region Unity Component Templates + public class UnityComponentTemplate : ComponentTemplateBase> where T : Component { public override string Name => "UnityComponent/" + typeof(T).Name; - public sealed override void Add(EcsWorld w, int e) => w.GetPool>().Add(e) = component; - public override void OnValidate(GameObject gameObject) + public sealed override void Apply(int worldID, int entityID) + { + EcsWorld.GetPool>>(worldID).TryAddOrGet(entityID) = component; + } + public override void OnValidate(UnityEngine.Object obj) { if (component.obj == null) - component.obj = gameObject.GetComponent(); + { + if (obj is GameObject go) + { + component.obj = go.GetComponent(); + } + } } } + [Serializable] + public sealed class UnityComponentRigitBodyInitializer : UnityComponentTemplate { } + [Serializable] + public sealed class UnityComponentAnimatorInitializer : UnityComponentTemplate { } + [Serializable] + public sealed class UnityComponentCharacterControllerInitializer : UnityComponentTemplate { } + #endregion + #region Collider Templates [Serializable] - public sealed class UnityComponentRigitBodyInitializer : UnityComponentInitializer - { - } - - [Serializable] - public sealed class UnityComponentAnimatorInitializer : UnityComponentInitializer - { - } - [Serializable] - public sealed class UnityComponentCharacterControllerInitializer : UnityComponentInitializer - { - } - - #region Colliders - [Serializable] - public sealed class UnityComponentColliderInitializer : UnityComponentInitializer + public sealed class UnityComponentColliderTemplate : UnityComponentTemplate { public override string Name => "UnityComponent/Collider/" + nameof(Collider); } [Serializable] - public sealed class UnityComponentBoxColliderInitializer : UnityComponentInitializer + public sealed class UnityComponentBoxColliderTemplate : UnityComponentTemplate { public override string Name => "UnityComponent/Collider/" + nameof(BoxCollider); } [Serializable] - public sealed class UnityComponentSphereColliderInitializer : UnityComponentInitializer + public sealed class UnityComponentSphereColliderTemplate : UnityComponentTemplate { public override string Name => "UnityComponent/Collider/" + nameof(SphereCollider); } [Serializable] - public sealed class UnityComponentCapsuleColliderInitializer : UnityComponentInitializer + public sealed class UnityComponentCapsuleColliderTemplate : UnityComponentTemplate { public override string Name => "UnityComponent/Collider/" + nameof(CapsuleCollider); } [Serializable] - public sealed class UnityComponentMeshColliderInitializer : UnityComponentInitializer + public sealed class UnityComponentMeshColliderTemplate : UnityComponentTemplate { public override string Name => "UnityComponent/Collider/" + nameof(MeshCollider); } #endregion - #region Joints + #region Joint Templates [Serializable] - public sealed class UnityComponentJointInitializer : UnityComponentInitializer + public sealed class UnityComponentJointTemplate : UnityComponentTemplate { public override string Name => "UnityComponent/Joint/" + nameof(Joint); } [Serializable] - public sealed class UnityComponentFixedJointInitializer : UnityComponentInitializer + public sealed class UnityComponentFixedJointTemplate : UnityComponentTemplate { public override string Name => "UnityComponent/Joint/" + nameof(FixedJoint); } [Serializable] - public sealed class UnityComponentCharacterJointInitializer : UnityComponentInitializer + public sealed class UnityComponentCharacterJointTemplate : UnityComponentTemplate { public override string Name => "UnityComponent/Joint/" + nameof(CharacterJoint); } [Serializable] - public sealed class UnityComponentConfigurableJointInitializer : UnityComponentInitializer + public sealed class UnityComponentConfigurableJointTemplate : UnityComponentTemplate { public override string Name => "UnityComponent/Joint/" + nameof(ConfigurableJoint); } diff --git a/src/Extensions/UnityComponents.cs.meta b/src/Buildin/UnityComponents.cs.meta similarity index 83% rename from src/Extensions/UnityComponents.cs.meta rename to src/Buildin/UnityComponents.cs.meta index a32753d..5fb8d60 100644 --- a/src/Extensions/UnityComponents.cs.meta +++ b/src/Buildin/UnityComponents.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 47a8547ed46c26e4bb6a68651ad40be0 +guid: 637d69c48b6c0164abe654cd7f5ceb07 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/src/Extensions/Runners.cs b/src/Buildin/UnityGameCyclieProcesses.cs similarity index 58% rename from src/Extensions/Runners.cs rename to src/Buildin/UnityGameCyclieProcesses.cs index 992136a..aa086c1 100644 --- a/src/Extensions/Runners.cs +++ b/src/Buildin/UnityGameCyclieProcesses.cs @@ -1,4 +1,5 @@ -using DCFApixels.DragonECS.RunnersCore; +using DCFApixels.DragonECS.Internal; +using DCFApixels.DragonECS.RunnersCore; namespace DCFApixels.DragonECS { @@ -10,7 +11,7 @@ namespace DCFApixels.DragonECS { public static void DrawGizmos(this EcsPipeline systems) { - systems.GetRunner().DrawGizmos(systems); + systems.GetRunnerInstance().DrawGizmos(systems); } } @@ -20,9 +21,9 @@ namespace DCFApixels.DragonECS } public static class IEcsLateRunSystemExtensions { - public static void LateRun(this EcsPipeline systems) + public static void LateRun(this EcsPipeline pipeline) { - systems.GetRunner().LateRun(systems); + pipeline.GetRunnerInstance().LateRun(pipeline); } } public interface IEcsFixedRunProcess : IEcsProcess @@ -33,14 +34,14 @@ namespace DCFApixels.DragonECS { public static void FixedRun(this EcsPipeline pipeline) { - pipeline.GetRunner().FixedRun(pipeline); + pipeline.GetRunnerInstance().FixedRun(pipeline); } } namespace Internal { - [DebugColor(DebugColor.Orange)] - public class EcsLateGizmosSystemRunner : EcsRunner, IEcsGizmosProcess + [MetaColor(MetaColor.Orange)] + public class EcsLateGizmosRunner : EcsRunner, IEcsGizmosProcess { #if DEBUG && !DISABLE_DEBUG private EcsProfilerMarker[] _markers; @@ -48,10 +49,10 @@ namespace DCFApixels.DragonECS public void DrawGizmos(EcsPipeline pipeline) { #if DEBUG && !DISABLE_DEBUG - for (int i = 0; i < targets.Length; i++) + for (int i = 0; i < Process.Length; i++) { using (_markers[i].Auto()) - targets[i].DrawGizmos(pipeline); + Process[i].DrawGizmos(pipeline); } #else foreach (var item in targets) item.DrawGizmos(pipeline); @@ -61,17 +62,17 @@ namespace DCFApixels.DragonECS #if DEBUG && !DISABLE_DEBUG protected override void OnSetup() { - _markers = new EcsProfilerMarker[targets.Length]; - for (int i = 0; i < targets.Length; i++) + _markers = new EcsProfilerMarker[Process.Length]; + for (int i = 0; i < Process.Length; i++) { - _markers[i] = new EcsProfilerMarker($"{targets[i].GetType().Name}.{nameof(DrawGizmos)}"); + _markers[i] = new EcsProfilerMarker($"{Process[i].GetType().Name}.{nameof(DrawGizmos)}"); } } #endif } - [DebugColor(DebugColor.Orange)] - public class EcsLateRunSystemRunner : EcsRunner, IEcsLateRunProcess + [MetaColor(MetaColor.Orange)] + public class EcsLateRunRunner : EcsRunner, IEcsLateRunProcess { #if DEBUG && !DISABLE_DEBUG private EcsProfilerMarker[] _markers; @@ -79,10 +80,12 @@ namespace DCFApixels.DragonECS public void LateRun(EcsPipeline pipeline) { #if DEBUG && !DISABLE_DEBUG - for (int i = 0; i < targets.Length; i++) + for (int i = 0; i < Process.Length; i++) { using (_markers[i].Auto()) - targets[i].LateRun(pipeline); + { + Process[i].LateRun(pipeline); + } } #else foreach (var item in targets) item.LateRun(pipeline); @@ -92,16 +95,16 @@ namespace DCFApixels.DragonECS #if DEBUG && !DISABLE_DEBUG protected override void OnSetup() { - _markers = new EcsProfilerMarker[targets.Length]; - for (int i = 0; i < targets.Length; i++) + _markers = new EcsProfilerMarker[Process.Length]; + for (int i = 0; i < Process.Length; i++) { - _markers[i] = new EcsProfilerMarker($"EcsRunner.{targets[i].GetType().Name}.{nameof(LateRun)}"); + _markers[i] = new EcsProfilerMarker($"EcsRunner.{Process[i].GetType().Name}.{nameof(LateRun)}"); } } #endif } - [DebugColor(DebugColor.Orange)] - public class EcsFixedRunSystemRunner : EcsRunner, IEcsFixedRunProcess + [MetaColor(MetaColor.Orange)] + public class EcsFixedRunRunner : EcsRunner, IEcsFixedRunProcess { #if DEBUG && !DISABLE_DEBUG private EcsProfilerMarker[] _markers; @@ -109,10 +112,12 @@ namespace DCFApixels.DragonECS public void FixedRun(EcsPipeline pipeline) { #if DEBUG && !DISABLE_DEBUG - for (int i = 0; i < targets.Length; i++) + for (int i = 0; i < Process.Length; i++) { using (_markers[i].Auto()) - targets[i].FixedRun(pipeline); + { + Process[i].FixedRun(pipeline); + } } #else foreach (var item in targets) item.FixedRun(pipeline); @@ -122,10 +127,10 @@ namespace DCFApixels.DragonECS #if DEBUG && !DISABLE_DEBUG protected override void OnSetup() { - _markers = new EcsProfilerMarker[targets.Length]; - for (int i = 0; i < targets.Length; i++) + _markers = new EcsProfilerMarker[Process.Length]; + for (int i = 0; i < Process.Length; i++) { - _markers[i] = new EcsProfilerMarker($"EcsRunner.{targets[i].GetType().Name}.{nameof(FixedRun)}"); + _markers[i] = new EcsProfilerMarker($"EcsRunner.{Process[i].GetType().Name}.{nameof(FixedRun)}"); } } #endif diff --git a/src/EntityTemplate/TemplateComponent.cs.meta b/src/Buildin/UnityGameCyclieProcesses.cs.meta similarity index 83% rename from src/EntityTemplate/TemplateComponent.cs.meta rename to src/Buildin/UnityGameCyclieProcesses.cs.meta index 77e0d5d..f2b4894 100644 --- a/src/EntityTemplate/TemplateComponent.cs.meta +++ b/src/Buildin/UnityGameCyclieProcesses.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 0ce52308e352f734e8a21c5ae282c246 +guid: 9b692b77d059ff445912bada1712ccab MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/src/Extensions/UnityGameObject.cs b/src/Buildin/UnityGameObject.cs similarity index 90% rename from src/Extensions/UnityGameObject.cs rename to src/Buildin/UnityGameObject.cs index 83959b4..be8159c 100644 --- a/src/Extensions/UnityGameObject.cs +++ b/src/Buildin/UnityGameObject.cs @@ -6,7 +6,7 @@ using UnityEditor; namespace DCFApixels.DragonECS { - [DebugColor(DebugColor.Cyan)] + [MetaColor(MetaColor.Cyan)] public readonly struct UnityGameObject : IEcsComponent { public readonly GameObject gameObject; @@ -60,12 +60,11 @@ namespace DCFApixels.DragonECS public static class GameObjectRefExt { - public static entlong NewEntityWithGameObject(this EcsWorld self, string name = "EcsEntity", GameObjectIcon icon = GameObjectIcon.NONE) + public static entlong NewEntityWithGameObject(this EcsWorld self, string name = "Entity", GameObjectIcon icon = GameObjectIcon.NONE) { - entlong result = self.GetEntityLong(self.NewEmptyEntity()); + entlong result = self.NewEntityLong(); GameObject newGameObject = new GameObject(name); newGameObject.AddComponent().ConnectWith(result); - // self.GetPool().Add(result.id) = #if UNITY_EDITOR if (icon != GameObjectIcon.NONE) { @@ -84,7 +83,6 @@ namespace DCFApixels.DragonECS EditorGUIUtility.SetIconForObject(newGameObject, (Texture2D)iconContent.image); } #endif - return result; } } diff --git a/src/Extensions/UnityGameObject.cs.meta b/src/Buildin/UnityGameObject.cs.meta similarity index 83% rename from src/Extensions/UnityGameObject.cs.meta rename to src/Buildin/UnityGameObject.cs.meta index 1b88100..7ec5d76 100644 --- a/src/Extensions/UnityGameObject.cs.meta +++ b/src/Buildin/UnityGameObject.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 909b2b01fa1e58b4e9e739827e36cff4 +guid: 398c78166eea90647a60b91b2b9a0f0b MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/src/Connectors/EcsDefaultWorldProvider.cs b/src/Connectors/EcsDefaultWorldProvider.cs deleted file mode 100644 index 40b1351..0000000 --- a/src/Connectors/EcsDefaultWorldProvider.cs +++ /dev/null @@ -1,19 +0,0 @@ -using UnityEngine; - -namespace DCFApixels.DragonECS -{ - [CreateAssetMenu(fileName = nameof(EcsDefaultWorldProvider), menuName = EcsConsts.FRAMEWORK_NAME + "/WorldProviders/" + nameof(EcsDefaultWorldProvider), order = 1)] - public class EcsDefaultWorldProvider : EcsWorldProvider - { - private static EcsDefaultWorldProvider _single; - public static EcsDefaultWorldProvider Single - { - get - { - if (_single == null) - _single = FindOrCreateSingle(); - return _single; - } - } - } -} diff --git a/src/Connectors/EcsEntityConnect.cs b/src/Connectors/EcsEntityConnect.cs index ba4d384..8492720 100644 --- a/src/Connectors/EcsEntityConnect.cs +++ b/src/Connectors/EcsEntityConnect.cs @@ -18,13 +18,13 @@ namespace DCFApixels.DragonECS private EcsWorld _world; [SerializeField] - private EntityTemplatePreset[] _entityTemplatePresets; + private ScriptableEntityTemplate[] _scriptableTemplates; [SerializeField] - private EntityTemplate[] _entityTemplates; + private MonoEntityTemplate[] _monoTemplates; - internal void SetTemplates_Editor(EntityTemplate[] tempaltes) + internal void SetTemplates_Editor(MonoEntityTemplate[] tempaltes) { - _entityTemplates = tempaltes; + _monoTemplates = tempaltes; } #region Properties @@ -38,7 +38,7 @@ namespace DCFApixels.DragonECS [MethodImpl(MethodImplOptions.AggressiveInlining)] get => _world; } - public bool IsAlive + public bool IsConected { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => _entity.IsAlive; @@ -69,70 +69,157 @@ namespace DCFApixels.DragonECS _entity = entlong.NULL; } } - public void ApplyTemplates() => ApplyTemplatesFor(_entity.ID); + public void ApplyTemplates() + { + ApplyTemplatesFor(_entity.ID); + } public void ApplyTemplatesFor(int entityID) { - foreach (var t in _entityTemplatePresets) - t.Apply(_world, entityID); - foreach (var t in _entityTemplates) - t.Apply(_world, entityID); + foreach (var t in _scriptableTemplates) + { + t.Apply(_world.id, entityID); + } + foreach (var t in _monoTemplates) + { + t.Apply(_world.id, entityID); + } } } } - #if UNITY_EDITOR - -namespace DCFApixels.DragonECS.Editors +namespace DCFApixels.DragonECS.Unity.Editors { using System.Collections.Generic; using UnityEditor; [CustomEditor(typeof(EcsEntityConnect))] + [CanEditMultipleObjects] public class EcsEntityEditor : Editor { - private EcsEntityConnect Target => (EcsEntityConnect)target; - private bool _isInit = false; + private EcsEntityConnect Target => (EcsEntityConnect)target; + private bool IsMultipleTargets => targets.Length > 1; private void Init() { if (_isInit) + { return; - + } _isInit = true; } public override void OnInspectorGUI() { Init(); - EcsGUI.Layout.DrawConnectStatus(Target.IsAlive); + EcsEntityConnect[] targets = new EcsEntityConnect[this.targets.Length]; + for (int i = 0; i < targets.Length; i++) + { + targets[i] = (EcsEntityConnect)this.targets[i]; + } + DrawTop(); - if (Target.Entity.TryGetID(out int id)) - EditorGUILayout.IntField(id); + DrawConnectStatus(targets); + DrawEntityInfo(); + + DrawTemplates(); + + DrawButtons(); + DrawComponents(); + } + private void DrawTop() + { + var iterator = serializedObject.GetIterator(); + iterator.NextVisible(true); + using (new EditorGUI.DisabledScope("m_Script" == iterator.propertyPath)) + { + EditorGUILayout.PropertyField(iterator, true); + } + } + private void DrawConnectStatus(EcsEntityConnect[] targets) + { + bool isConnected = Target.IsConected; + for (int i = 0; i < targets.Length; i++) + { + if (isConnected != targets[i].IsConected) + { + isConnected = !Target.IsConected; + break; + } + } + if (isConnected == Target.IsConected) + { + EcsGUI.Layout.DrawConnectStatus(Target.IsConected); + } else - EditorGUILayout.IntField(0); - GUILayout.Label(Target.Entity.ToString()); + { + EcsGUI.Layout.DrawUndeterminedConnectStatus(); + } + } - base.OnInspectorGUI(); + private void DrawEntityInfo() + { + GUILayout.Label(string.Empty); + Rect entityRect = GUILayoutUtility.GetLastRect(); + Rect idRect = entityRect; + idRect.xMax -= idRect.width / 2f; + Rect genRect = entityRect; + genRect.xMin = idRect.xMax; + genRect.xMax -= genRect.width / 2f; + Rect worldRect = genRect; + worldRect.x += worldRect.width; + if (IsMultipleTargets == false && Target.Entity.TryUnpack(out int id, out short gen, out short world)) + { + EditorGUI.IntField(idRect, id); + EditorGUI.IntField(genRect, gen); + EditorGUI.IntField(worldRect, world); + } + else + { + EditorGUI.TextField(idRect, "-"); + EditorGUI.TextField(genRect, "-"); + EditorGUI.TextField(worldRect, "-"); + } + } + + private void DrawTemplates() + { + var iterator = serializedObject.GetIterator(); + iterator.NextVisible(true); + bool enterChildren = true; + while (iterator.NextVisible(enterChildren)) + { + using (new EditorGUI.DisabledScope("m_Script" == iterator.propertyPath)) + { + EditorGUILayout.PropertyField(iterator, true); + } + enterChildren = false; + } + } + + private void DrawButtons() + { if (GUILayout.Button("Autoset Templates")) { - Target.SetTemplates_Editor(Target.GetComponents()); - + Target.SetTemplates_Editor(Target.GetComponents()); EditorUtility.SetDirty(target); } if (GUILayout.Button("Autoset Templates Cascade")) { foreach (var item in Target.GetComponentsInChildren()) { - item.SetTemplates_Editor(item.GetComponents()); + item.SetTemplates_Editor(item.GetComponents()); EditorUtility.SetDirty(item); } } + } - if (Target.IsAlive) + private void DrawComponents() + { + if (Target.IsConected) { List comps = new List(); Target.World.GetComponents(Target.Entity.ID, comps); diff --git a/src/Connectors/EcsWorldProvider.cs b/src/Connectors/EcsWorldProvider.cs index 3217499..48cbbbd 100644 --- a/src/Connectors/EcsWorldProvider.cs +++ b/src/Connectors/EcsWorldProvider.cs @@ -9,43 +9,50 @@ namespace DCFApixels.DragonECS [Serializable] public abstract class EcsWorldProviderBase : ScriptableObject { - public abstract EcsWorld WorldRaw { get; } - public abstract EcsWorld GetRaw(Func builder = null); + public abstract bool IsEmpty { get; } + public abstract void SetRaw(EcsWorld world); + public abstract EcsWorld GetRaw(); } [Serializable] public abstract class EcsWorldProvider : EcsWorldProviderBase where TWorld : EcsWorld { - private static TWorld _world; - public sealed override EcsWorld WorldRaw => _world; - public override EcsWorld GetRaw(Func builder = null) - { - if (_world == null || _world.IsDestroyed) - { - if (builder != null) - _world = (TWorld)builder(); - else - _world = (TWorld)Activator.CreateInstance(typeof(TWorld)); - OnWorldCreated(_world); - } - return _world; - } - public TWorld Get(Func builder = null) - { - if (_world == null || _world.IsDestroyed) - { - if(builder != null) - _world = builder(); - else - _world = (TWorld)Activator.CreateInstance(typeof(TWorld)); - OnWorldCreated(_world); - } - return _world; - } - protected virtual void OnWorldCreated(TWorld world) { } + private TWorld _world; - protected static TProvider FindOrCreateSingle() where TProvider : EcsWorldProvider + #region Properties + public sealed override bool IsEmpty + { + get { return _world == null; } + } + #endregion + + #region Methods + public sealed override void SetRaw(EcsWorld worldRaw) + { + Set((TWorld)worldRaw); + } + public void Set(TWorld world) + { + _world = world; + } + public sealed override EcsWorld GetRaw() + { + return Get(); + } + public TWorld Get() + { + if (_world == null || _world.IsDestroyed) + { + _world = BuildWorld(); + OnWorldCreated(_world); + } + return _world; + } + protected static TProvider FindOrCreateSingleton() where TProvider : EcsWorldProvider + { + return FindOrCreateSingleton(typeof(TProvider).Name + "Singleton"); + } + protected static TProvider FindOrCreateSingleton(string name) where TProvider : EcsWorldProvider { - string name = typeof(TProvider).Name + "Single"; TProvider instance = Resources.Load(name); if (instance == null) { @@ -62,5 +69,42 @@ namespace DCFApixels.DragonECS } return instance; } + #endregion + + #region Events + protected virtual TWorld BuildWorld() + { + return (TWorld)Activator.CreateInstance(typeof(TWorld), new object[] { null, -1 }); + } + protected virtual void OnWorldCreated(TWorld world) { } + #endregion } -} \ No newline at end of file +} + +#if UNITY_EDITOR +namespace DCFApixels.DragonECS.Unity.Editors +{ + [CustomEditor(typeof(EcsWorldProviderBase), true)] + [CanEditMultipleObjects] + public class EcsWorldProviderBaseEditor : Editor + { + private EcsWorldProviderBase Target => (EcsWorldProviderBase)target; + + public override void OnInspectorGUI() + { + base.OnInspectorGUI(); + if (Target.IsEmpty) + { + var style = EcsEditor.GetStyle(new Color32(255, 0, 75, 100)); + GUILayout.Box("Is Empty", style, GUILayout.ExpandWidth(true)); + } + else + { + var style = EcsEditor.GetStyle(new Color32(75, 255, 0, 100)); + EcsWorld world = Target.GetRaw(); + GUILayout.Box($"{world.GetMeta().Name} ( {world.id} )", style, GUILayout.ExpandWidth(true)); + } + } + } +} +#endif \ No newline at end of file diff --git a/src/Debug/DebugService/UnityDebugService.cs b/src/Debug/DebugService/UnityDebugService.cs index 361d821..20d3097 100644 --- a/src/Debug/DebugService/UnityDebugService.cs +++ b/src/Debug/DebugService/UnityDebugService.cs @@ -18,6 +18,7 @@ namespace DCFApixels.DragonECS if (v is Exception e) { Debug.LogException(e); + return; } bool hasTag = string.IsNullOrEmpty(tag) == false; diff --git a/src/Debug/Editor/DebugMonitorPrefs.cs b/src/Debug/Editor/DebugMonitorPrefs.cs index b502b93..3b32eb0 100644 --- a/src/Debug/Editor/DebugMonitorPrefs.cs +++ b/src/Debug/Editor/DebugMonitorPrefs.cs @@ -1,7 +1,7 @@ #if UNITY_EDITOR using UnityEditor; -namespace DCFApixels.DragonECS.Editors +namespace DCFApixels.DragonECS.Unity.Editors { [FilePath("DragonECS/DebugMonitorPrefs.prefs", FilePathAttribute.Location.ProjectFolder)] public class DebugMonitorPrefs : ScriptableSingleton diff --git a/src/Debug/Editor/EcsEditor.cs b/src/Debug/Editor/EcsEditor.cs index 51ff38e..1a673e4 100644 --- a/src/Debug/Editor/EcsEditor.cs +++ b/src/Debug/Editor/EcsEditor.cs @@ -1,48 +1,83 @@ #if UNITY_EDITOR +using DCFApixels.DragonECS.Unity.Internal; using System; using System.Reflection; using System.Runtime.InteropServices; using UnityEditor; -using UnityEditor.UI; using UnityEngine; -namespace DCFApixels.DragonECS.Editors +namespace DCFApixels.DragonECS.Unity.Editors { public static class EcsGUI { + private static GUIStyle _grayStyle; private static GUIStyle _greenStyle; private static GUIStyle _redStyle; + private static GUILayoutOption[] _defaultParams; private static bool _isInit = false; private static void Init() { if (_isInit) + { return; + } + _defaultParams = new GUILayoutOption[] { GUILayout.ExpandWidth(true) }; + _grayStyle = EcsEditor.GetStyle(new Color32(100, 100, 100, 100)); _greenStyle = EcsEditor.GetStyle(new Color32(75, 255, 0, 100)); _redStyle = EcsEditor.GetStyle(new Color32(255, 0, 75, 100)); _isInit = true; } + + private const string CONNECTED = "Connected"; + private const string NOT_CONNECTED = "Not connected"; + private const string UNDETERMINED_CONNECTED = "---"; public static void DrawConnectStatus(Rect position, bool status) { Init(); if (status) - GUI.Box(position, "Connected", _greenStyle); + { + GUI.Box(position, CONNECTED, _greenStyle); + } else - GUI.Box(position, "Not connected", _redStyle); + { + GUI.Box(position, NOT_CONNECTED, _redStyle); + } } - + public static void DrawUndeterminedConnectStatus(Rect position) + { + Init(); + GUI.Box(position, UNDETERMINED_CONNECTED, _grayStyle); + } public static class Layout { public static void DrawConnectStatus(bool status, params GUILayoutOption[] options) { Init(); + if(options == null || options.Length <= 0) + { + options = _defaultParams; + } if (status) - GUILayout.Box("Connected", _greenStyle, GUILayout.ExpandWidth(true)); + { + GUILayout.Box(CONNECTED, _greenStyle, options); + } else - GUILayout.Box("Not connected", _redStyle, GUILayout.ExpandWidth(true)); + { + GUILayout.Box(NOT_CONNECTED, _redStyle, options); + } + } + public static void DrawUndeterminedConnectStatus(params GUILayoutOption[] options) + { + Init(); + if (options == null || options.Length <= 0) + { + options = _defaultParams; + } + GUILayout.Box(UNDETERMINED_CONNECTED, _grayStyle, options); } } } diff --git a/src/Debug/Systems/PipelineDebugSystem.cs b/src/Debug/Systems/PipelineDebugSystem.cs index c76d447..8f4efa3 100644 --- a/src/Debug/Systems/PipelineDebugSystem.cs +++ b/src/Debug/Systems/PipelineDebugSystem.cs @@ -1,29 +1,30 @@ using DCFApixels.DragonECS.Unity.Debug; -using System.Reflection; using UnityEngine; +using System.Linq; namespace DCFApixels.DragonECS { - [DebugHide, DebugColor(DebugColor.Gray)] - public class PipelineDebugSystem : IEcsPreInitProcess + [MetaTags(MetaTags.HIDDEN), MetaColor(MetaColor.Gray)] + public class PipelineDebugSystem : IEcsPreInit, IEcsPipelineMember { + public EcsPipeline Pipeline { get; set; } private string _monitorName; public PipelineDebugSystem(string monitorName = "Pipeline") { _monitorName = monitorName; } - void IEcsPreInitProcess.PreInit(EcsPipeline pipeline) + void IEcsPreInit.PreInit() { PipelineDebugMonitor monitor = new GameObject(EcsConsts.DEBUG_PREFIX + _monitorName).AddComponent(); monitor.source = this; - monitor.pipeline = pipeline; + monitor.pipeline = Pipeline; monitor.monitorName = _monitorName; PipelineProcessesDebugMonitor processesMonitor = new GameObject(EcsConsts.DEBUG_PREFIX + "Processes Matrix").AddComponent(); processesMonitor.transform.parent = monitor.transform; processesMonitor.source = this; - processesMonitor.pipeline = pipeline; + processesMonitor.pipeline = Pipeline; processesMonitor.monitorName = "Processes Matrix"; //foreach (var item in pipeline.AllSystems) //Вырезано пока не сделаю TODO в SystemDebugMonitor @@ -46,295 +47,295 @@ namespace DCFApixels.DragonECS internal PipelineDebugSystem source; internal EcsPipeline pipeline; } +} + #if UNITY_EDITOR - namespace Editors +namespace DCFApixels.DragonECS.Unity.Editors +{ + using DCFApixels.DragonECS.RunnersCore; + using DCFApixels.DragonECS.Unity.Internal; + using System; + using System.Collections.Generic; + using UnityEditor; + + [CustomEditor(typeof(PipelineDebugMonitor))] + public class PipelineDebugMonitorEditor : Editor { - using DCFApixels.DragonECS.Internal; - using DCFApixels.DragonECS.RunnersCore; - using System; - using System.Collections.Generic; - using System.Linq; - using UnityEditor; + private MetaColorAttribute _fakeDebugColorAttribute = new MetaColorAttribute(190, 190, 190); + private Type _debugColorAttributeType = typeof(MetaColorAttribute); + private GUIStyle _headerStyle; + private GUIStyle _interfacesStyle; + private Color _interfaceColor = new Color(0.96f, 1f, 0.16f); + private PipelineDebugMonitor Target => (PipelineDebugMonitor)target; - [CustomEditor(typeof(PipelineDebugMonitor))] - public class PipelineDebugMonitorEditor : Editor + + private GUIStyle systemsListStyle; + + public override void OnInspectorGUI() { - private DebugColorAttribute _fakeDebugColorAttribute = new DebugColorAttribute(190, 190, 190); - private Type _debugColorAttributeType = typeof(DebugColorAttribute); - private GUIStyle _headerStyle; - private GUIStyle _interfacesStyle; - private Color _interfaceColor = new Color(0.96f, 1f, 0.16f); - private PipelineDebugMonitor Target => (PipelineDebugMonitor)target; + systemsListStyle = new GUIStyle(EditorStyles.miniLabel); + systemsListStyle.wordWrap = true; - - private GUIStyle systemsListStyle; - - public override void OnInspectorGUI() + if (Target.source == null) + return; + if (_headerStyle == null) { - systemsListStyle = new GUIStyle(EditorStyles.miniLabel); - systemsListStyle.wordWrap = true; - - if (Target.source == null) - return; - if (_headerStyle == null) - { - _headerStyle = new GUIStyle(EditorStyles.boldLabel); - _interfacesStyle = new GUIStyle(EditorStyles.miniLabel); - _interfacesStyle.hover.textColor = _interfaceColor; - _interfacesStyle.focused.textColor = _interfaceColor; - _interfacesStyle.active.textColor = _interfaceColor; - _interfacesStyle.normal.textColor = _interfaceColor; - _interfacesStyle.wordWrap = true; - _headerStyle.fontSize = 28; - } - - GUILayout.Label("[Systems]", _headerStyle); - - DebugMonitorPrefs.instance.IsShowInterfaces = EditorGUILayout.Toggle("Show Interfaces", DebugMonitorPrefs.instance.IsShowInterfaces); - DebugMonitorPrefs.instance.IsShowHidden = EditorGUILayout.Toggle("Show Hidden", DebugMonitorPrefs.instance.IsShowHidden); - - GUILayout.BeginVertical(); - foreach (var item in Target.pipeline.AllSystems) - { - DrawSystem(item); - } - GUILayout.EndVertical(); - - - GUILayout.Label("[Runners]", _headerStyle); - - GUILayout.BeginVertical(EcsEditor.GetStyle(Color.black, 0.2f)); - foreach (var item in Target.pipeline.AllRunners) - { - DrawRunner(item.Value); - } - GUILayout.EndVertical(); + _headerStyle = new GUIStyle(EditorStyles.boldLabel); + _interfacesStyle = new GUIStyle(EditorStyles.miniLabel); + _interfacesStyle.hover.textColor = _interfaceColor; + _interfacesStyle.focused.textColor = _interfaceColor; + _interfacesStyle.active.textColor = _interfaceColor; + _interfacesStyle.normal.textColor = _interfaceColor; + _interfacesStyle.wordWrap = true; + _headerStyle.fontSize = 28; } - private void DrawSystem(IEcsProcess system) + GUILayout.Label("[Systems]", _headerStyle); + + DebugMonitorPrefs.instance.IsShowInterfaces = EditorGUILayout.Toggle("Show Interfaces", DebugMonitorPrefs.instance.IsShowInterfaces); + DebugMonitorPrefs.instance.IsShowHidden = EditorGUILayout.Toggle("Show Hidden", DebugMonitorPrefs.instance.IsShowHidden); + + GUILayout.BeginVertical(); + foreach (var item in Target.pipeline.AllSystems) { - if (system is SystemsLayerMarkerSystem markerSystem) - { - GUILayout.EndVertical(); - GUILayout.BeginVertical(EcsEditor.GetStyle(Color.black, 0.2f)); - - GUILayout.BeginHorizontal(); - GUILayout.Label("<"); - GUILayout.Label($"{markerSystem.name}", EditorStyles.boldLabel); - GUILayout.Label(">", GUILayout.ExpandWidth(false)); - GUILayout.EndHorizontal(); - return; - } - - Type type = system.GetType(); - - if (CheckIsHidden(type)) - return; - - string name = EcsEditor.GetGenericName(type); - //Color color = (GetAttribute(type) ?? _fakeDebugColorAttribute).GetUnityColor(); - Color color = EcsDebugUtility.GetColor(type).ToUnityColor(); - - GUILayout.BeginVertical(EcsEditor.GetStyle(color, 0.2f)); - if (DebugMonitorPrefs.instance.IsShowInterfaces) - { - GUILayout.Label(string.Join(", ", type.GetInterfaces().Select(o => o.Name)), _interfacesStyle); - } - GUILayout.Label(name, EditorStyles.boldLabel); - GUILayout.EndVertical(); + DrawSystem(item); } + GUILayout.EndVertical(); - private void DrawRunner(IEcsRunner runner) + + GUILayout.Label("[Runners]", _headerStyle); + + GUILayout.BeginVertical(EcsEditor.GetStyle(Color.black, 0.2f)); + foreach (var item in Target.pipeline.AllRunners) { - Type type = runner.GetType(); - if (CheckIsHidden(type)) - return; - - //Color color = (GetAttribute(type) ?? _fakeDebugColorAttribute).GetUnityColor(); - Color color = EcsDebugUtility.GetColor(type).ToUnityColor(); - - GUILayout.BeginVertical(EcsEditor.GetStyle(color, 0.2f)); - GUILayout.Label(EcsEditor.GetGenericName(type), EditorStyles.boldLabel); - GUILayout.Label(string.Join(", ", runner.Targets.Cast().Select(o => o.GetType().Name)), systemsListStyle); - GUILayout.EndVertical(); - } - - private TAttribute GetAttribute(Type target) where TAttribute : Attribute - { - var result = target.GetCustomAttributes(_debugColorAttributeType, false); - if (result.Length > 0) - return (TAttribute)result[0]; - return null; - } - - private bool CheckIsHidden(Type target) - { - if (DebugMonitorPrefs.instance.IsShowHidden) - return false; - return target.GetCustomAttribute() != null; + DrawRunner(item.Value); } + GUILayout.EndVertical(); } - [CustomEditor(typeof(PipelineProcessesDebugMonitor))] - public class PipelineProcessesDebugMonitorEditor : Editor + private void DrawSystem(IEcsProcess system) { - private bool _isInit = false; - private List _processesList = new List(); - private Dictionary _processeIndexes = new Dictionary(); - - private PipelineProcessesDebugMonitor Target => (PipelineProcessesDebugMonitor)target; - private Type systemInterfaceType = typeof(IEcsProcess); - - private IEcsProcess[] _systems; - private void Init() + if (system is SystemsLayerMarkerSystem markerSystem) { - if (_isInit) - return; - bool showHidden = DebugMonitorPrefs.instance.IsShowHidden; - _processesList.Clear(); - _processeIndexes.Clear(); - if (showHidden) - _systems = Target.pipeline.AllSystems.Where(o => o is SystemsLayerMarkerSystem == false).ToArray(); - else - _systems = Target.pipeline.AllSystems.Where(o => o.GetType().GetCustomAttribute() == null).ToArray(); + GUILayout.EndVertical(); + GUILayout.BeginVertical(EcsEditor.GetStyle(Color.black, 0.2f)); - int i = 0; - foreach (var system in _systems) - { - foreach (var intr in system.GetType().GetInterfaces()) - { - if (systemInterfaceType.IsAssignableFrom(intr) && systemInterfaceType != intr && (showHidden || intr.GetCustomAttribute() == null)) - { - ProcessData data; - if (!_processeIndexes.TryGetValue(intr, out int index)) - { - index = _processesList.Count; - _processeIndexes.Add(intr, index); - - data = new ProcessData(); - _processesList.Add(data); - - data.name = EcsEditor.GetGenericName(intr); - data.interfaceType = intr; - data.systemsBitMask = new BitMask(_systems.Length); - } - data = _processesList[index]; - data.systemsBitMask[i] = true; - } - } - i++; - } - - _isInit = true; - } - private Vector2 _position; - private Vector2 _cellsize = new Vector2(EditorGUIUtility.singleLineHeight, EditorGUIUtility.singleLineHeight); - private Vector2 _nameCellSize = new Vector2(200f, 200f); - - public override void OnInspectorGUI() - { - EditorGUI.BeginChangeCheck(); - DebugMonitorPrefs.instance.IsShowHidden = EditorGUILayout.Toggle("Show Hidden", DebugMonitorPrefs.instance.IsShowHidden); - if (EditorGUI.EndChangeCheck()) - { - _isInit = false; - } - - Init(); - - Rect rect; - Rect lineRect; - GUILayout.Label("", GUILayout.ExpandWidth(true), GUILayout.Height(400f)); - rect = GUILayoutUtility.GetLastRect(); - - rect.height = 400f; - - - Rect rectView = new Rect(0f, 0f, _nameCellSize.x + _cellsize.x * _processesList.Count, _nameCellSize.y + _cellsize.y * _systems.Length); - _position = GUI.BeginScrollView(rect, _position, rectView, true, true); - - List systeNames = new List(); - - var blackStyle = EcsEditor.GetStyle(Color.black, 0.04f); - var whiteStyle = EcsEditor.GetStyle(Color.white, 0.04f); - GUIContent label = new GUIContent(); - - - Vector2 pivod = _nameCellSize; - rect = new Rect(); - rect.y = _nameCellSize.y; - rect.width = _nameCellSize.x; - rect.height = _cellsize.x; - rect.y -= _cellsize.y; - for (int i = 0; i < _processesList.Count; i++) - { - lineRect = rect; - lineRect.y = 0f; - lineRect.x = _nameCellSize.x + _cellsize.x * i; - lineRect.width = _cellsize.x; - lineRect.height = rectView.height; - GUI.Label(lineRect, "", i % 2 == 1 ? whiteStyle : blackStyle); - - GUIUtility.RotateAroundPivot(90, pivod); - //GUIContent label = new GUIContent(_processesList[i].name, "." + _processesList[i].name); - label.text = _processesList[i].name; - label.tooltip = "." + _processesList[i].name; - GUI.Label(rect, label, EditorStyles.miniBoldLabel); - GUIUtility.RotateAroundPivot(-90, pivod); - - pivod.x += _cellsize.x; - rect.x += _cellsize.x; - } - - //GUIUtility.RotateAroundPivot(-90, _nameCellSize); - rect = new Rect(); - rect.y = _nameCellSize.y; - rect.width = _nameCellSize.x; - rect.height = _cellsize.x; - for (int i = 0; i < _systems.Length; i++) - { - string name = EcsEditor.GetGenericName(_systems[i].GetType()); - systeNames.Add(name); - - lineRect = rect; - lineRect.width = rectView.width; - GUI.Label(lineRect, "", i % 2 == 1 ? whiteStyle : blackStyle); - - // GUIContent label = new GUIContent(name, i + " " + name); - label.text = name; - label.tooltip = i + " " + name; - GUI.Label(rect, label, EditorStyles.miniBoldLabel); - rect.y += _cellsize.y; - } - - for (int x = 0; x < _processesList.Count; x++) - { - var process = _processesList[x]; - for (int y = 0; y < _systems.Length; y++) - { - string systemName = systeNames[x]; - rect = new Rect(x * _cellsize.x + _nameCellSize.x, y * _cellsize.y + _nameCellSize.y, _cellsize.x, _cellsize.y); - bool flag = process.systemsBitMask[y]; - string labeltext = flag ? "^" : " "; - label.text = labeltext; - label.tooltip = $"{process.name}-{systemName}"; - GUI.Label(rect, label); - //GUI.Label(rect, lable, flag ? whiteStyle : blackStyle); - // GUI.Label(rect, label, EditorStyles.helpBox); - } - } - - GUI.EndScrollView(); + GUILayout.BeginHorizontal(); + GUILayout.Label("<"); + GUILayout.Label($"{markerSystem.name}", EditorStyles.boldLabel); + GUILayout.Label(">", GUILayout.ExpandWidth(false)); + GUILayout.EndHorizontal(); + return; } - private class ProcessData + Type type = system.GetType(); + + if (CheckIsHidden(type)) + return; + + string name = EcsEditor.GetGenericName(type); + //Color color = (GetAttribute(type) ?? _fakeDebugColorAttribute).GetUnityColor(); + Color color = EcsDebugUtility.GetColor(type).ToUnityColor(); + + GUILayout.BeginVertical(EcsEditor.GetStyle(color, 0.2f)); + if (DebugMonitorPrefs.instance.IsShowInterfaces) { - public Type interfaceType; - public string name; - public BitMask systemsBitMask; + GUILayout.Label(string.Join(", ", type.GetInterfaces().Select(o => o.Name)), _interfacesStyle); } + GUILayout.Label(name, EditorStyles.boldLabel); + GUILayout.EndVertical(); + } + + private void DrawRunner(IEcsRunner runner) + { + Type type = runner.GetType(); + if (CheckIsHidden(type)) + return; + + //Color color = (GetAttribute(type) ?? _fakeDebugColorAttribute).GetUnityColor(); + Color color = EcsDebugUtility.GetColor(type).ToUnityColor(); + + GUILayout.BeginVertical(EcsEditor.GetStyle(color, 0.2f)); + GUILayout.Label(EcsEditor.GetGenericName(type), EditorStyles.boldLabel); + GUILayout.Label(string.Join(", ", runner.ProcessRaw.Cast().Select(o => o.GetType().Name)), systemsListStyle); + GUILayout.EndVertical(); + } + + private TAttribute GetAttribute(Type target) where TAttribute : Attribute + { + var result = target.GetCustomAttributes(_debugColorAttributeType, false); + if (result.Length > 0) + return (TAttribute)result[0]; + return null; + } + + private bool CheckIsHidden(Type target) + { + if (DebugMonitorPrefs.instance.IsShowHidden) + return false; + return target.GetCustomAttribute() != null; + } + } + + [CustomEditor(typeof(PipelineProcessesDebugMonitor))] + public class PipelineProcessesDebugMonitorEditor : Editor + { + private bool _isInit = false; + private List _processesList = new List(); + private Dictionary _processeIndexes = new Dictionary(); + + private PipelineProcessesDebugMonitor Target => (PipelineProcessesDebugMonitor)target; + private Type systemInterfaceType = typeof(IEcsProcess); + + private IEcsProcess[] _systems; + private void Init() + { + if (_isInit) + return; + bool showHidden = DebugMonitorPrefs.instance.IsShowHidden; + _processesList.Clear(); + _processeIndexes.Clear(); + if (showHidden) + _systems = Target.pipeline.AllSystems.Where(o => o is SystemsLayerMarkerSystem == false).ToArray(); + else + _systems = Target.pipeline.AllSystems.Where(o => o.GetType().GetCustomAttribute() == null).ToArray(); + + int i = 0; + foreach (var system in _systems) + { + foreach (var intr in system.GetType().GetInterfaces()) + { + if (systemInterfaceType.IsAssignableFrom(intr) && systemInterfaceType != intr && (showHidden || intr.GetCustomAttribute() == null)) + { + ProcessData data; + if (!_processeIndexes.TryGetValue(intr, out int index)) + { + index = _processesList.Count; + _processeIndexes.Add(intr, index); + + data = new ProcessData(); + _processesList.Add(data); + + data.name = EcsEditor.GetGenericName(intr); + data.interfaceType = intr; + data.systemsBitMask = new BitMask(_systems.Length); + } + data = _processesList[index]; + data.systemsBitMask[i] = true; + } + } + i++; + } + + _isInit = true; + } + private Vector2 _position; + private Vector2 _cellsize = new Vector2(EditorGUIUtility.singleLineHeight, EditorGUIUtility.singleLineHeight); + private Vector2 _nameCellSize = new Vector2(200f, 200f); + + public override void OnInspectorGUI() + { + EditorGUI.BeginChangeCheck(); + DebugMonitorPrefs.instance.IsShowHidden = EditorGUILayout.Toggle("Show Hidden", DebugMonitorPrefs.instance.IsShowHidden); + if (EditorGUI.EndChangeCheck()) + { + _isInit = false; + } + + Init(); + + Rect rect; + Rect lineRect; + GUILayout.Label("", GUILayout.ExpandWidth(true), GUILayout.Height(400f)); + rect = GUILayoutUtility.GetLastRect(); + + rect.height = 400f; + + + Rect rectView = new Rect(0f, 0f, _nameCellSize.x + _cellsize.x * _processesList.Count, _nameCellSize.y + _cellsize.y * _systems.Length); + _position = GUI.BeginScrollView(rect, _position, rectView, true, true); + + List systeNames = new List(); + + var blackStyle = EcsEditor.GetStyle(Color.black, 0.04f); + var whiteStyle = EcsEditor.GetStyle(Color.white, 0.04f); + GUIContent label = new GUIContent(); + + + Vector2 pivod = _nameCellSize; + rect = new Rect(); + rect.y = _nameCellSize.y; + rect.width = _nameCellSize.x; + rect.height = _cellsize.x; + rect.y -= _cellsize.y; + for (int i = 0; i < _processesList.Count; i++) + { + lineRect = rect; + lineRect.y = 0f; + lineRect.x = _nameCellSize.x + _cellsize.x * i; + lineRect.width = _cellsize.x; + lineRect.height = rectView.height; + GUI.Label(lineRect, "", i % 2 == 1 ? whiteStyle : blackStyle); + + GUIUtility.RotateAroundPivot(90, pivod); + //GUIContent label = new GUIContent(_processesList[i].name, "." + _processesList[i].name); + label.text = _processesList[i].name; + label.tooltip = "." + _processesList[i].name; + GUI.Label(rect, label, EditorStyles.miniBoldLabel); + GUIUtility.RotateAroundPivot(-90, pivod); + + pivod.x += _cellsize.x; + rect.x += _cellsize.x; + } + + //GUIUtility.RotateAroundPivot(-90, _nameCellSize); + rect = new Rect(); + rect.y = _nameCellSize.y; + rect.width = _nameCellSize.x; + rect.height = _cellsize.x; + for (int i = 0; i < _systems.Length; i++) + { + string name = EcsEditor.GetGenericName(_systems[i].GetType()); + systeNames.Add(name); + + lineRect = rect; + lineRect.width = rectView.width; + GUI.Label(lineRect, "", i % 2 == 1 ? whiteStyle : blackStyle); + + // GUIContent label = new GUIContent(name, i + " " + name); + label.text = name; + label.tooltip = i + " " + name; + GUI.Label(rect, label, EditorStyles.miniBoldLabel); + rect.y += _cellsize.y; + } + + for (int x = 0; x < _processesList.Count; x++) + { + var process = _processesList[x]; + for (int y = 0; y < _systems.Length; y++) + { + string systemName = systeNames[x]; + rect = new Rect(x * _cellsize.x + _nameCellSize.x, y * _cellsize.y + _nameCellSize.y, _cellsize.x, _cellsize.y); + bool flag = process.systemsBitMask[y]; + string labeltext = flag ? "^" : " "; + label.text = labeltext; + label.tooltip = $"{process.name}-{systemName}"; + GUI.Label(rect, label); + //GUI.Label(rect, lable, flag ? whiteStyle : blackStyle); + // GUI.Label(rect, label, EditorStyles.helpBox); + } + } + + GUI.EndScrollView(); + } + + private class ProcessData + { + public Type interfaceType; + public string name; + public BitMask systemsBitMask; } } -#endif } +#endif diff --git a/src/Debug/Systems/WorldDebugSystem.cs b/src/Debug/Systems/WorldDebugSystem.cs index fee56cb..003ed6e 100644 --- a/src/Debug/Systems/WorldDebugSystem.cs +++ b/src/Debug/Systems/WorldDebugSystem.cs @@ -1,10 +1,11 @@ using DCFApixels.DragonECS.Unity.Debug; using UnityEngine; +using System.Linq; namespace DCFApixels.DragonECS { - [DebugHide, DebugColor(DebugColor.Gray)] - public class WorldDebugSystem : IEcsRunProcess + [MetaTags(MetaTags.HIDDEN), MetaColor(MetaColor.Gray)] + public class WorldDebugSystem : IEcsRun { private string _monitorName; private EcsWorld _ecsWorld; @@ -27,7 +28,7 @@ namespace DCFApixels.DragonECS poolsmonitor.monitorName = "pools"; } - public void Run(EcsPipeline pipeline) + public void Run() { } } @@ -65,116 +66,112 @@ namespace DCFApixels.DragonECS internal WorldDebugSystem source; internal EcsWorld world; } +} #if UNITY_EDITOR - namespace Editors +namespace DCFApixels.DragonECS.Unity.Editors +{ + using UnityEditor; + + [CustomEditor(typeof(WorldPoolsMonitor))] + public class WorldPoolsMonitorEditor : Editor { - using System.Linq; - using System.Reflection; - using UnityEditor; + private static Vector2 _poolBlockMinSize = new Vector2(80, 160); + private static Vector2 _poolProgressBasrSize = _poolBlockMinSize * new Vector2(1f, 0.8f); - [CustomEditor(typeof(WorldPoolsMonitor))] - public class WorldPoolsMonitorEditor : Editor + private WorldPoolsMonitor Target => (WorldPoolsMonitor)target; + + private Vector2 _scroll; + + public override void OnInspectorGUI() { - private static Vector2 _poolBlockMinSize = new Vector2(80, 160); - private static Vector2 _poolProgressBasrSize = _poolBlockMinSize * new Vector2(1f, 0.8f); + _scroll = GUILayout.BeginScrollView(_scroll, GUILayout.Height(800f)); - private WorldPoolsMonitor Target => (WorldPoolsMonitor)target; + var pools = Target.world.AllPools.ToArray().Where(o => !o.IsNullOrDummy()).OfType(); - private Vector2 _scroll; + GUILayout.Label("", GUILayout.ExpandWidth(true)); - public override void OnInspectorGUI() + 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) { - _scroll = GUILayout.BeginScrollView(_scroll, GUILayout.Height(800f)); - - var pools = Target.world.AllPools.ToArray().Where(o => !o.IsNullOrDummy()).OfType(); - - 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) { - if (++x >= widthCount) - { - x = 0; - y++; - } - - DrawPoolBlock(pool, new Rect(newPoolBlockSize.x * x, newPoolBlockSize.y * y, newPoolBlockSize.x, newPoolBlockSize.y)); + x = 0; + y++; } - GUILayout.EndScrollView(); + + DrawPoolBlock(pool, new Rect(newPoolBlockSize.x * x, newPoolBlockSize.y * y, newPoolBlockSize.x, newPoolBlockSize.y)); } + GUILayout.EndScrollView(); + } + /// : new Color(0.3f, 1f, 0f, 1f); - private void DrawPoolBlock(IEcsPool pool, Rect position) - { - int count = pool.Count; - int capacity = pool.Capacity < 0 ? count : pool.Capacity; + private void DrawPoolBlock(IEcsPool pool, Rect position) + { + var meta = pool.GetMeta(); - Color defaultContentColor = GUI.contentColor; - GUI.contentColor = Color.black * 0.925f; + int count = pool.Count; + int capacity = pool.Capacity < 0 ? count : pool.Capacity; - position = AddMargin(position, 1f, 1f); + Color defaultContentColor = GUI.contentColor; + GUI.contentColor = Color.black * 0.925f; - EditorGUI.DrawRect(position, Color.black * 0.16f); + position = AddMargin(position, 1f, 1f); - Rect progressBar = new Rect(Vector2.zero, _poolProgressBasrSize); - progressBar.width = position.width; - progressBar.center = position.center - Vector2.up * _poolBlockMinSize.y * 0.09f; + 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.ComponentType.GetCustomAttribute(); - if (debugColor != null) - { - mainColor = debugColor.GetUnityColor(); - } - Color backgroundColor = mainColor * 0.3f + Color.white * 0.2f; + Color mainColor = meta.Color.ToUnityColor(); + Color backgroundColor = mainColor * 0.3f + Color.white * 0.2f; - EditorGUI.DrawRect(progressBar, backgroundColor); + EditorGUI.DrawRect(progressBar, backgroundColor); - progressBar.yMin = progressBar.yMax - ((float)count / capacity) * progressBar.height; + progressBar.yMin = progressBar.yMax - ((float)count / capacity) * progressBar.height; - GUIStyle textStyle0 = new GUIStyle(EditorStyles.miniBoldLabel); - textStyle0.alignment = TextAnchor.MiddleCenter; + GUIStyle textStyle0 = new GUIStyle(EditorStyles.miniBoldLabel); + textStyle0.alignment = TextAnchor.MiddleCenter; - Color foregroundColor = mainColor; - EditorGUI.DrawRect(progressBar, foregroundColor); - GUI.Label(progressBar, count.ToString(), textStyle0); + Color foregroundColor = mainColor; + EditorGUI.DrawRect(progressBar, foregroundColor); + GUI.Label(progressBar, count.ToString(), textStyle0); - GUIStyle textStyle1 = new GUIStyle(EditorStyles.miniBoldLabel); - textStyle1.alignment = TextAnchor.UpperCenter; - GUI.Label(AddMargin(position, 3f, 3f), "Total\r\n" + capacity, textStyle1); + GUIStyle textStyle1 = new GUIStyle(EditorStyles.miniBoldLabel); + textStyle1.alignment = TextAnchor.UpperCenter; + GUI.Label(AddMargin(position, 3f, 3f), "Total\r\n" + capacity, textStyle1); - GUI.contentColor = defaultContentColor; - GUIStyle textStyle2 = new GUIStyle(EditorStyles.miniBoldLabel); - textStyle2.wordWrap = true; - textStyle2.alignment = TextAnchor.LowerCenter; - string name = EcsEditor.GetGenericName(pool.ComponentType); - GUIContent label = new GUIContent(name, $"{name} e:{count}"); - GUI.Label(AddMargin(position, -10f, 3f), label, textStyle2); + GUI.contentColor = defaultContentColor; + GUIStyle textStyle2 = new GUIStyle(EditorStyles.miniBoldLabel); + textStyle2.wordWrap = true; + textStyle2.alignment = TextAnchor.LowerCenter; + string name = EcsEditor.GetGenericName(pool.ComponentType); + GUIContent label = new GUIContent(name, $"{name} e:{count}"); + GUI.Label(AddMargin(position, -10f, 3f), label, 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; - } + 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 } +#endif + diff --git a/src/EntityTemplate/Editor.meta b/src/EntityTemplate/Editor.meta new file mode 100644 index 0000000..9b140d9 --- /dev/null +++ b/src/EntityTemplate/Editor.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d8c6da13649cc094e80f3ec624bad02b +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/EntityTemplate/Editor/EntityTemplateEditor.cs b/src/EntityTemplate/Editor/EntityTemplateEditor.cs new file mode 100644 index 0000000..4f31b38 --- /dev/null +++ b/src/EntityTemplate/Editor/EntityTemplateEditor.cs @@ -0,0 +1,251 @@ +using DCFApixels.DragonECS.Unity.Internal; +using System; +using System.Reflection; + +#if UNITY_EDITOR +namespace DCFApixels.DragonECS.Unity.Editors +{ + using UnityEditor; + using UnityEngine; + + public abstract class EntityTemplateEditorBase : Editor + { + private static readonly Rect RemoveButtonRect = new Rect(0f, 0f, 15f, 15f); + private static readonly Rect TooltipIconRect = new Rect(0f, 0f, 15f, 15f); + + private GUIStyle removeButtonStyle; + private GenericMenu genericMenu; + private bool _isInit = false; + + #region Init + private void Init() + { + if (genericMenu == null) + _isInit = false; + if (_isInit) + return; + + var tmpstylebase = EcsEditor.GetStyle(new Color(0.9f, 0f, 0.22f), 0.5f); + var tmpStyle = EcsEditor.GetStyle(new Color(1f, 0.5f, 0.7f), 0.5f); + + removeButtonStyle = new GUIStyle(EditorStyles.linkLabel); + removeButtonStyle.alignment = TextAnchor.MiddleCenter; + + removeButtonStyle.normal = tmpstylebase.normal; + removeButtonStyle.hover = tmpStyle.normal; + removeButtonStyle.active = tmpStyle.normal; + removeButtonStyle.focused = tmpStyle.normal; + + removeButtonStyle.padding = new RectOffset(0, 0, 0, 0); + removeButtonStyle.margin = new RectOffset(0, 0, 0, 0); + removeButtonStyle.border = new RectOffset(0, 0, 0, 0); + + genericMenu = new GenericMenu(); + + var dummies = ComponentTemplateTypeCache.Dummies; + foreach (var dummy in dummies) + { + string name = dummy.Name; + string description = dummy.Description; + if (string.IsNullOrEmpty(description) == false) + { + name = $"{name} {EcsUnityConsts.INFO_MARK}"; + } + genericMenu.AddItem(new GUIContent(name, description), false, OnAddComponent, dummy); + } + + _isInit = true; + } + #endregion + + #region Add/Remove + private void OnAddComponent(object obj) + { + Type componentType = obj.GetType(); + if (this.target is ITemplateInternal target) + { + SerializedProperty componentsProp = serializedObject.FindProperty(target.ComponentsPropertyName); + for (int i = 0; i < componentsProp.arraySize; i++) + { + if (componentsProp.GetArrayElementAtIndex(i).managedReferenceValue.GetType() == componentType) + return; + } + + componentsProp.InsertArrayElementAtIndex(0); + + componentsProp.GetArrayElementAtIndex(0).managedReferenceValue = ((IComponentTemplate)obj).Clone(); + + serializedObject.ApplyModifiedProperties(); + EditorUtility.SetDirty(this.target); + } + } + private void OnRemoveComponentAt(int index) + { + if (this.target is ITemplateInternal target) + { + SerializedProperty componentsProp = serializedObject.FindProperty(target.ComponentsPropertyName); + componentsProp.DeleteArrayElementAtIndex(index); + serializedObject.ApplyModifiedProperties(); + EditorUtility.SetDirty(this.target); + } + } + #endregion + + protected void Draw(ITemplateInternal target) + { + Init(); + SerializedProperty componentsProp = serializedObject.FindProperty(target.ComponentsPropertyName); + if (componentsProp == null) + return; + + DrawTop(target); + for (int i = 0; i < componentsProp.arraySize; i++) + { + DrawComponentData(componentsProp.GetArrayElementAtIndex(i), i); + GUILayout.Space(EditorGUIUtility.standardVerticalSpacing * 2); + } + DrawFooter(target); + } + private void DrawTop(ITemplateInternal target) + { + if (GUILayout.Button("Add Component", GUILayout.Height(24f))) + { + Init(); + genericMenu.ShowAsContext(); + } + } + private void DrawFooter(ITemplateInternal target) + { + if (GUILayout.Button("Clear", GUILayout.Height(24f))) + { + Init(); + serializedObject.FindProperty(target.ComponentsPropertyName).ClearArray(); + serializedObject.ApplyModifiedProperties(); + } + } + private void DrawComponentData(SerializedProperty componentRefProp, int index) + { + IComponentTemplate template = componentRefProp.managedReferenceValue as IComponentTemplate; + if (template == null) + { + DrawDamagedComponent(componentRefProp, index); + return; + } + + if (componentRefProp.managedReferenceValue == null) + { + DrawDamagedComponent(componentRefProp, index); + return; + } + + Type initializerType; + Type componentType; + SerializedProperty componentProperty = componentRefProp; + ComponentTemplateBase customInitializer = componentProperty.managedReferenceValue as ComponentTemplateBase; + if (customInitializer != null) + { + componentProperty = componentRefProp.FindPropertyRelative("component"); + initializerType = customInitializer.Type; + componentType = customInitializer.GetType().GetField("component", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FieldType; + } + else + { + initializerType = componentProperty.managedReferenceValue.GetType(); + componentType = initializerType; + } + + string name = template.Name; + string description = template.Description; + Color panelColor = template.Color; + + GUILayout.BeginHorizontal(); + + GUILayout.BeginVertical(EcsEditor.GetStyle(panelColor, 0.22f)); + + EditorGUI.BeginChangeCheck(); + GUIContent label = new GUIContent(name); + if (componentType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Length <= 0) + { + GUILayout.Label(label); + } + else + { + EditorGUILayout.PropertyField(componentProperty, label, true); + } + if (EditorGUI.EndChangeCheck()) + { + componentProperty.serializedObject.ApplyModifiedProperties(); + EditorUtility.SetDirty(componentProperty.serializedObject.targetObject); + } + + Rect lastrect = GUILayoutUtility.GetLastRect(); + Rect removeButtonRect = RemoveButtonRect; + removeButtonRect.center = new Vector2(lastrect.xMax + removeButtonRect.width, lastrect.yMin + removeButtonRect.height / 2f); + + GUILayout.EndVertical(); + Rect lineRect = GUILayoutUtility.GetLastRect(); + lineRect.y = lineRect.yMax; + lineRect.height = 3f; + Color rectColor = panelColor; + rectColor.a = 0.34f; + EditorGUI.DrawRect(lineRect, rectColor); + GUILayout.Label("", GUILayout.Width(removeButtonRect.width)); + + if (GUI.Button(removeButtonRect, "x", removeButtonStyle)) + OnRemoveComponentAt(index); + + if (!string.IsNullOrEmpty(description)) + { + Rect tooltipIconRect = TooltipIconRect; + tooltipIconRect.center = new Vector2(lastrect.xMax - removeButtonRect.width / 2f, lastrect.yMin + removeButtonRect.height / 2f); + GUIContent descriptionLabel = new GUIContent(EcsUnityConsts.INFO_MARK, description); + GUI.Label(tooltipIconRect, descriptionLabel, EditorStyles.boldLabel); + } + GUILayout.EndHorizontal(); + } + + private void DrawDamagedComponent(SerializedProperty componentRefProp, int index) + { + GUILayout.BeginHorizontal(); + + EditorGUILayout.HelpBox($"Damaged component. If the problem occurred after renaming a component or initializer. use MovedFromAttrubute", MessageType.Warning); + + Rect lastrect = GUILayoutUtility.GetLastRect(); + Rect removeButtonRect = RemoveButtonRect; + removeButtonRect.center = new Vector2(lastrect.xMax + removeButtonRect.width, lastrect.yMin + removeButtonRect.height / 2f); + + GUILayout.Label("", GUILayout.Width(removeButtonRect.width)); + if (GUI.Button(removeButtonRect, "x", removeButtonStyle)) + OnRemoveComponentAt(index); + + GUILayout.EndHorizontal(); + } + + public string GetLastPathComponent(string input) + { + int lastSlashIndex = input.LastIndexOfAny(new char[] { '/', '\\' }); + if (lastSlashIndex == -1) + return input; + else + return input.Substring(lastSlashIndex + 1); + } + } + + [CustomEditor(typeof(ScriptableEntityTemplate), true)] + public class EntityTemplatePresetEditor : EntityTemplateEditorBase + { + public override void OnInspectorGUI() + { + Draw((ITemplateInternal)target); + } + } + [CustomEditor(typeof(MonoEntityTemplate), true)] + public class EntityTemplateEditor : EntityTemplateEditorBase + { + public override void OnInspectorGUI() + { + Draw((ITemplateInternal)target); + } + } +} +#endif diff --git a/src/EntityTemplate/EntityTemplateEditor.cs.meta b/src/EntityTemplate/Editor/EntityTemplateEditor.cs.meta similarity index 100% rename from src/EntityTemplate/EntityTemplateEditor.cs.meta rename to src/EntityTemplate/Editor/EntityTemplateEditor.cs.meta diff --git a/src/EntityTemplate/EntityTemplate.cs b/src/EntityTemplate/EntityTemplate.cs deleted file mode 100644 index 26cc481..0000000 --- a/src/EntityTemplate/EntityTemplate.cs +++ /dev/null @@ -1,49 +0,0 @@ -using UnityEngine; - -namespace DCFApixels.DragonECS -{ - public class EntityTemplate : MonoBehaviour, ITemplateInternal - { - [SerializeReference] - private ITemplateComponent[] _components; - string ITemplateInternal.ComponentsPropertyName => nameof(_components); - - public void Apply(EcsWorld world, int entityID) - { - foreach (var item in _components) - item.Add(world, entityID); - } - private void OnValidate() - { - if (_components == null) return; - foreach (var item in _components) - { - if (item is ITemplateComponentOnValidate g) - g.OnValidate(gameObject); - } - - } - private void OnDrawGizmos() - { - if (_components == null) return; - foreach (var item in _components) - { - if (item is ITemplateComponentGizmos g) - g.OnGizmos(transform, ITemplateComponentGizmos.Mode.Always); - } - } - private void OnDrawGizmosSelected() - { - if (_components == null) return; - foreach (var item in _components) - { - if (item is ITemplateComponentGizmos g) - g.OnGizmos(transform, ITemplateComponentGizmos.Mode.Selected); - } - } - public void Clear() - { - _components = new ITemplateComponent[0]; - } - } -} diff --git a/src/EntityTemplate/EntityTemplateEditor.cs b/src/EntityTemplate/EntityTemplateEditor.cs deleted file mode 100644 index 95f379b..0000000 --- a/src/EntityTemplate/EntityTemplateEditor.cs +++ /dev/null @@ -1,260 +0,0 @@ -using System; -using System.Reflection; - -namespace DCFApixels.DragonECS -{ -#if UNITY_EDITOR - namespace Editors - { - using UnityEditor; - using UnityEngine; - - public abstract class EntityTemplateEditorBase : Editor - { - private static readonly Rect RemoveButtonRect = new Rect(0f, 0f, 15f, 15f); - private static readonly Rect TooltipIconRect = new Rect(0f, 0f, 15f, 15f); - - private GUIStyle removeButtonStyle; - private GenericMenu genericMenu; - private bool _isInit = false; - - #region Init - private void Init() - { - if (genericMenu == null) - _isInit = false; - if (_isInit) - return; - - var tmpstylebase = EcsEditor.GetStyle(new Color(0.9f, 0f, 0.22f), 0.5f); - var tmpStyle = EcsEditor.GetStyle(new Color(1f, 0.5f, 0.7f), 0.5f); - - removeButtonStyle = new GUIStyle(EditorStyles.linkLabel); - removeButtonStyle.alignment = TextAnchor.MiddleCenter; - - removeButtonStyle.normal = tmpstylebase.normal; - removeButtonStyle.hover = tmpStyle.normal; - removeButtonStyle.active = tmpStyle.normal; - removeButtonStyle.focused = tmpStyle.normal; - - removeButtonStyle.padding = new RectOffset(0, 0, 0, 0); - removeButtonStyle.margin = new RectOffset(0, 0, 0, 0); - removeButtonStyle.border = new RectOffset(0, 0, 0, 0); - - genericMenu = new GenericMenu(); - - var dummies = TemplateBrowsableTypeCache.Dummies; - foreach (var dummy in dummies) - { - string name, description; - if (dummy is ITemplateComponentName browsableName) - name = browsableName.Name; - else - name = EcsEditor.GetName(dummy.GetType()); - - if (dummy is TemplateComponentInitializerBase initializer) - description = initializer.Description; - else - description = EcsEditor.GetDescription(dummy.GetType()); - - if (!string.IsNullOrEmpty(description)) - { - name = $"{name} {EcsUnityConsts.INFO_MARK}"; - } - - genericMenu.AddItem(new GUIContent(name, description), false, OnAddComponent, dummy); - } - - _isInit = true; - } - #endregion - - #region Add/Remove - private void OnAddComponent(object obj) - { - Type componentType = obj.GetType(); - if (this.target is ITemplateInternal target) - { - SerializedProperty componentsProp = serializedObject.FindProperty(target.ComponentsPropertyName); - for (int i = 0; i < componentsProp.arraySize; i++) - { - if (componentsProp.GetArrayElementAtIndex(i).managedReferenceValue.GetType() == componentType) - return; - } - - componentsProp.InsertArrayElementAtIndex(0); - - componentsProp.GetArrayElementAtIndex(0).managedReferenceValue = ((ITemplateComponent)obj).Clone(); - - serializedObject.ApplyModifiedProperties(); - EditorUtility.SetDirty(this.target); - } - } - private void OnRemoveComponentAt(int index) - { - if (this.target is ITemplateInternal target) - { - SerializedProperty componentsProp = serializedObject.FindProperty(target.ComponentsPropertyName); - componentsProp.DeleteArrayElementAtIndex(index); - serializedObject.ApplyModifiedProperties(); - EditorUtility.SetDirty(this.target); - } - } - #endregion - - protected void Draw(ITemplateInternal target) - { - Init(); - SerializedProperty componentsProp = serializedObject.FindProperty(target.ComponentsPropertyName); - if (componentsProp == null) - return; - - DrawTop(target); - for (int i = 0; i < componentsProp.arraySize; i++) - { - DrawComponentData(componentsProp.GetArrayElementAtIndex(i), i); - GUILayout.Space(EditorGUIUtility.standardVerticalSpacing * 2); - } - DrawFooter(target); - } - private void DrawTop(ITemplateInternal target) - { - if (GUILayout.Button("Add Component", GUILayout.Height(24f))) - { - Init(); - genericMenu.ShowAsContext(); - } - } - private void DrawFooter(ITemplateInternal target) - { - if (GUILayout.Button("Clear", GUILayout.Height(24f))) - { - Init(); - serializedObject.FindProperty(target.ComponentsPropertyName).ClearArray(); - serializedObject.ApplyModifiedProperties(); - } - } - private void DrawComponentData(SerializedProperty componentRefProp, int index) - { - ITemplateComponent browsable = componentRefProp.managedReferenceValue as ITemplateComponent; - if (browsable == null) - { - DrawDamagedComponent(componentRefProp, index); - return; - } - ITemplateComponentName browsableName = browsable as ITemplateComponentName; - - if (componentRefProp.managedReferenceValue == null) - { - DrawDamagedComponent(componentRefProp, index); - return; - } - - Type initializerType; - Type componentType; - SerializedProperty componentProperty = componentRefProp; - TemplateComponentInitializerBase customInitializer = componentProperty.managedReferenceValue as TemplateComponentInitializerBase; - if (customInitializer != null) - { - componentProperty = componentRefProp.FindPropertyRelative("component"); - initializerType = customInitializer.Type; - componentType = customInitializer.GetType().GetField("component", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FieldType; - } - else - { - initializerType = componentProperty.managedReferenceValue.GetType(); - componentType = initializerType; - } - - Type type = browsable.GetType(); - string name = browsableName == null ? type.Name : GetLastPathComponent(browsableName.Name); - string description = customInitializer != null ? customInitializer.Description : initializerType.GetCustomAttribute()?.description; - // Color panelColor = customInitializer != null ? customInitializer.Color : initializerType.GetCustomAttribute()?.GetUnityColor() ?? Color.black; - Color panelColor = customInitializer != null ? customInitializer.Color : EcsDebugUtility.GetColor(initializerType).ToUnityColor(); - - GUILayout.BeginHorizontal(); - - GUILayout.BeginVertical(EcsEditor.GetStyle(panelColor, 0.2f)); - - EditorGUI.BeginChangeCheck(); - GUIContent label = new GUIContent(name, $"{name} "); - if (componentType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Length <= 0) - { - GUILayout.Label(label); - } - else - { - EditorGUILayout.PropertyField(componentProperty, label, true); - } - if (EditorGUI.EndChangeCheck()) - { - componentProperty.serializedObject.ApplyModifiedProperties(); - EditorUtility.SetDirty(componentProperty.serializedObject.targetObject); - } - - Rect lastrect = GUILayoutUtility.GetLastRect(); - Rect removeButtonRect = RemoveButtonRect; - removeButtonRect.center = new Vector2(lastrect.xMax + removeButtonRect.width, lastrect.yMin + removeButtonRect.height / 2f); - - GUILayout.EndVertical(); - GUILayout.Label("", GUILayout.Width(removeButtonRect.width)); - - if (GUI.Button(removeButtonRect, "x", removeButtonStyle)) - OnRemoveComponentAt(index); - - if (!string.IsNullOrEmpty(description)) - { - Rect tooltipIconRect = TooltipIconRect; - tooltipIconRect.center = new Vector2(lastrect.xMax - removeButtonRect.width / 2f, lastrect.yMin + removeButtonRect.height / 2f); - GUIContent descriptionLabel = new GUIContent(EcsUnityConsts.INFO_MARK, description); - GUI.Label(tooltipIconRect, descriptionLabel, EditorStyles.boldLabel); - } - GUILayout.EndHorizontal(); - } - - private void DrawDamagedComponent(SerializedProperty componentRefProp, int index) - { - GUILayout.BeginHorizontal(); - - EditorGUILayout.HelpBox($"Damaged component. If the problem occurred after renaming a component or initializer. use MovedFromAttrubute", MessageType.Warning); - - Rect lastrect = GUILayoutUtility.GetLastRect(); - Rect removeButtonRect = RemoveButtonRect; - removeButtonRect.center = new Vector2(lastrect.xMax + removeButtonRect.width, lastrect.yMin + removeButtonRect.height / 2f); - - GUILayout.Label("", GUILayout.Width(removeButtonRect.width)); - if (GUI.Button(removeButtonRect, "x", removeButtonStyle)) - OnRemoveComponentAt(index); - - GUILayout.EndHorizontal(); - } - - public string GetLastPathComponent(string input) - { - int lastSlashIndex = input.LastIndexOfAny(new char[] { '/', '\\' }); - if (lastSlashIndex == -1) - return input; - else - return input.Substring(lastSlashIndex + 1); - } - } - - [CustomEditor(typeof(EntityTemplatePreset), true)] - public class EntityTemplatePresetEditor : EntityTemplateEditorBase - { - public override void OnInspectorGUI() - { - Draw((ITemplateInternal)target); - } - } - [CustomEditor(typeof(EntityTemplate), true)] - public class EntityTemplateEditor : EntityTemplateEditorBase - { - public override void OnInspectorGUI() - { - Draw((ITemplateInternal)target); - } - } - } -#endif -} diff --git a/src/EntityTemplate/EntityTemplatePreset.cs b/src/EntityTemplate/EntityTemplatePreset.cs deleted file mode 100644 index 2de34e3..0000000 --- a/src/EntityTemplate/EntityTemplatePreset.cs +++ /dev/null @@ -1,29 +0,0 @@ -using UnityEngine; - -namespace DCFApixels.DragonECS -{ - [CreateAssetMenu(fileName = "EntityTemplatePreset", menuName = EcsConsts.FRAMEWORK_NAME + "/EntityTemplatePreset", order = 1)] - public class EntityTemplatePreset : ScriptableObject, ITemplateInternal - { - [SerializeReference] - private ITemplateComponent[] _components; - string ITemplateInternal.ComponentsPropertyName => nameof(_components); - - //ITemplateBrowsable[] ITemplateInternal.Components - //{ - // get => _components; - // set => _components = value; - //} - - public void Apply(EcsWorld world, int entityID) - { - foreach (var item in _components) - item.Add(world, entityID); - } - - public void Clear() - { - _components = new ITemplateComponent[0]; - } - } -} diff --git a/src/EntityTemplate/ITemplate.cs b/src/EntityTemplate/ITemplate.cs deleted file mode 100644 index 9a45baa..0000000 --- a/src/EntityTemplate/ITemplate.cs +++ /dev/null @@ -1,23 +0,0 @@ -namespace DCFApixels.DragonECS -{ - public interface ITemplate - { - public void Apply(EcsWorld world, int entityID); - } - - public interface ITemplateInternal : ITemplate - { - // internal ITemplateBrowsable[] Components { get; set; } - internal string ComponentsPropertyName { get; } - } - - public static class ITemplateExt - { - public static int NewEntity(this ITemplate self, EcsWorld world) - { - int e = world.NewEmptyEntity(); - self.Apply(world, e); - return e; - } - } -} diff --git a/src/EntityTemplate/ITemplateNode.cs b/src/EntityTemplate/ITemplateNode.cs new file mode 100644 index 0000000..b2c9967 --- /dev/null +++ b/src/EntityTemplate/ITemplateNode.cs @@ -0,0 +1,57 @@ +namespace DCFApixels.DragonECS +{ + public interface ITemplateNode + { + void Apply(int worldID, int entityID); + } + public interface ITemplate : ITemplateNode + { + //void Add(ITemplateNode template); + //void Remove(ITemplateNode template); + } + + public interface ITemplateInternal : ITemplate + { + string ComponentsPropertyName { get; } + //EntityTemplateInheritanceMatrix InheritanceMatrix { get; } + } + + public static class ITemplateExtensions + { + public static int NewEntity(this EcsWorld world, ITemplateNode template) + { + int e = world.NewEntity(); + template.Apply(world.id, e); + return e; + } + public static entlong NewEntityLong(this EcsWorld world, ITemplateNode template) + { + entlong e = world.NewEntityLong(); + template.Apply(world.id, e.ID); + return e; + } + public static entlong NewEntityWithGameObject(this EcsWorld world, ITemplateNode template, string name = "Entity", GameObjectIcon icon = GameObjectIcon.NONE) + { + entlong e = world.NewEntityWithGameObject(name, icon); + template.Apply(world.id, e.ID); + return e; + } + } + + //[Serializable] + //public class EntityTemplateInheritanceMatrix + //{ + // [SerializeReference] + // private ITemplateNode[] _components; + // + // #region Methods + // public void Apply(int worldID, int entityID) + // { + // foreach (var item in _components) + // { + // item.Apply(worldID, entityID); + // } + // } + // #endregion + //} +} diff --git a/src/EntityTemplate/ITemplate.cs.meta b/src/EntityTemplate/ITemplateNode.cs.meta similarity index 100% rename from src/EntityTemplate/ITemplate.cs.meta rename to src/EntityTemplate/ITemplateNode.cs.meta diff --git a/src/EntityTemplate/TemplateComponent.cs b/src/EntityTemplate/TemplateComponent.cs deleted file mode 100644 index 54bb644..0000000 --- a/src/EntityTemplate/TemplateComponent.cs +++ /dev/null @@ -1,151 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using UnityEngine; - -namespace DCFApixels.DragonECS -{ - public interface ITemplateComponent - { - public void Add(EcsWorld w, int e); - } - public interface ITemplateComponentName : ITemplateComponent - { - public string Name { get; } - } - public interface ITemplateComponentGizmos - { - public void OnGizmos(Transform transform, Mode mode); - public enum Mode - { - Always, - Selected - } - } - public interface ITemplateComponentOnValidate - { - public void OnValidate(GameObject gameObject); - } - - [Serializable] - public abstract class TemplateComponentInitializerBase - { - public virtual string Name => string.Empty; - public virtual Color Color => Color.black; - public virtual string Description => string.Empty; - public abstract Type Type { get; } - - internal abstract object ComponentRef { get; } - - #region Get meta - internal static Color GetColor(Type type) - { - //var atr = type.GetCustomAttribute(); - //if (atr == null) return Color.black; - //return atr.GetUnityColor(); - return EcsDebugUtility.GetColor(type).ToUnityColor(); - } - internal static string GetName(Type type) - { - string friendlyName = type.Name; - if (type.IsGenericType) - { - int iBacktick = friendlyName.IndexOf('`'); - if (iBacktick > 0) - friendlyName = friendlyName.Remove(iBacktick); - - friendlyName += "/" + friendlyName; - friendlyName += "<"; - Type[] typeParameters = type.GetGenericArguments(); - for (int i = 0; i < typeParameters.Length; ++i) - { - string typeParamName = GetName(typeParameters[i]); - friendlyName += (i == 0 ? typeParamName : "," + typeParamName); - } - friendlyName += ">"; - } - return friendlyName; - } - - internal static string GetDescription(Type type) - { - var atr = type.GetCustomAttribute(); - if (atr == null) return string.Empty; - return atr.description; - } - #endregion - } - [Serializable] - public abstract class TemplateComponentInitializer : TemplateComponentInitializerBase, ITemplateComponentName, ITemplateComponentGizmos, ITemplateComponentOnValidate - { - private static string _autoname = GetName(typeof(T)); - private static Color _autoColor = GetColor(typeof(T)); - private static string _autoDescription = GetDescription(typeof(T)); - - [SerializeField] - protected T component; - - #region Properties - public override string Name => _autoname; - public override Color Color => _autoColor; - public override string Description => _autoDescription; - public sealed override Type Type => typeof(T); - - internal T Component => component; - internal override object ComponentRef => component; - #endregion - - public abstract void Add(EcsWorld w, int e); - public virtual void OnGizmos(Transform transform, ITemplateComponentGizmos.Mode mode) { } - public virtual void OnValidate(GameObject gameObject) { } - } - - internal static class ITemplateBrowsableExt - { - private static MethodInfo memberwiseCloneMethdo = typeof(object).GetMethod("MemberwiseClone", BindingFlags.Instance | BindingFlags.NonPublic); - internal static ITemplateComponent Clone(this ITemplateComponent obj) - { - return (ITemplateComponent)memberwiseCloneMethdo.Invoke(obj, null); - } - } - -#if UNITY_EDITOR - namespace Editors - { - internal static class TemplateBrowsableTypeCache - { - private static Type[] _types; - private static ITemplateComponent[] _dummies; - internal static ReadOnlySpan Types => _types; - internal static ReadOnlySpan Dummies => _dummies; - - static TemplateBrowsableTypeCache() - { - List types = new List(); - Type interfaceType = typeof(ITemplateComponent); - foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) - { - var targetTypes = assembly.GetTypes().Where(type => !type.IsGenericType && (type.IsValueType || type.IsClass) && type.GetCustomAttribute() != null); - - types.AddRange(targetTypes.Where(type => interfaceType.IsAssignableFrom(type))); - - foreach (var t in targetTypes) - { - if (t.IsSubclassOf(typeof(TemplateComponentInitializer<>))) - { - if (t.HasAttribute()) - types.Add(t); - } - } - } - _types = types.ToArray(); - _dummies = new ITemplateComponent[_types.Length]; - - for (int i = 0; i < _types.Length; i++) - _dummies[i] = (ITemplateComponent)Activator.CreateInstance(_types[i]); - } - } - } -#endif -} diff --git a/src/EntityTemplate/Templates.meta b/src/EntityTemplate/Templates.meta new file mode 100644 index 0000000..7e9abc7 --- /dev/null +++ b/src/EntityTemplate/Templates.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 14555d6350df03d448d362de7b6a31c1 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/EntityTemplate/Templates/ComponentTemplateBase.cs b/src/EntityTemplate/Templates/ComponentTemplateBase.cs new file mode 100644 index 0000000..9d12a76 --- /dev/null +++ b/src/EntityTemplate/Templates/ComponentTemplateBase.cs @@ -0,0 +1,157 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using UnityEngine; +using static DCFApixels.DragonECS.IComponentTemplate; + +namespace DCFApixels.DragonECS +{ + public interface IComponentTemplate : ITemplateNode + { + #region Properties + Type Type { get; } + string Name { get; } + MetaGroup Group { get; } + string Description { get; } + IReadOnlyCollection Tags { get; } + Color Color { get; } + #endregion + + #region Methods + object GetRaw(); + void SetRaw(object raw); + void OnGizmos(Transform transform, GizmosMode mode); + void OnValidate(UnityEngine.Object obj); + #endregion + + public enum GizmosMode + { + Always, + Selected + } + } + + [Serializable] + public abstract class ComponentTemplateBase : IComponentTemplate + { + #region Properties + public abstract Type Type { get; } + public virtual string Name { get { return string.Empty; } } + public virtual MetaGroup Group { get { return default; } } + public virtual string Description { get { return string.Empty; } } + public virtual IReadOnlyCollection Tags { get { return Array.Empty(); } } + public virtual Color Color { get { return Color.black; } } + #endregion + + #region Methods + public abstract object GetRaw(); + public abstract void SetRaw(object raw); + public virtual void OnGizmos(Transform transform, GizmosMode mode) { } + public virtual void OnValidate(UnityEngine.Object obj) { } + + public abstract void Apply(int worldID, int entityID); + #endregion + } + [Serializable] + public abstract class ComponentTemplateBase : ComponentTemplateBase, IComponentTemplate + { + private static TypeMetaDataCached _meta = EcsDebugUtility.GetCachedTypeMeta(); + [SerializeField] + protected T component; + + #region Properties + public override Type Type { get { return typeof(T); } } + public override string Name { get { return _meta.Name; } } + public override MetaGroup Group { get { return _meta.Group; } } + public override string Description { get { return _meta.Description; } } + public override IReadOnlyCollection Tags { get { return _meta.Tags; } } + public override Color Color { get { return _meta.Color.ToUnityColor(); } } + #endregion + + #region Methods + public override object GetRaw() + { + return component; + } + public override void SetRaw(object raw) + { + component = (T)raw; + } + #endregion + } + + public abstract class ComponentTemplate : ComponentTemplateBase, IComponentTemplate + where T : struct, IEcsComponent + { + public override void Apply(int worldID, int entityID) + { + EcsWorld.GetPool>(worldID).TryAddOrGet(entityID) = component; + } + } + public abstract class TagComponentTemplate : ComponentTemplateBase, IComponentTemplate + where T : struct, IEcsTagComponent + { + public override void Apply(int worldID, int entityID) + { + EcsWorld.GetPool>(worldID).Set(entityID, true); + } + } +} + +namespace DCFApixels.DragonECS.Unity.Internal +{ + internal static class ComponentTemplateExtensions + { + private static MethodInfo memberwiseCloneMethdo = typeof(object).GetMethod("MemberwiseClone", BindingFlags.Instance | BindingFlags.NonPublic); + internal static IComponentTemplate Clone(this IComponentTemplate obj) + { + return (IComponentTemplate)memberwiseCloneMethdo.Invoke(obj, null); + } + } +} + +#if UNITY_EDITOR +namespace DCFApixels.DragonECS.Unity.Editors +{ + internal static class ComponentTemplateTypeCache + { + private static Type[] _types; + private static IComponentTemplate[] _dummies; + internal static ReadOnlySpan Types => _types; + internal static ReadOnlySpan Dummies => _dummies; + + static ComponentTemplateTypeCache() + { + List types = new List(); + Type interfaceType = typeof(IComponentTemplate); + foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) + { + var targetTypes = assembly.GetTypes().Where(type => !type.IsGenericType && !(type.IsAbstract || type.IsInterface) && type.GetCustomAttribute() != null); + + types.AddRange(targetTypes.Where(type => interfaceType.IsAssignableFrom(type))); + + foreach (var t in targetTypes) + { + if (t.IsSubclassOf(typeof(ComponentTemplateBase<>))) + { + types.Add(t); + } + } + } + _types = types.ToArray(); + foreach (var type in _types) + { + EcsDebugUtility.GetCachedTypeMeta(type); + } + _dummies = new IComponentTemplate[_types.Length]; + + for (int i = 0; i < _types.Length; i++) + { + _dummies[i] = (IComponentTemplate)Activator.CreateInstance(_types[i]); + } + } + } +} +#endif + diff --git a/src/EntityTemplate/EntityTemplate.cs.meta b/src/EntityTemplate/Templates/ComponentTemplateBase.cs.meta similarity index 83% rename from src/EntityTemplate/EntityTemplate.cs.meta rename to src/EntityTemplate/Templates/ComponentTemplateBase.cs.meta index 3a14226..8ee6928 100644 --- a/src/EntityTemplate/EntityTemplate.cs.meta +++ b/src/EntityTemplate/Templates/ComponentTemplateBase.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 3c96e3aedd5a69443af75096e5561265 +guid: b532f9d8441035d49b9acb99ea23c231 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/src/EntityTemplate/Templates/MonoEntityTemplate.cs b/src/EntityTemplate/Templates/MonoEntityTemplate.cs new file mode 100644 index 0000000..3e7d248 --- /dev/null +++ b/src/EntityTemplate/Templates/MonoEntityTemplate.cs @@ -0,0 +1,65 @@ +using System; +using UnityEngine; + +namespace DCFApixels.DragonECS +{ + public class MonoEntityTemplate : MonoBehaviour, ITemplateInternal + { + [SerializeReference] + private IComponentTemplate[] _components; + //[SerializeField] + //private EntityTemplateInheritanceMatrix _inheritanceMatrix; + + #region Properties + string ITemplateInternal.ComponentsPropertyName + { + get { return nameof(_components); } + } + //EntityTemplateInheritanceMatrix ITemplateInternal.InheritanceMatrix + //{ + // get { return _inheritanceMatrix; } + //} + #endregion + + #region Methods + public void Apply(int worldID, int entityID) + { + foreach (var item in _components) + { + item.Apply(worldID, entityID); + } + } + public void Clear() + { + _components = Array.Empty(); + } + #endregion + + #region UnityEvents + private void OnValidate() + { + if (_components == null) { return; } + foreach (var item in _components) + { + item.OnValidate(gameObject); + } + } + private void OnDrawGizmos() + { + if (_components == null) { return; } + foreach (var item in _components) + { + item.OnGizmos(transform, IComponentTemplate.GizmosMode.Always); + } + } + private void OnDrawGizmosSelected() + { + if (_components == null) { return; } + foreach (var item in _components) + { + item.OnGizmos(transform, IComponentTemplate.GizmosMode.Selected); + } + } + #endregion + } +} diff --git a/src/Extensions/Runners.cs.meta b/src/EntityTemplate/Templates/MonoEntityTemplate.cs.meta similarity index 83% rename from src/Extensions/Runners.cs.meta rename to src/EntityTemplate/Templates/MonoEntityTemplate.cs.meta index 2b4d105..38b24c0 100644 --- a/src/Extensions/Runners.cs.meta +++ b/src/EntityTemplate/Templates/MonoEntityTemplate.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 385a6c66660032944ad2cce7130715d7 +guid: 351338ca92ace49499f450172d857af6 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/src/EntityTemplate/Templates/ScriptableEntityTemplate.cs b/src/EntityTemplate/Templates/ScriptableEntityTemplate.cs new file mode 100644 index 0000000..95dde5a --- /dev/null +++ b/src/EntityTemplate/Templates/ScriptableEntityTemplate.cs @@ -0,0 +1,50 @@ +using System; +using UnityEngine; + +namespace DCFApixels.DragonECS +{ + [CreateAssetMenu(fileName = nameof(ScriptableEntityTemplate), menuName = EcsConsts.FRAMEWORK_NAME + "/" + nameof(ScriptableEntityTemplate), order = 1)] + public class ScriptableEntityTemplate : ScriptableObject, ITemplateInternal + { + [SerializeReference] + private IComponentTemplate[] _components; + //[SerializeField] + //private EntityTemplateInheritanceMatrix _inheritanceMatrix; + + #region Properties + string ITemplateInternal.ComponentsPropertyName + { + get { return nameof(_components); } + } + //EntityTemplateInheritanceMatrix ITemplateInternal.InheritanceMatrix + //{ + // get { return _inheritanceMatrix; } + //} + #endregion + + #region Methods + public void Apply(int worldID, int entityID) + { + foreach (var item in _components) + { + item.Apply(worldID, entityID); + } + } + public void Clear() + { + _components = Array.Empty(); + } + #endregion + + #region UnityEvents + private void OnValidate() + { + if (_components == null) { return; } + foreach (var item in _components) + { + item.OnValidate(this); + } + } + #endregion + } +} diff --git a/src/EntityTemplate/Templates/ScriptableEntityTemplate.cs.meta b/src/EntityTemplate/Templates/ScriptableEntityTemplate.cs.meta new file mode 100644 index 0000000..7d1bf18 --- /dev/null +++ b/src/EntityTemplate/Templates/ScriptableEntityTemplate.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3d2b62f9703592042befb46ac1fee09c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/Extensions/Systems.cs b/src/Extensions/Systems.cs deleted file mode 100644 index 0c8f39d..0000000 --- a/src/Extensions/Systems.cs +++ /dev/null @@ -1,42 +0,0 @@ -using DCFApixels.DragonECS.Internal; -using System.Collections.Generic; - -namespace DCFApixels.DragonECS -{ - [DebugHide, DebugColor(DebugColor.Grey)] - public class DeleteOneFrameComponentFixedSystem : IEcsFixedRunProcess, IEcsInject - where TComponent : struct, IEcsComponent - { - private sealed class Aspect : EcsAspect - { - public EcsPool pool; - public Aspect(Builder b) => pool = b.Include(); - } - List _worlds = new List(); - public void Inject(EcsWorld obj) => _worlds.Add(obj); - public void FixedRun(EcsPipeline pipeline) - { - for (int i = 0, iMax = _worlds.Count; i < iMax; i++) - { - EcsWorld world = _worlds[i]; - if (world.IsComponentTypeDeclared()) - { - foreach (var e in world.Where(out Aspect a)) - a.pool.Del(e); - } - } - } - } - public static class DeleteOneFrameComponentFixedSystemExtensions - { - private const string AUTO_DEL_LAYER = nameof(AUTO_DEL_LAYER); - public static EcsPipeline.Builder AutoDelFixed(this EcsPipeline.Builder b, string layerName = AUTO_DEL_LAYER) - where TComponent : struct, IEcsComponent - { - if (AUTO_DEL_LAYER == layerName) - b.Layers.Insert(EcsConsts.POST_END_LAYER, AUTO_DEL_LAYER); - b.AddUnique(new DeleteOneFrameComponentSystem(), layerName); - return b; - } - } -} diff --git a/src/Extensions/Systems.cs.meta b/src/Extensions/Systems.cs.meta deleted file mode 100644 index 21f2963..0000000 --- a/src/Extensions/Systems.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: e8c608fea9f3569409826ec54affa822 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/src/Utils/BitMask.cs b/src/Utils/BitMask.cs index 17c9b07..f31f7bb 100644 --- a/src/Utils/BitMask.cs +++ b/src/Utils/BitMask.cs @@ -1,7 +1,7 @@ using System; using System.Runtime.CompilerServices; -namespace DCFApixels.DragonECS.Editors +namespace DCFApixels.DragonECS.Unity.Internal { internal class BitMask { @@ -21,21 +21,30 @@ namespace DCFApixels.DragonECS.Editors public bool this[int index] { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => (_data[index >> OFFSET] & (1 << (index & MOD_MASK))) != 0; + get + { + return (_data[index >> OFFSET] & (1 << (index & MOD_MASK))) != 0; + } [MethodImpl(MethodImplOptions.AggressiveInlining)] set { if (value) + { _data[index >> OFFSET] |= (1 << (index & MOD_MASK)); + } else + { _data[index >> OFFSET] &= ~(1 << (index & MOD_MASK)); + } } } public void Resize(int newSize) { if (newSize <= _size) + { return; + } _size = newSize / DATA_BITS + 1; Array.Resize(ref _data, _size); diff --git a/src/Utils/DebugColorAttributeExt.cs b/src/Utils/DebugColorAttributeExt.cs deleted file mode 100644 index 29c8da0..0000000 --- a/src/Utils/DebugColorAttributeExt.cs +++ /dev/null @@ -1,25 +0,0 @@ -using UnityEngine; - -namespace DCFApixels.DragonECS -{ - public static class DebugColorAttributeExt - { - public static Color GetUnityColor(this DebugColorAttribute self) - { - return self.color.ToUnityColor(); - } - public static Color32 GetUnityColor32(this DebugColorAttribute self) - { - return self.color.ToUnityColor32(); - } - - public static Color ToUnityColor(this DebugColor self) - { - return new Color(self.r / 255f, self.g / 255f, self.b / 255f, self.a / 255f); - } - public static Color32 ToUnityColor32(this DebugColor self) - { - return new Color32(self.r, self.g, self.b, self.a); - } - } -} diff --git a/src/Utils/MetaColorExstensions.cs b/src/Utils/MetaColorExstensions.cs new file mode 100644 index 0000000..18238e6 --- /dev/null +++ b/src/Utils/MetaColorExstensions.cs @@ -0,0 +1,16 @@ +using UnityEngine; + +namespace DCFApixels.DragonECS +{ + public static class MetaColorExstensions + { + public static Color ToUnityColor(this T self) where T : IMetaColor + { + return new Color(self.R / 255f, self.G / 255f, self.B / 255f, self.A / 255f); + } + public static Color32 ToUnityColor32(this T self) where T : IMetaColor + { + return new Color32(self.R, self.G, self.B, self.A); + } + } +} diff --git a/src/Utils/DebugColorAttributeExt.cs.meta b/src/Utils/MetaColorExstensions.cs.meta similarity index 100% rename from src/Utils/DebugColorAttributeExt.cs.meta rename to src/Utils/MetaColorExstensions.cs.meta diff --git a/src/Utils/SparseArray.cs b/src/Utils/SparseArray.cs index 5699919..340f17f 100644 --- a/src/Utils/SparseArray.cs +++ b/src/Utils/SparseArray.cs @@ -6,7 +6,7 @@ using System.Diagnostics.Contracts; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -namespace DCFApixels.DragonECS.Editors +namespace DCFApixels.DragonECS.Unity.Internal { internal class SparseArray { From 84445bfb7c20d496a9e26872d10fc5c16f4805a6 Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Sun, 3 Mar 2024 19:59:39 +0800 Subject: [PATCH 17/50] update? add runtime component editing --- src/Connectors/EcsEntityConnect.cs | 33 +- src/Debug/{Systems => }/DebugModule.cs | 5 +- src/Debug/{Systems => }/DebugModule.cs.meta | 0 src/Debug/Editor/DebugMonitorPrefs.cs | 3 +- src/Debug/Editor/EcsEditor.cs | 190 --------- .../{DebugService.meta => Monitors.meta} | 2 +- src/Debug/Monitors/EntityMonitor.cs | 31 ++ .../EntityMonitor.cs.meta} | 2 +- src/Debug/Monitors/PipelineMonitor.cs | 9 + .../PipelineMonitor.cs.meta} | 2 +- src/Debug/Monitors/WorldMonitor.cs | 9 + .../WorldMonitor.cs.meta} | 2 +- src/Debug/Systems/DebugMonitorBase.cs | 17 - src/Debug/Systems/PipelineDebugSystem.cs | 341 ---------------- src/Debug/Systems/WorldDebugSystem.cs | 177 --------- .../{DebugService => }/UnityDebugService.cs | 0 .../UnityDebugService.cs.meta | 0 src/Editor.meta | 8 + src/Editor/EditorUtility.cs | 365 ++++++++++++++++++ .../EditorUtility.cs.meta} | 0 src/Editor/FieldDrawerInfo.cs | 25 ++ src/Editor/FieldDrawerInfo.cs.meta | 11 + .../Editor/EntityTemplateEditor.cs | 2 + 23 files changed, 492 insertions(+), 742 deletions(-) rename src/Debug/{Systems => }/DebugModule.cs (80%) rename src/Debug/{Systems => }/DebugModule.cs.meta (100%) delete mode 100644 src/Debug/Editor/EcsEditor.cs rename src/Debug/{DebugService.meta => Monitors.meta} (77%) create mode 100644 src/Debug/Monitors/EntityMonitor.cs rename src/Debug/{Systems/PipelineDebugSystem.cs.meta => Monitors/EntityMonitor.cs.meta} (83%) create mode 100644 src/Debug/Monitors/PipelineMonitor.cs rename src/Debug/{Systems/WorldDebugSystem.cs.meta => Monitors/PipelineMonitor.cs.meta} (83%) create mode 100644 src/Debug/Monitors/WorldMonitor.cs rename src/Debug/{Systems/DebugMonitorBase.cs.meta => Monitors/WorldMonitor.cs.meta} (83%) delete mode 100644 src/Debug/Systems/DebugMonitorBase.cs delete mode 100644 src/Debug/Systems/PipelineDebugSystem.cs delete mode 100644 src/Debug/Systems/WorldDebugSystem.cs rename src/Debug/{DebugService => }/UnityDebugService.cs (100%) rename src/Debug/{DebugService => }/UnityDebugService.cs.meta (100%) create mode 100644 src/Editor.meta create mode 100644 src/Editor/EditorUtility.cs rename src/{Debug/Editor/EcsEditor.cs.meta => Editor/EditorUtility.cs.meta} (100%) create mode 100644 src/Editor/FieldDrawerInfo.cs create mode 100644 src/Editor/FieldDrawerInfo.cs.meta diff --git a/src/Connectors/EcsEntityConnect.cs b/src/Connectors/EcsEntityConnect.cs index 8492720..4e4a023 100644 --- a/src/Connectors/EcsEntityConnect.cs +++ b/src/Connectors/EcsEntityConnect.cs @@ -91,7 +91,6 @@ namespace DCFApixels.DragonECS #if UNITY_EDITOR namespace DCFApixels.DragonECS.Unity.Editors { - using System.Collections.Generic; using UnityEditor; [CustomEditor(typeof(EcsEntityConnect))] @@ -127,7 +126,7 @@ namespace DCFApixels.DragonECS.Unity.Editors DrawTemplates(); DrawButtons(); - DrawComponents(); + DrawComponents(targets); } private void DrawTop() { @@ -179,9 +178,16 @@ namespace DCFApixels.DragonECS.Unity.Editors } else { - EditorGUI.TextField(idRect, "-"); - EditorGUI.TextField(genRect, "-"); - EditorGUI.TextField(worldRect, "-"); + //Color defColor = GUI.contentColor; + //Color c = defColor; + //c.a = 0.55f; + //GUI.contentColor = c; + GUI.enabled = false; + EditorGUI.TextField(idRect, "Entity ID"); + EditorGUI.TextField(genRect, "Gen"); + EditorGUI.TextField(worldRect, "World ID"); + GUI.enabled = true; + //GUI.contentColor = defColor; } } @@ -217,13 +223,22 @@ namespace DCFApixels.DragonECS.Unity.Editors } } - private void DrawComponents() + private void DrawComponents(EcsEntityConnect[] targets) { + if (IsMultipleTargets) + { + for (int i = 0; i < targets.Length; i++) + { + if (targets[i].IsConected == true) + { + EditorGUILayout.HelpBox("Multiple component editing is not available.", MessageType.Warning); + break; + } + } + } if (Target.IsConected) { - List comps = new List(); - Target.World.GetComponents(Target.Entity.ID, comps); - GUILayout.TextArea(string.Join("\r\n", comps)); + EcsGUI.Layout.DrawComponents(Target.Entity); } } } diff --git a/src/Debug/Systems/DebugModule.cs b/src/Debug/DebugModule.cs similarity index 80% rename from src/Debug/Systems/DebugModule.cs rename to src/Debug/DebugModule.cs index 9fb7311..9be3304 100644 --- a/src/Debug/Systems/DebugModule.cs +++ b/src/Debug/DebugModule.cs @@ -4,6 +4,7 @@ { public const string DEBUG_LAYER = nameof(DEBUG_LAYER); public EcsWorld[] _worlds; + public DebugModule(params EcsWorld[] worlds) { _worlds = worlds; @@ -12,10 +13,10 @@ void IEcsModule.Import(EcsPipeline.Builder b) { b.Layers.Insert(EcsConsts.POST_END_LAYER, DEBUG_LAYER); - b.Add(new PipelineDebugSystem(), DEBUG_LAYER); + //b.Add(new PipelineDebugSystem(), DEBUG_LAYER); foreach (var world in _worlds) { - b.Add(new WorldDebugSystem(world), DEBUG_LAYER); + //b.Add(new WorldDebugSystem(world), DEBUG_LAYER); } } } diff --git a/src/Debug/Systems/DebugModule.cs.meta b/src/Debug/DebugModule.cs.meta similarity index 100% rename from src/Debug/Systems/DebugModule.cs.meta rename to src/Debug/DebugModule.cs.meta diff --git a/src/Debug/Editor/DebugMonitorPrefs.cs b/src/Debug/Editor/DebugMonitorPrefs.cs index 3b32eb0..b6385e7 100644 --- a/src/Debug/Editor/DebugMonitorPrefs.cs +++ b/src/Debug/Editor/DebugMonitorPrefs.cs @@ -3,7 +3,7 @@ using UnityEditor; namespace DCFApixels.DragonECS.Unity.Editors { - [FilePath("DragonECS/DebugMonitorPrefs.prefs", FilePathAttribute.Location.ProjectFolder)] + [FilePath(EcsConsts.FRAMEWORK_NAME + "/" + nameof(DebugMonitorPrefs) + ".prefs", FilePathAttribute.Location.ProjectFolder)] public class DebugMonitorPrefs : ScriptableSingleton { private bool _isShowInterfaces = false; @@ -34,7 +34,6 @@ namespace DCFApixels.DragonECS.Unity.Editors Save(false); } } - } } #endif diff --git a/src/Debug/Editor/EcsEditor.cs b/src/Debug/Editor/EcsEditor.cs deleted file mode 100644 index 1a673e4..0000000 --- a/src/Debug/Editor/EcsEditor.cs +++ /dev/null @@ -1,190 +0,0 @@ -#if UNITY_EDITOR -using DCFApixels.DragonECS.Unity.Internal; -using System; -using System.Reflection; -using System.Runtime.InteropServices; -using UnityEditor; -using UnityEngine; - -namespace DCFApixels.DragonECS.Unity.Editors -{ - public static class EcsGUI - { - private static GUIStyle _grayStyle; - private static GUIStyle _greenStyle; - private static GUIStyle _redStyle; - private static GUILayoutOption[] _defaultParams; - - private static bool _isInit = false; - private static void Init() - { - if (_isInit) - { - return; - } - - _defaultParams = new GUILayoutOption[] { GUILayout.ExpandWidth(true) }; - _grayStyle = EcsEditor.GetStyle(new Color32(100, 100, 100, 100)); - _greenStyle = EcsEditor.GetStyle(new Color32(75, 255, 0, 100)); - _redStyle = EcsEditor.GetStyle(new Color32(255, 0, 75, 100)); - _isInit = true; - } - - - private const string CONNECTED = "Connected"; - private const string NOT_CONNECTED = "Not connected"; - private const string UNDETERMINED_CONNECTED = "---"; - public static void DrawConnectStatus(Rect position, bool status) - { - Init(); - if (status) - { - GUI.Box(position, CONNECTED, _greenStyle); - } - else - { - GUI.Box(position, NOT_CONNECTED, _redStyle); - } - } - - public static void DrawUndeterminedConnectStatus(Rect position) - { - Init(); - GUI.Box(position, UNDETERMINED_CONNECTED, _grayStyle); - } - public static class Layout - { - public static void DrawConnectStatus(bool status, params GUILayoutOption[] options) - { - Init(); - if(options == null || options.Length <= 0) - { - options = _defaultParams; - } - if (status) - { - GUILayout.Box(CONNECTED, _greenStyle, options); - } - else - { - GUILayout.Box(NOT_CONNECTED, _redStyle, options); - } - } - public static void DrawUndeterminedConnectStatus(params GUILayoutOption[] options) - { - Init(); - if (options == null || options.Length <= 0) - { - options = _defaultParams; - } - GUILayout.Box(UNDETERMINED_CONNECTED, _grayStyle, options); - } - } - } - [InitializeOnLoad] - public static class EcsEditor - { - static EcsEditor() - { - colorBoxeStyles = new SparseArray(); - } - private static SparseArray colorBoxeStyles = new SparseArray(); - public static GUIStyle GetStyle(Color color, float alphaMultiplier) - { - color.a *= alphaMultiplier; - return GetStyle(color); - } - public static GUIStyle GetStyle(Color32 color32) - { - int colorCode = new Color32Union(color32).colorCode; - if (colorBoxeStyles.TryGetValue(colorCode, out GUIStyle style)) - { - if (style == null || style.normal.background == null) - { - style = CreateStyle(color32, colorCode); - colorBoxeStyles[colorCode] = style; - } - return style; - } - - style = CreateStyle(color32, colorCode); - colorBoxeStyles.Add(colorCode, style); - return style; - } - private static GUIStyle CreateStyle(Color32 color32, int colorCode) - { - GUIStyle result = new GUIStyle(GUI.skin.box); - Color componentColor = color32; - Texture2D texture2D = CreateTexture(2, 2, componentColor); - result.hover.background = texture2D; - result.focused.background = texture2D; - result.active.background = texture2D; - result.normal.background = texture2D; - return result; - } - private static Texture2D CreateTexture(int width, int height, Color color) - { - var pixels = new Color[width * height]; - for (var i = 0; i < pixels.Length; ++i) - pixels[i] = color; - - var result = new Texture2D(width, height); - result.SetPixels(pixels); - result.Apply(); - return result; - } - - public static string GetGenericName(Type type) => EcsDebugUtility.GetGenericTypeName(type); - - public static string GetName() => GetName(typeof(T)); - public static string GetName(Type type) => EcsDebugUtility.GetName(type); - - public static string GetDescription() => GetDescription(typeof(T)); - public static string GetDescription(Type type) => EcsDebugUtility.GetDescription(type); - - #region Utils - [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 4)] - private readonly ref struct Color32Union - { - [FieldOffset(0)] - public readonly int colorCode; - [FieldOffset(0)] - public readonly byte r; - [FieldOffset(1)] - public readonly byte g; - [FieldOffset(2)] - public readonly byte b; - [FieldOffset(3)] - public readonly byte a; - public Color32Union(byte r, byte g, byte b, byte a) : this() - { - this.r = r; - this.g = g; - this.b = b; - this.a = a; - } - public Color32Union(Color32 color) : this() - { - r = color.r; - g = color.g; - b = color.b; - a = color.a; - } - } - #endregion - } - - public static class ReflectionExtensions - { - public static bool TryGetAttribute(this MemberInfo self, out T attrbiute) where T : Attribute - { - attrbiute = self.GetCustomAttribute(); - return attrbiute != null; - } - public static bool HasAttribute(this MemberInfo self) where T : Attribute - { - return self.GetCustomAttribute() != null; - } - } -} -#endif diff --git a/src/Debug/DebugService.meta b/src/Debug/Monitors.meta similarity index 77% rename from src/Debug/DebugService.meta rename to src/Debug/Monitors.meta index d45a1b6..58d6270 100644 --- a/src/Debug/DebugService.meta +++ b/src/Debug/Monitors.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: a124aa9f464ff79439c89b52281215d3 +guid: 8b7186fd57cbf9c42b4759c49920a688 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/src/Debug/Monitors/EntityMonitor.cs b/src/Debug/Monitors/EntityMonitor.cs new file mode 100644 index 0000000..905a720 --- /dev/null +++ b/src/Debug/Monitors/EntityMonitor.cs @@ -0,0 +1,31 @@ +using UnityEngine; + +namespace DCFApixels.DragonECS +{ + [MetaTags(MetaTags.HIDDEN), MetaColor(MetaColor.Gray)] + public class EntityMonitor : MonoBehaviour, IEcsProcess + { + private entlong _entity; + private int _entityID; + private short _gen; + private EcsWorld _world; + + public EcsWorld World + { + get { return _world; } + } + public int EntityID + { + get { return _entityID; } + } + + public EntityMonitor(entlong entity) + { + _entity = entity; + if (_entity.TryUnpack(out _entityID, out _gen, out _world)) + { + + } + } + } +} diff --git a/src/Debug/Systems/PipelineDebugSystem.cs.meta b/src/Debug/Monitors/EntityMonitor.cs.meta similarity index 83% rename from src/Debug/Systems/PipelineDebugSystem.cs.meta rename to src/Debug/Monitors/EntityMonitor.cs.meta index 54d26b0..b9fb7dd 100644 --- a/src/Debug/Systems/PipelineDebugSystem.cs.meta +++ b/src/Debug/Monitors/EntityMonitor.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 1caa902906afea3409fc63ed94cbbc11 +guid: b3c51f9f4aa13e74fbb4339f8c1746d4 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/src/Debug/Monitors/PipelineMonitor.cs b/src/Debug/Monitors/PipelineMonitor.cs new file mode 100644 index 0000000..66e102d --- /dev/null +++ b/src/Debug/Monitors/PipelineMonitor.cs @@ -0,0 +1,9 @@ +using UnityEngine; + +namespace DCFApixels.DragonECS +{ + [MetaTags(MetaTags.HIDDEN), MetaColor(MetaColor.Gray)] + public class PipelineMonitor : MonoBehaviour, IEcsProcess + { + } +} diff --git a/src/Debug/Systems/WorldDebugSystem.cs.meta b/src/Debug/Monitors/PipelineMonitor.cs.meta similarity index 83% rename from src/Debug/Systems/WorldDebugSystem.cs.meta rename to src/Debug/Monitors/PipelineMonitor.cs.meta index a314c41..0444ffa 100644 --- a/src/Debug/Systems/WorldDebugSystem.cs.meta +++ b/src/Debug/Monitors/PipelineMonitor.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: d36835beef2392f40854af962ff47472 +guid: 03154a226ad86e24ebfa4faf43da8310 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/src/Debug/Monitors/WorldMonitor.cs b/src/Debug/Monitors/WorldMonitor.cs new file mode 100644 index 0000000..1db0c00 --- /dev/null +++ b/src/Debug/Monitors/WorldMonitor.cs @@ -0,0 +1,9 @@ +using UnityEngine; + +namespace DCFApixels.DragonECS +{ + [MetaTags(MetaTags.HIDDEN), MetaColor(MetaColor.Gray)] + public class WorldMonitor : MonoBehaviour, IEcsProcess + { + } +} diff --git a/src/Debug/Systems/DebugMonitorBase.cs.meta b/src/Debug/Monitors/WorldMonitor.cs.meta similarity index 83% rename from src/Debug/Systems/DebugMonitorBase.cs.meta rename to src/Debug/Monitors/WorldMonitor.cs.meta index c35ff94..a595b88 100644 --- a/src/Debug/Systems/DebugMonitorBase.cs.meta +++ b/src/Debug/Monitors/WorldMonitor.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 6b7b4bd406553d64589aa4e085d4ff28 +guid: 3d65916dbb4c8f74cb5239c5bbf7ba31 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/src/Debug/Systems/DebugMonitorBase.cs b/src/Debug/Systems/DebugMonitorBase.cs deleted file mode 100644 index f4f89d1..0000000 --- a/src/Debug/Systems/DebugMonitorBase.cs +++ /dev/null @@ -1,17 +0,0 @@ -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/PipelineDebugSystem.cs b/src/Debug/Systems/PipelineDebugSystem.cs deleted file mode 100644 index 8f4efa3..0000000 --- a/src/Debug/Systems/PipelineDebugSystem.cs +++ /dev/null @@ -1,341 +0,0 @@ -using DCFApixels.DragonECS.Unity.Debug; -using UnityEngine; -using System.Linq; - -namespace DCFApixels.DragonECS -{ - [MetaTags(MetaTags.HIDDEN), MetaColor(MetaColor.Gray)] - public class PipelineDebugSystem : IEcsPreInit, IEcsPipelineMember - { - public EcsPipeline Pipeline { get; set; } - private string _monitorName; - public PipelineDebugSystem(string monitorName = "Pipeline") - { - _monitorName = monitorName; - } - - void IEcsPreInit.PreInit() - { - PipelineDebugMonitor monitor = new GameObject(EcsConsts.DEBUG_PREFIX + _monitorName).AddComponent(); - monitor.source = this; - monitor.pipeline = Pipeline; - monitor.monitorName = _monitorName; - - PipelineProcessesDebugMonitor processesMonitor = new GameObject(EcsConsts.DEBUG_PREFIX + "Processes Matrix").AddComponent(); - processesMonitor.transform.parent = monitor.transform; - processesMonitor.source = this; - processesMonitor.pipeline = Pipeline; - processesMonitor.monitorName = "Processes Matrix"; - - //foreach (var item in pipeline.AllSystems) //Вырезано пока не сделаю TODO в SystemDebugMonitor - //{ - // DebugNameAttribute debugName = item.GetType().GetCustomAttribute(); - // string name = debugName == null ? item.GetType().Name : debugName.name; - // SystemDebugMonitor.CreateMonitor(monitor.transform, item, name); - //} - } - } - - public class PipelineDebugMonitor : DebugMonitorBase - { - internal PipelineDebugSystem source; - internal EcsPipeline pipeline; - } - - public class PipelineProcessesDebugMonitor : DebugMonitorBase - { - internal PipelineDebugSystem source; - internal EcsPipeline pipeline; - } -} - - -#if UNITY_EDITOR -namespace DCFApixels.DragonECS.Unity.Editors -{ - using DCFApixels.DragonECS.RunnersCore; - using DCFApixels.DragonECS.Unity.Internal; - using System; - using System.Collections.Generic; - using UnityEditor; - - [CustomEditor(typeof(PipelineDebugMonitor))] - public class PipelineDebugMonitorEditor : Editor - { - private MetaColorAttribute _fakeDebugColorAttribute = new MetaColorAttribute(190, 190, 190); - private Type _debugColorAttributeType = typeof(MetaColorAttribute); - private GUIStyle _headerStyle; - private GUIStyle _interfacesStyle; - private Color _interfaceColor = new Color(0.96f, 1f, 0.16f); - private PipelineDebugMonitor Target => (PipelineDebugMonitor)target; - - - private GUIStyle systemsListStyle; - - public override void OnInspectorGUI() - { - systemsListStyle = new GUIStyle(EditorStyles.miniLabel); - systemsListStyle.wordWrap = true; - - if (Target.source == null) - return; - if (_headerStyle == null) - { - _headerStyle = new GUIStyle(EditorStyles.boldLabel); - _interfacesStyle = new GUIStyle(EditorStyles.miniLabel); - _interfacesStyle.hover.textColor = _interfaceColor; - _interfacesStyle.focused.textColor = _interfaceColor; - _interfacesStyle.active.textColor = _interfaceColor; - _interfacesStyle.normal.textColor = _interfaceColor; - _interfacesStyle.wordWrap = true; - _headerStyle.fontSize = 28; - } - - GUILayout.Label("[Systems]", _headerStyle); - - DebugMonitorPrefs.instance.IsShowInterfaces = EditorGUILayout.Toggle("Show Interfaces", DebugMonitorPrefs.instance.IsShowInterfaces); - DebugMonitorPrefs.instance.IsShowHidden = EditorGUILayout.Toggle("Show Hidden", DebugMonitorPrefs.instance.IsShowHidden); - - GUILayout.BeginVertical(); - foreach (var item in Target.pipeline.AllSystems) - { - DrawSystem(item); - } - GUILayout.EndVertical(); - - - GUILayout.Label("[Runners]", _headerStyle); - - GUILayout.BeginVertical(EcsEditor.GetStyle(Color.black, 0.2f)); - foreach (var item in Target.pipeline.AllRunners) - { - DrawRunner(item.Value); - } - GUILayout.EndVertical(); - } - - private void DrawSystem(IEcsProcess system) - { - if (system is SystemsLayerMarkerSystem markerSystem) - { - GUILayout.EndVertical(); - GUILayout.BeginVertical(EcsEditor.GetStyle(Color.black, 0.2f)); - - GUILayout.BeginHorizontal(); - GUILayout.Label("<"); - GUILayout.Label($"{markerSystem.name}", EditorStyles.boldLabel); - GUILayout.Label(">", GUILayout.ExpandWidth(false)); - GUILayout.EndHorizontal(); - return; - } - - Type type = system.GetType(); - - if (CheckIsHidden(type)) - return; - - string name = EcsEditor.GetGenericName(type); - //Color color = (GetAttribute(type) ?? _fakeDebugColorAttribute).GetUnityColor(); - Color color = EcsDebugUtility.GetColor(type).ToUnityColor(); - - GUILayout.BeginVertical(EcsEditor.GetStyle(color, 0.2f)); - if (DebugMonitorPrefs.instance.IsShowInterfaces) - { - GUILayout.Label(string.Join(", ", type.GetInterfaces().Select(o => o.Name)), _interfacesStyle); - } - GUILayout.Label(name, EditorStyles.boldLabel); - GUILayout.EndVertical(); - } - - private void DrawRunner(IEcsRunner runner) - { - Type type = runner.GetType(); - if (CheckIsHidden(type)) - return; - - //Color color = (GetAttribute(type) ?? _fakeDebugColorAttribute).GetUnityColor(); - Color color = EcsDebugUtility.GetColor(type).ToUnityColor(); - - GUILayout.BeginVertical(EcsEditor.GetStyle(color, 0.2f)); - GUILayout.Label(EcsEditor.GetGenericName(type), EditorStyles.boldLabel); - GUILayout.Label(string.Join(", ", runner.ProcessRaw.Cast().Select(o => o.GetType().Name)), systemsListStyle); - GUILayout.EndVertical(); - } - - private TAttribute GetAttribute(Type target) where TAttribute : Attribute - { - var result = target.GetCustomAttributes(_debugColorAttributeType, false); - if (result.Length > 0) - return (TAttribute)result[0]; - return null; - } - - private bool CheckIsHidden(Type target) - { - if (DebugMonitorPrefs.instance.IsShowHidden) - return false; - return target.GetCustomAttribute() != null; - } - } - - [CustomEditor(typeof(PipelineProcessesDebugMonitor))] - public class PipelineProcessesDebugMonitorEditor : Editor - { - private bool _isInit = false; - private List _processesList = new List(); - private Dictionary _processeIndexes = new Dictionary(); - - private PipelineProcessesDebugMonitor Target => (PipelineProcessesDebugMonitor)target; - private Type systemInterfaceType = typeof(IEcsProcess); - - private IEcsProcess[] _systems; - private void Init() - { - if (_isInit) - return; - bool showHidden = DebugMonitorPrefs.instance.IsShowHidden; - _processesList.Clear(); - _processeIndexes.Clear(); - if (showHidden) - _systems = Target.pipeline.AllSystems.Where(o => o is SystemsLayerMarkerSystem == false).ToArray(); - else - _systems = Target.pipeline.AllSystems.Where(o => o.GetType().GetCustomAttribute() == null).ToArray(); - - int i = 0; - foreach (var system in _systems) - { - foreach (var intr in system.GetType().GetInterfaces()) - { - if (systemInterfaceType.IsAssignableFrom(intr) && systemInterfaceType != intr && (showHidden || intr.GetCustomAttribute() == null)) - { - ProcessData data; - if (!_processeIndexes.TryGetValue(intr, out int index)) - { - index = _processesList.Count; - _processeIndexes.Add(intr, index); - - data = new ProcessData(); - _processesList.Add(data); - - data.name = EcsEditor.GetGenericName(intr); - data.interfaceType = intr; - data.systemsBitMask = new BitMask(_systems.Length); - } - data = _processesList[index]; - data.systemsBitMask[i] = true; - } - } - i++; - } - - _isInit = true; - } - private Vector2 _position; - private Vector2 _cellsize = new Vector2(EditorGUIUtility.singleLineHeight, EditorGUIUtility.singleLineHeight); - private Vector2 _nameCellSize = new Vector2(200f, 200f); - - public override void OnInspectorGUI() - { - EditorGUI.BeginChangeCheck(); - DebugMonitorPrefs.instance.IsShowHidden = EditorGUILayout.Toggle("Show Hidden", DebugMonitorPrefs.instance.IsShowHidden); - if (EditorGUI.EndChangeCheck()) - { - _isInit = false; - } - - Init(); - - Rect rect; - Rect lineRect; - GUILayout.Label("", GUILayout.ExpandWidth(true), GUILayout.Height(400f)); - rect = GUILayoutUtility.GetLastRect(); - - rect.height = 400f; - - - Rect rectView = new Rect(0f, 0f, _nameCellSize.x + _cellsize.x * _processesList.Count, _nameCellSize.y + _cellsize.y * _systems.Length); - _position = GUI.BeginScrollView(rect, _position, rectView, true, true); - - List systeNames = new List(); - - var blackStyle = EcsEditor.GetStyle(Color.black, 0.04f); - var whiteStyle = EcsEditor.GetStyle(Color.white, 0.04f); - GUIContent label = new GUIContent(); - - - Vector2 pivod = _nameCellSize; - rect = new Rect(); - rect.y = _nameCellSize.y; - rect.width = _nameCellSize.x; - rect.height = _cellsize.x; - rect.y -= _cellsize.y; - for (int i = 0; i < _processesList.Count; i++) - { - lineRect = rect; - lineRect.y = 0f; - lineRect.x = _nameCellSize.x + _cellsize.x * i; - lineRect.width = _cellsize.x; - lineRect.height = rectView.height; - GUI.Label(lineRect, "", i % 2 == 1 ? whiteStyle : blackStyle); - - GUIUtility.RotateAroundPivot(90, pivod); - //GUIContent label = new GUIContent(_processesList[i].name, "." + _processesList[i].name); - label.text = _processesList[i].name; - label.tooltip = "." + _processesList[i].name; - GUI.Label(rect, label, EditorStyles.miniBoldLabel); - GUIUtility.RotateAroundPivot(-90, pivod); - - pivod.x += _cellsize.x; - rect.x += _cellsize.x; - } - - //GUIUtility.RotateAroundPivot(-90, _nameCellSize); - rect = new Rect(); - rect.y = _nameCellSize.y; - rect.width = _nameCellSize.x; - rect.height = _cellsize.x; - for (int i = 0; i < _systems.Length; i++) - { - string name = EcsEditor.GetGenericName(_systems[i].GetType()); - systeNames.Add(name); - - lineRect = rect; - lineRect.width = rectView.width; - GUI.Label(lineRect, "", i % 2 == 1 ? whiteStyle : blackStyle); - - // GUIContent label = new GUIContent(name, i + " " + name); - label.text = name; - label.tooltip = i + " " + name; - GUI.Label(rect, label, EditorStyles.miniBoldLabel); - rect.y += _cellsize.y; - } - - for (int x = 0; x < _processesList.Count; x++) - { - var process = _processesList[x]; - for (int y = 0; y < _systems.Length; y++) - { - string systemName = systeNames[x]; - rect = new Rect(x * _cellsize.x + _nameCellSize.x, y * _cellsize.y + _nameCellSize.y, _cellsize.x, _cellsize.y); - bool flag = process.systemsBitMask[y]; - string labeltext = flag ? "^" : " "; - label.text = labeltext; - label.tooltip = $"{process.name}-{systemName}"; - GUI.Label(rect, label); - //GUI.Label(rect, lable, flag ? whiteStyle : blackStyle); - // GUI.Label(rect, label, EditorStyles.helpBox); - } - } - - GUI.EndScrollView(); - } - - private class ProcessData - { - public Type interfaceType; - public string name; - public BitMask systemsBitMask; - } - } -} -#endif diff --git a/src/Debug/Systems/WorldDebugSystem.cs b/src/Debug/Systems/WorldDebugSystem.cs deleted file mode 100644 index 003ed6e..0000000 --- a/src/Debug/Systems/WorldDebugSystem.cs +++ /dev/null @@ -1,177 +0,0 @@ -using DCFApixels.DragonECS.Unity.Debug; -using UnityEngine; -using System.Linq; - -namespace DCFApixels.DragonECS -{ - [MetaTags(MetaTags.HIDDEN), MetaColor(MetaColor.Gray)] - public class WorldDebugSystem : IEcsRun - { - private string _monitorName; - private EcsWorld _ecsWorld; - - public WorldDebugSystem(EcsWorld ecsWorld, string monitorName = null) - { - _monitorName = monitorName; - if (string.IsNullOrEmpty(_monitorName)) _monitorName = ecsWorld.GetType().Name; - _ecsWorld = ecsWorld; - WorldDebugMonitor monitor = new GameObject(EcsConsts.DEBUG_PREFIX + _monitorName).AddComponent(); - WorldPoolsMonitor poolsmonitor = new GameObject(EcsConsts.DEBUG_PREFIX + "Pools").AddComponent(); - poolsmonitor.transform.SetParent(monitor.transform); - - monitor.source = this; - monitor.world = _ecsWorld; - monitor.monitorName = _monitorName; - - poolsmonitor.source = this; - poolsmonitor.world = _ecsWorld; - poolsmonitor.monitorName = "pools"; - } - - public void Run() - { - } - } - - public class WorldDebugMonitor : DebugMonitorBase - { - internal WorldDebugSystem source; - internal EcsWorld world; - } - -#if UNITY_EDITOR - namespace Editors - { - using UnityEditor; - - [CustomEditor(typeof(WorldDebugMonitor))] - public class WorldDebugMonitorEditor : Editor - { - private WorldDebugMonitor Target => (WorldDebugMonitor)target; - - public override void OnInspectorGUI() - { - GUILayout.Label($"Size: {Target.world.Capacity}"); - GUILayout.Label($"Total entities: {Target.world.Count}"); - } - } - } -#endif - - - - - public class WorldPoolsMonitor : DebugMonitorBase - { - internal WorldDebugSystem source; - internal EcsWorld world; - } -} - -#if UNITY_EDITOR -namespace DCFApixels.DragonECS.Unity.Editors -{ - using UnityEditor; - - [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.AllPools.ToArray().Where(o => !o.IsNullOrDummy()).OfType(); - - 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(); - } - - /// : new Color(0.3f, 1f, 0f, 1f); - - private void DrawPoolBlock(IEcsPool pool, Rect position) - { - var meta = pool.GetMeta(); - - int count = pool.Count; - int capacity = pool.Capacity < 0 ? count : pool.Capacity; - - 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 = meta.Color.ToUnityColor(); - Color backgroundColor = mainColor * 0.3f + Color.white * 0.2f; - - EditorGUI.DrawRect(progressBar, backgroundColor); - - progressBar.yMin = progressBar.yMax - ((float)count / capacity) * progressBar.height; - - GUIStyle textStyle0 = new GUIStyle(EditorStyles.miniBoldLabel); - textStyle0.alignment = TextAnchor.MiddleCenter; - - Color foregroundColor = mainColor; - EditorGUI.DrawRect(progressBar, foregroundColor); - GUI.Label(progressBar, count.ToString(), textStyle0); - - GUIStyle textStyle1 = new GUIStyle(EditorStyles.miniBoldLabel); - textStyle1.alignment = TextAnchor.UpperCenter; - GUI.Label(AddMargin(position, 3f, 3f), "Total\r\n" + capacity, textStyle1); - - GUI.contentColor = defaultContentColor; - GUIStyle textStyle2 = new GUIStyle(EditorStyles.miniBoldLabel); - textStyle2.wordWrap = true; - textStyle2.alignment = TextAnchor.LowerCenter; - string name = EcsEditor.GetGenericName(pool.ComponentType); - GUIContent label = new GUIContent(name, $"{name} e:{count}"); - GUI.Label(AddMargin(position, -10f, 3f), label, 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/Debug/DebugService/UnityDebugService.cs b/src/Debug/UnityDebugService.cs similarity index 100% rename from src/Debug/DebugService/UnityDebugService.cs rename to src/Debug/UnityDebugService.cs diff --git a/src/Debug/DebugService/UnityDebugService.cs.meta b/src/Debug/UnityDebugService.cs.meta similarity index 100% rename from src/Debug/DebugService/UnityDebugService.cs.meta rename to src/Debug/UnityDebugService.cs.meta diff --git a/src/Editor.meta b/src/Editor.meta new file mode 100644 index 0000000..336de05 --- /dev/null +++ b/src/Editor.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 7ff185425dcbca44f820bfc6c564d1d2 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/Editor/EditorUtility.cs b/src/Editor/EditorUtility.cs new file mode 100644 index 0000000..aac050d --- /dev/null +++ b/src/Editor/EditorUtility.cs @@ -0,0 +1,365 @@ +#if UNITY_EDITOR +using DCFApixels.DragonECS.Unity.Internal; +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Runtime.InteropServices; +using UnityEditor; +using UnityEngine; + +namespace DCFApixels.DragonECS.Unity.Editors +{ + internal class WrapperBase : ScriptableObject + where TSelf : WrapperBase + { + private SerializedObject _so; + private SerializedProperty _property; + + private bool _isReleased = false; + private static Stack _wrappers = new Stack(); + + public SerializedObject SO + { + get { return _so; } + } + public SerializedProperty Property + { + get { return _property; } + } + + public static TSelf Take() + { + TSelf result; + if (_wrappers.Count <= 0) + { + result = CreateInstance(); + result._so = new SerializedObject(result); + result._property = result._so.FindProperty("data"); + } + else + { + result = _wrappers.Pop(); + } + return result; + } + public static void Release(TSelf wrapper) + { + if (wrapper._isReleased) + { + return; + } + wrapper._isReleased = true; + _wrappers.Push(wrapper); + } + } + internal class RefEditorWrapper : WrapperBase + { + [SerializeReference] + public object data; + } + internal class UnityObjEditorWrapper : WrapperBase + { + [SerializeField] + public UnityEngine.Object data; + } + + public static class EcsGUI + { + private static Color _grayColor = new Color32(100, 100, 100, 100); + private static Color _greenColor = new Color32(75, 255, 0, 100); + private static Color _redColor = new Color32(255, 0, 75, 100); + + private static GUIStyle _grayStyle; + private static GUIStyle _greenStyle; + private static GUIStyle _redStyle; + private static GUILayoutOption[] _defaultParams; + + private static bool _isInit = false; + + private static void Init() + { + if (_isInit) + { + return; + } + + _defaultParams = new GUILayoutOption[] { GUILayout.ExpandWidth(true) }; + _grayStyle = EcsEditor.GetStyle(_grayColor); + _greenStyle = EcsEditor.GetStyle(_greenColor); + _redStyle = EcsEditor.GetStyle(_redColor); + _isInit = true; + } + + + private const string CONNECTED = "Connected"; + private const string NOT_CONNECTED = "Not connected"; + private const string UNDETERMINED_CONNECTED = "---"; + public static void DrawConnectStatus(Rect position, bool status) + { + Init(); + if (status) + { + GUI.Box(position, CONNECTED, _greenStyle); + } + else + { + GUI.Box(position, NOT_CONNECTED, _redStyle); + } + } + + public static void DrawUndeterminedConnectStatus(Rect position) + { + Init(); + GUI.Box(position, UNDETERMINED_CONNECTED, _grayStyle); + } + + public static class Layout + { + public static void DrawConnectStatus(bool status, params GUILayoutOption[] options) + { + Init(); + if (options == null || options.Length <= 0) + { + options = _defaultParams; + } + GUILayout.Box("", options); + Rect lastRect = GUILayoutUtility.GetLastRect(); + if (status) + { + Color color = _greenColor; + color.a = 0.6f; + EditorGUI.DrawRect(lastRect, color); + GUI.Box(lastRect, CONNECTED); + } + else + { + Color color = _redColor; + color.a = 0.6f; + EditorGUI.DrawRect(lastRect, color); + GUI.Box(lastRect, NOT_CONNECTED); + } + } + public static void DrawUndeterminedConnectStatus(params GUILayoutOption[] options) + { + Init(); + if (options == null || options.Length <= 0) + { + options = _defaultParams; + } + GUILayout.Box(UNDETERMINED_CONNECTED, _grayStyle, options); + } + public static void DrawComponents(entlong entity) + { + if (entity.TryUnpack(out int entityID, out EcsWorld world)) + { + DrawComponents(entityID, world); + } + } + public static void DrawComponents(int entityID, EcsWorld world) + { + var componentTypeIDs = world.GetComponentTypeIDs(entityID); + + foreach (var componentTypeID in componentTypeIDs) + { + var pool = world.GetPool(componentTypeID); + { + DrawComponent(entityID, world, pool); + } + } + } + private static readonly BindingFlags fieldFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; + private static void DrawComponent(int entityID, EcsWorld world, IEcsPool pool) + { + object data = pool.GetRaw(entityID); + var meta = data.GetMeta(); + + Color panelColor = meta.Color.ToUnityColor(); + GUILayout.BeginVertical(EcsEditor.GetStyle(panelColor, 0.22f)); + EditorGUI.BeginChangeCheck(); + + bool changed = DrawData(pool.ComponentType, data, out object resultData); + + if (changed) + { + pool.SetRaw(entityID, resultData); + } + + GUILayout.EndVertical(); + + Rect lineRect = GUILayoutUtility.GetLastRect(); + lineRect.y = lineRect.yMax; + lineRect.height = 3f; + Color rectColor = panelColor; + rectColor.a = 0.34f; + EditorGUI.DrawRect(lineRect, rectColor); + + GUILayout.Space(2f); + } + + private static bool DrawData(Type fieldType, object data, out object outData) + { + var meta = data.GetMeta(); + GUIContent label = new GUIContent(meta.Name); + + Type type = data.GetType(); + var uobj = data as UnityEngine.Object; + if (uobj == false && type.IsGenericType) + { + bool result = false; + foreach (var field in type.GetFields(fieldFlags)) + { + if (DrawData(field.FieldType, field.GetValue(data), out object fieldData)) + { + field.SetValue(data, fieldData); + result = true; + } + } + outData = data; + return result; + } + else + { + if (uobj == null) + { + EditorGUI.BeginChangeCheck(); + + var w = RefEditorWrapper.Take(); + w.data = data; + w.SO.Update(); + + EditorGUILayout.PropertyField(w.Property, true); + RefEditorWrapper.Release(w); + + if (EditorGUI.EndChangeCheck()) + { + w.SO.ApplyModifiedProperties(); + outData = w.data; + return true; + } + } + else + { + EditorGUI.BeginChangeCheck(); + + var w = UnityObjEditorWrapper.Take(); + w.data = uobj; + w.SO.Update(); + + EditorGUILayout.PropertyField(w.Property, true); + UnityObjEditorWrapper.Release(w); + + if (EditorGUI.EndChangeCheck()) + { + w.SO.ApplyModifiedProperties(); + outData = uobj; + return true; + } + } + + outData = data; + return false; + } + } + } + } + + + [InitializeOnLoad] + public static class EcsEditor + { + static EcsEditor() + { + colorBoxeStyles = new SparseArray(); + } + private static SparseArray colorBoxeStyles = new SparseArray(); + public static GUIStyle GetStyle(Color color, float alphaMultiplier) + { + color.a *= alphaMultiplier; + return GetStyle(color); + } + public static GUIStyle GetStyle(Color32 color32) + { + int colorCode = new Color32Union(color32).colorCode; + if (colorBoxeStyles.TryGetValue(colorCode, out GUIStyle style)) + { + if (style == null || style.normal.background == null) + { + style = CreateStyle(color32, colorCode); + colorBoxeStyles[colorCode] = style; + } + return style; + } + + style = CreateStyle(color32, colorCode); + colorBoxeStyles.Add(colorCode, style); + return style; + } + private static GUIStyle CreateStyle(Color32 color32, int colorCode) + { + GUIStyle result = new GUIStyle(GUI.skin.box); + Color componentColor = color32; + Texture2D texture2D = CreateTexture(2, 2, componentColor); + result.hover.background = texture2D; + result.focused.background = texture2D; + result.active.background = texture2D; + result.normal.background = texture2D; + return result; + } + private static Texture2D CreateTexture(int width, int height, Color color) + { + var pixels = new Color[width * height]; + for (var i = 0; i < pixels.Length; ++i) + pixels[i] = color; + + var result = new Texture2D(width, height); + result.SetPixels(pixels); + result.Apply(); + return result; + } + + #region Utils + [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 4)] + private readonly ref struct Color32Union + { + [FieldOffset(0)] + public readonly int colorCode; + [FieldOffset(0)] + public readonly byte r; + [FieldOffset(1)] + public readonly byte g; + [FieldOffset(2)] + public readonly byte b; + [FieldOffset(3)] + public readonly byte a; + public Color32Union(byte r, byte g, byte b, byte a) : this() + { + this.r = r; + this.g = g; + this.b = b; + this.a = a; + } + public Color32Union(Color32 color) : this() + { + r = color.r; + g = color.g; + b = color.b; + a = color.a; + } + } + #endregion + } + + public static class ReflectionExtensions + { + public static bool TryGetAttribute(this MemberInfo self, out T attrbiute) where T : Attribute + { + attrbiute = self.GetCustomAttribute(); + return attrbiute != null; + } + public static bool HasAttribute(this MemberInfo self) where T : Attribute + { + return self.GetCustomAttribute() != null; + } + } +} +#endif diff --git a/src/Debug/Editor/EcsEditor.cs.meta b/src/Editor/EditorUtility.cs.meta similarity index 100% rename from src/Debug/Editor/EcsEditor.cs.meta rename to src/Editor/EditorUtility.cs.meta diff --git a/src/Editor/FieldDrawerInfo.cs b/src/Editor/FieldDrawerInfo.cs new file mode 100644 index 0000000..e4c7976 --- /dev/null +++ b/src/Editor/FieldDrawerInfo.cs @@ -0,0 +1,25 @@ +using System; +using System.Reflection; + +namespace DCFApixels.DragonECS.Unity.Editors +{ + public struct FieldDrawerInfo + { + private static readonly BindingFlags fieldFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; + public Type type; + public object data; + public FieldInfo[] fields; + public FieldDrawerInfo(object data) + { + type = data.GetType(); + this.data = data; + fields = type.GetFields(fieldFlags); + } + public void Set(object data) + { + type = data.GetType(); + this.data = data; + fields = type.GetFields(fieldFlags); + } + } +} diff --git a/src/Editor/FieldDrawerInfo.cs.meta b/src/Editor/FieldDrawerInfo.cs.meta new file mode 100644 index 0000000..ba3d1cf --- /dev/null +++ b/src/Editor/FieldDrawerInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9047f4ae8f7a24c4d8b053ffeeb259f7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/EntityTemplate/Editor/EntityTemplateEditor.cs b/src/EntityTemplate/Editor/EntityTemplateEditor.cs index 4f31b38..1ef2a86 100644 --- a/src/EntityTemplate/Editor/EntityTemplateEditor.cs +++ b/src/EntityTemplate/Editor/EntityTemplateEditor.cs @@ -192,7 +192,9 @@ namespace DCFApixels.DragonECS.Unity.Editors GUILayout.Label("", GUILayout.Width(removeButtonRect.width)); if (GUI.Button(removeButtonRect, "x", removeButtonStyle)) + { OnRemoveComponentAt(index); + } if (!string.IsNullOrEmpty(description)) { From 963cd2a286b87f079a992f0137834d66f24fb97b Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Sun, 3 Mar 2024 22:46:26 +0800 Subject: [PATCH 18/50] update editor --- src/Connectors/EcsEntityConnect.cs | 11 +- src/Editor/EditorUtility.cs | 160 +++++++++--------- src/Editor/FieldDrawerInfo.cs | 25 --- src/Editor/SOWrappers.meta | 8 + src/Editor/SOWrappers/RefEditorWrapper.cs | 24 +++ .../RefEditorWrapper.cs.meta} | 2 +- .../SOWrappers/UnityObjEditorWrapper.cs | 24 +++ .../SOWrappers/UnityObjEditorWrapper.cs.meta | 11 ++ src/Editor/SOWrappers/WrapperBase.cs | 73 ++++++++ src/Editor/SOWrappers/WrapperBase.cs.meta | 11 ++ 10 files changed, 231 insertions(+), 118 deletions(-) delete mode 100644 src/Editor/FieldDrawerInfo.cs create mode 100644 src/Editor/SOWrappers.meta create mode 100644 src/Editor/SOWrappers/RefEditorWrapper.cs rename src/Editor/{FieldDrawerInfo.cs.meta => SOWrappers/RefEditorWrapper.cs.meta} (83%) create mode 100644 src/Editor/SOWrappers/UnityObjEditorWrapper.cs create mode 100644 src/Editor/SOWrappers/UnityObjEditorWrapper.cs.meta create mode 100644 src/Editor/SOWrappers/WrapperBase.cs create mode 100644 src/Editor/SOWrappers/WrapperBase.cs.meta diff --git a/src/Connectors/EcsEntityConnect.cs b/src/Connectors/EcsEntityConnect.cs index 4e4a023..5da7a36 100644 --- a/src/Connectors/EcsEntityConnect.cs +++ b/src/Connectors/EcsEntityConnect.cs @@ -178,16 +178,11 @@ namespace DCFApixels.DragonECS.Unity.Editors } else { - //Color defColor = GUI.contentColor; - //Color c = defColor; - //c.a = 0.55f; - //GUI.contentColor = c; GUI.enabled = false; - EditorGUI.TextField(idRect, "Entity ID"); - EditorGUI.TextField(genRect, "Gen"); - EditorGUI.TextField(worldRect, "World ID"); + EditorGUI.TextField(idRect, "Entity ID"); + EditorGUI.TextField(genRect, "Gen"); + EditorGUI.TextField(worldRect, "World ID"); GUI.enabled = true; - //GUI.contentColor = defColor; } } diff --git a/src/Editor/EditorUtility.cs b/src/Editor/EditorUtility.cs index aac050d..4a338b1 100644 --- a/src/Editor/EditorUtility.cs +++ b/src/Editor/EditorUtility.cs @@ -1,67 +1,64 @@ #if UNITY_EDITOR using DCFApixels.DragonECS.Unity.Internal; using System; -using System.Collections.Generic; using System.Reflection; using System.Runtime.InteropServices; +using System.Text; using UnityEditor; using UnityEngine; namespace DCFApixels.DragonECS.Unity.Editors { - internal class WrapperBase : ScriptableObject - where TSelf : WrapperBase + internal static class EcsUnityEditorUtility { - private SerializedObject _so; - private SerializedProperty _property; - - private bool _isReleased = false; - private static Stack _wrappers = new Stack(); - - public SerializedObject SO + public static string TransformFieldName(string name) { - get { return _so; } - } - public SerializedProperty Property - { - get { return _property; } - } - - public static TSelf Take() - { - TSelf result; - if (_wrappers.Count <= 0) + if (name.Length <= 0) { - result = CreateInstance(); - result._so = new SerializedObject(result); - result._property = result._so.FindProperty("data"); + return name; } - else + StringBuilder b = new StringBuilder(); + bool nextWorld = true; + bool prewIsUpper = false; + + + for (int i = 0; i < name.Length; i++) { - result = _wrappers.Pop(); + char c = name[i]; + if (char.IsLetter(c) == false) + { + nextWorld = true; + prewIsUpper = false; + continue; + } + + bool isUpper = char.IsUpper(c); + if (isUpper) + { + if (nextWorld == false && prewIsUpper == false) + { + b.Append(' '); + } + } + else + { + if (nextWorld) + { + b.Append(char.ToUpper(c)); + } + else + { + b.Append(c); + } + nextWorld = false; + } + prewIsUpper = isUpper; } - return result; - } - public static void Release(TSelf wrapper) - { - if (wrapper._isReleased) - { - return; - } - wrapper._isReleased = true; - _wrappers.Push(wrapper); + + return b.ToString(); } } - internal class RefEditorWrapper : WrapperBase - { - [SerializeReference] - public object data; - } - internal class UnityObjEditorWrapper : WrapperBase - { - [SerializeField] - public UnityEngine.Object data; - } + public static class EcsGUI { @@ -177,7 +174,7 @@ namespace DCFApixels.DragonECS.Unity.Editors GUILayout.BeginVertical(EcsEditor.GetStyle(panelColor, 0.22f)); EditorGUI.BeginChangeCheck(); - bool changed = DrawData(pool.ComponentType, data, out object resultData); + bool changed = DrawData(pool.ComponentType, new GUIContent(meta.Name), data, out object resultData); if (changed) { @@ -196,64 +193,59 @@ namespace DCFApixels.DragonECS.Unity.Editors GUILayout.Space(2f); } - private static bool DrawData(Type fieldType, object data, out object outData) + private static bool DrawData(Type fieldType, GUIContent label, object data, out object outData) { - var meta = data.GetMeta(); - GUIContent label = new GUIContent(meta.Name); - Type type = data.GetType(); var uobj = data as UnityEngine.Object; - if (uobj == false && type.IsGenericType) + + if ((uobj == false && type.IsGenericType) || + (uobj == false && !type.IsSerializable)) { bool result = false; - foreach (var field in type.GetFields(fieldFlags)) + WrapperBase w = RefEditorWrapper.Take(EmptyDummy.Instance); + //w.SO.Update(); + //EditorGUILayout.PropertyField(w.Property, label, true); + w.Property.isExpanded = EditorGUILayout.Foldout(w.Property.isExpanded, label); + if (w.Property.isExpanded) { - if (DrawData(field.FieldType, field.GetValue(data), out object fieldData)) + EditorGUI.indentLevel++; + foreach (var field in type.GetFields(fieldFlags)) { - field.SetValue(data, fieldData); - result = true; + GUIContent subLabel = new GUIContent(EcsUnityEditorUtility.TransformFieldName(field.Name)); + if (DrawData(field.FieldType, subLabel, field.GetValue(data), out object fieldData)) + { + field.SetValue(data, fieldData); + result = true; + } } + EditorGUI.indentLevel--; } + w.Release(); outData = data; return result; } else { + EditorGUI.BeginChangeCheck(); + WrapperBase w; if (uobj == null) { - EditorGUI.BeginChangeCheck(); - - var w = RefEditorWrapper.Take(); - w.data = data; - w.SO.Update(); - - EditorGUILayout.PropertyField(w.Property, true); - RefEditorWrapper.Release(w); - - if (EditorGUI.EndChangeCheck()) - { - w.SO.ApplyModifiedProperties(); - outData = w.data; - return true; - } + w = RefEditorWrapper.Take(data); } else { - EditorGUI.BeginChangeCheck(); + w = UnityObjEditorWrapper.Take(uobj); + } + w.SO.Update(); - var w = UnityObjEditorWrapper.Take(); - w.data = uobj; - w.SO.Update(); + EditorGUILayout.PropertyField(w.Property, label, true); + w.Release(); - EditorGUILayout.PropertyField(w.Property, true); - UnityObjEditorWrapper.Release(w); - - if (EditorGUI.EndChangeCheck()) - { - w.SO.ApplyModifiedProperties(); - outData = uobj; - return true; - } + if (EditorGUI.EndChangeCheck()) + { + w.SO.ApplyModifiedProperties(); + outData = w.Data; + return true; } outData = data; diff --git a/src/Editor/FieldDrawerInfo.cs b/src/Editor/FieldDrawerInfo.cs deleted file mode 100644 index e4c7976..0000000 --- a/src/Editor/FieldDrawerInfo.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; -using System.Reflection; - -namespace DCFApixels.DragonECS.Unity.Editors -{ - public struct FieldDrawerInfo - { - private static readonly BindingFlags fieldFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; - public Type type; - public object data; - public FieldInfo[] fields; - public FieldDrawerInfo(object data) - { - type = data.GetType(); - this.data = data; - fields = type.GetFields(fieldFlags); - } - public void Set(object data) - { - type = data.GetType(); - this.data = data; - fields = type.GetFields(fieldFlags); - } - } -} diff --git a/src/Editor/SOWrappers.meta b/src/Editor/SOWrappers.meta new file mode 100644 index 0000000..b4ebbe8 --- /dev/null +++ b/src/Editor/SOWrappers.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: fc9ef2bbe6a95624e9c6d50e19f38a05 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/Editor/SOWrappers/RefEditorWrapper.cs b/src/Editor/SOWrappers/RefEditorWrapper.cs new file mode 100644 index 0000000..059d36b --- /dev/null +++ b/src/Editor/SOWrappers/RefEditorWrapper.cs @@ -0,0 +1,24 @@ +#if UNITY_EDITOR +using System; +using UnityEngine; + +namespace DCFApixels.DragonECS.Unity.Editors +{ + [Serializable] + internal class RefEditorWrapper : WrapperBase + { + [SerializeReference] + public object data; + public override object Data + { + get { return data; } + } + public static RefEditorWrapper Take(object data) + { + var result = Take(); + result.data = data; + return result; + } + } +} +#endif diff --git a/src/Editor/FieldDrawerInfo.cs.meta b/src/Editor/SOWrappers/RefEditorWrapper.cs.meta similarity index 83% rename from src/Editor/FieldDrawerInfo.cs.meta rename to src/Editor/SOWrappers/RefEditorWrapper.cs.meta index ba3d1cf..2a823f7 100644 --- a/src/Editor/FieldDrawerInfo.cs.meta +++ b/src/Editor/SOWrappers/RefEditorWrapper.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 9047f4ae8f7a24c4d8b053ffeeb259f7 +guid: b0f14ae652b89744888db94704a170ef MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/src/Editor/SOWrappers/UnityObjEditorWrapper.cs b/src/Editor/SOWrappers/UnityObjEditorWrapper.cs new file mode 100644 index 0000000..ceaf616 --- /dev/null +++ b/src/Editor/SOWrappers/UnityObjEditorWrapper.cs @@ -0,0 +1,24 @@ +#if UNITY_EDITOR +using System; +using UnityEngine; + +namespace DCFApixels.DragonECS.Unity.Editors +{ + [Serializable] + internal class UnityObjEditorWrapper : WrapperBase + { + [SerializeField] + public UnityEngine.Object data; + public override object Data + { + get { return data; } + } + public static UnityObjEditorWrapper Take(UnityEngine.Object data) + { + var result = Take(); + result.data = data; + return result; + } + } +} +#endif diff --git a/src/Editor/SOWrappers/UnityObjEditorWrapper.cs.meta b/src/Editor/SOWrappers/UnityObjEditorWrapper.cs.meta new file mode 100644 index 0000000..8960b1f --- /dev/null +++ b/src/Editor/SOWrappers/UnityObjEditorWrapper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7060bf63683c82a4a8a6cf54255c4139 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/Editor/SOWrappers/WrapperBase.cs b/src/Editor/SOWrappers/WrapperBase.cs new file mode 100644 index 0000000..6315714 --- /dev/null +++ b/src/Editor/SOWrappers/WrapperBase.cs @@ -0,0 +1,73 @@ +#if UNITY_EDITOR +using System; +using System.Collections.Generic; +using UnityEditor; +using UnityEngine; + +namespace DCFApixels.DragonECS.Unity.Editors +{ + [Serializable] + internal abstract class WrapperBase : ScriptableObject + { + public abstract object Data { get; } + public abstract SerializedObject SO { get; } + public abstract SerializedProperty Property { get; } + public abstract void Release(); + } + [Serializable] + internal abstract class WrapperBase : WrapperBase + where TSelf : WrapperBase + { + private SerializedObject _so; + private SerializedProperty _property; + + private bool _isReleased = false; + private static Stack _wrappers = new Stack(); + public override SerializedObject SO + { + get { return _so; } + } + public override SerializedProperty Property + { + get { return _property; } + } + + public static TSelf Take() + { + TSelf result; + if (_wrappers.Count <= 0) + { + result = CreateInstance(); + result._so = new SerializedObject(result); + result._property = result._so.FindProperty("data"); + } + else + { + result = _wrappers.Pop(); + } + return result; + } + public static void Release(TSelf wrapper) + { + if (wrapper._isReleased) + { + return; + } + wrapper._isReleased = true; + _wrappers.Push(wrapper); + } + + public override void Release() + { + Release((TSelf)this); + } + } + + [Serializable] + public class EmptyDummy + { + public static readonly EmptyDummy Instance = new EmptyDummy(); + private EmptyDummy() { } + } +} +#endif diff --git a/src/Editor/SOWrappers/WrapperBase.cs.meta b/src/Editor/SOWrappers/WrapperBase.cs.meta new file mode 100644 index 0000000..4649771 --- /dev/null +++ b/src/Editor/SOWrappers/WrapperBase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6c0cef58c08259f4bbb78af2fcec4c79 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From f88b07950f1e044eb3d8eef01635302731180865 Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Mon, 4 Mar 2024 03:00:45 +0800 Subject: [PATCH 19/50] fix foldouts --- src/Connectors/AutoEntityCreator.cs | 75 ++++++++++++++++++ src/Connectors/AutoEntityCreator.cs.meta | 11 +++ src/Editor/EditorUtility.cs | 76 ++++++++----------- src/Editor/ExpandMatrix.cs | 57 ++++++++++++++ src/Editor/ExpandMatrix.cs.meta | 11 +++ src/Editor/SOWrappers/RefEditorWrapper.cs | 9 +++ .../SOWrappers/UnityObjEditorWrapper.cs | 2 + src/Editor/SOWrappers/WrapperBase.cs | 29 ++++--- 8 files changed, 218 insertions(+), 52 deletions(-) create mode 100644 src/Connectors/AutoEntityCreator.cs create mode 100644 src/Connectors/AutoEntityCreator.cs.meta create mode 100644 src/Editor/ExpandMatrix.cs create mode 100644 src/Editor/ExpandMatrix.cs.meta diff --git a/src/Connectors/AutoEntityCreator.cs b/src/Connectors/AutoEntityCreator.cs new file mode 100644 index 0000000..18f423c --- /dev/null +++ b/src/Connectors/AutoEntityCreator.cs @@ -0,0 +1,75 @@ +using UnityEngine; + +namespace DCFApixels.DragonECS +{ + public static class EcsDefaultWorldBuilder + { + public static EcsDefaultWorld Build() + { + return new EcsDefaultWorld(); + } + } + + namespace Project.Unity + { + public class AutoEntityCreator : MonoBehaviour + { + [SerializeField] + private EcsEntityConnect _connect; + [SerializeField] + private EcsWorldProviderBase _world; + + private bool _created; + + #region Properties + public EcsEntityConnect Connect => _connect; + #endregion + + #region UnityEvents + private void OnValidate() + { + if (_world == null) + { + AutoResolveWorldProviderDependensy(); + } + } + private void Start() + { + + CreateEntity(); + } + #endregion + + private void AutoResolveWorldProviderDependensy() + { + _world = EcsDefaultWorldSingletonProvider.Instance; + } + public void ManualStart() + { + CreateEntity(); + } + private void CreateEntity() + { + if (_created) + { + return; + } + if (_world == null) + { + AutoResolveWorldProviderDependensy(); + } + else + { + InitConnect(_connect, _world.GetRaw()); + } + _created = true; + } + + private void InitConnect(EcsEntityConnect connect, EcsWorld world) + { + connect.ConnectWith(world.NewEntityLong()); + connect.ApplyTemplates(); + } + } + } +} \ No newline at end of file diff --git a/src/Connectors/AutoEntityCreator.cs.meta b/src/Connectors/AutoEntityCreator.cs.meta new file mode 100644 index 0000000..f8a686f --- /dev/null +++ b/src/Connectors/AutoEntityCreator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e244d7ed454067a4bb82fecd87513856 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/Editor/EditorUtility.cs b/src/Editor/EditorUtility.cs index 4a338b1..7c07174 100644 --- a/src/Editor/EditorUtility.cs +++ b/src/Editor/EditorUtility.cs @@ -1,6 +1,7 @@ #if UNITY_EDITOR using DCFApixels.DragonECS.Unity.Internal; using System; +using System.Collections.Generic; using System.Reflection; using System.Runtime.InteropServices; using System.Text; @@ -38,20 +39,19 @@ namespace DCFApixels.DragonECS.Unity.Editors if (nextWorld == false && prewIsUpper == false) { b.Append(' '); + nextWorld = true; } } + + if (nextWorld) + { + b.Append(char.ToUpper(c)); + } else { - if (nextWorld) - { - b.Append(char.ToUpper(c)); - } - else - { - b.Append(c); - } - nextWorld = false; + b.Append(c); } + nextWorld = false; prewIsUpper = isUpper; } @@ -121,21 +121,13 @@ namespace DCFApixels.DragonECS.Unity.Editors } GUILayout.Box("", options); Rect lastRect = GUILayoutUtility.GetLastRect(); - if (status) - { - Color color = _greenColor; - color.a = 0.6f; - EditorGUI.DrawRect(lastRect, color); - GUI.Box(lastRect, CONNECTED); - } - else - { - Color color = _redColor; - color.a = 0.6f; - EditorGUI.DrawRect(lastRect, color); - GUI.Box(lastRect, NOT_CONNECTED); - } + Color color = status ? _greenColor : _redColor; + string text = status ? CONNECTED : NOT_CONNECTED; + color.a = 0.6f; + EditorGUI.DrawRect(lastRect, color); + GUI.Box(lastRect, text); } + public static void DrawUndeterminedConnectStatus(params GUILayoutOption[] options) { Init(); @@ -174,8 +166,9 @@ namespace DCFApixels.DragonECS.Unity.Editors GUILayout.BeginVertical(EcsEditor.GetStyle(panelColor, 0.22f)); EditorGUI.BeginChangeCheck(); - bool changed = DrawData(pool.ComponentType, new GUIContent(meta.Name), data, out object resultData); - + Type componentType = pool.ComponentType; + ExpandMatrix expandMatrix = ExpandMatrix.Take(componentType); + bool changed = DrawData(componentType, new GUIContent(meta.Name), expandMatrix, data, out object resultData); if (changed) { pool.SetRaw(entityID, resultData); @@ -193,26 +186,26 @@ namespace DCFApixels.DragonECS.Unity.Editors GUILayout.Space(2f); } - private static bool DrawData(Type fieldType, GUIContent label, object data, out object outData) + private static bool DrawData(Type fieldType, GUIContent label, ExpandMatrix expandMatrix, object data, out object outData) { Type type = data.GetType(); var uobj = data as UnityEngine.Object; + ref bool isExpanded = ref expandMatrix.Down(); if ((uobj == false && type.IsGenericType) || (uobj == false && !type.IsSerializable)) { bool result = false; - WrapperBase w = RefEditorWrapper.Take(EmptyDummy.Instance); - //w.SO.Update(); - //EditorGUILayout.PropertyField(w.Property, label, true); - w.Property.isExpanded = EditorGUILayout.Foldout(w.Property.isExpanded, label); - if (w.Property.isExpanded) + + isExpanded = EditorGUILayout.Foldout(isExpanded, label); + + if (isExpanded) { EditorGUI.indentLevel++; foreach (var field in type.GetFields(fieldFlags)) { GUIContent subLabel = new GUIContent(EcsUnityEditorUtility.TransformFieldName(field.Name)); - if (DrawData(field.FieldType, subLabel, field.GetValue(data), out object fieldData)) + if (DrawData(field.FieldType, subLabel, expandMatrix, field.GetValue(data), out object fieldData)) { field.SetValue(data, fieldData); result = true; @@ -220,26 +213,23 @@ namespace DCFApixels.DragonECS.Unity.Editors } EditorGUI.indentLevel--; } - w.Release(); + + expandMatrix.Up(); + outData = data; return result; } else { EditorGUI.BeginChangeCheck(); - WrapperBase w; - if (uobj == null) - { - w = RefEditorWrapper.Take(data); - } - else - { - w = UnityObjEditorWrapper.Take(uobj); - } - w.SO.Update(); + WrapperBase w = uobj == null ? RefEditorWrapper.Take(data) : UnityObjEditorWrapper.Take(uobj); + w.IsExpanded = isExpanded; EditorGUILayout.PropertyField(w.Property, label, true); + isExpanded = w.IsExpanded; + w.Release(); + expandMatrix.Up(); if (EditorGUI.EndChangeCheck()) { diff --git a/src/Editor/ExpandMatrix.cs b/src/Editor/ExpandMatrix.cs new file mode 100644 index 0000000..b3afb6d --- /dev/null +++ b/src/Editor/ExpandMatrix.cs @@ -0,0 +1,57 @@ +#if UNITY_EDITOR +using System; +using System.Collections.Generic; + +namespace DCFApixels.DragonECS.Unity.Editors +{ + internal class ExpandMatrix + { + private const bool TOP_DEFAULT = true; + private const bool DEFAULT = false; + private static Dictionary _instances = new Dictionary(); + public static ExpandMatrix Take(Type type) + { + if(_instances.TryGetValue(type, out ExpandMatrix result) == false) + { + result = new ExpandMatrix(); + _instances.Add(type, result); + } + return result; + } + private bool[] _flags = new bool[8]; + private int _count = 0; + private int _ptr = 0; + + public int Count + { + get { return _count; } + } + public ref bool CurrentIsExpanded + { + get { return ref _flags[_ptr]; } + } + public void Up() + { + if (_ptr < 0) + { + throw new Exception("нарушение баланса инкремент/декремент"); + } + _ptr--; + } + + public ref bool Down() + { + _ptr++; + if (_ptr >= _count) + { + if (_count >= _flags.Length) + { + Array.Resize(ref _flags, _flags.Length << 1); + } + _flags[_count++] = _ptr <= 1 ? TOP_DEFAULT : DEFAULT; + } + return ref _flags[_ptr]; + } + } +} +#endif \ No newline at end of file diff --git a/src/Editor/ExpandMatrix.cs.meta b/src/Editor/ExpandMatrix.cs.meta new file mode 100644 index 0000000..30baaf9 --- /dev/null +++ b/src/Editor/ExpandMatrix.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fef04508ed32be24386f6b2a43e01b2c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/Editor/SOWrappers/RefEditorWrapper.cs b/src/Editor/SOWrappers/RefEditorWrapper.cs index 059d36b..8a5c40e 100644 --- a/src/Editor/SOWrappers/RefEditorWrapper.cs +++ b/src/Editor/SOWrappers/RefEditorWrapper.cs @@ -9,6 +9,7 @@ namespace DCFApixels.DragonECS.Unity.Editors { [SerializeReference] public object data; + public override object Data { get { return data; } @@ -17,8 +18,16 @@ namespace DCFApixels.DragonECS.Unity.Editors { var result = Take(); result.data = data; + result.SO.Update(); return result; } } } + +[Serializable] +public class EmptyDummy +{ + public static readonly EmptyDummy Instance = new EmptyDummy(); + private EmptyDummy() { } +} #endif diff --git a/src/Editor/SOWrappers/UnityObjEditorWrapper.cs b/src/Editor/SOWrappers/UnityObjEditorWrapper.cs index ceaf616..385c092 100644 --- a/src/Editor/SOWrappers/UnityObjEditorWrapper.cs +++ b/src/Editor/SOWrappers/UnityObjEditorWrapper.cs @@ -9,6 +9,7 @@ namespace DCFApixels.DragonECS.Unity.Editors { [SerializeField] public UnityEngine.Object data; + public override object Data { get { return data; } @@ -17,6 +18,7 @@ namespace DCFApixels.DragonECS.Unity.Editors { var result = Take(); result.data = data; + result.SO.Update(); return result; } } diff --git a/src/Editor/SOWrappers/WrapperBase.cs b/src/Editor/SOWrappers/WrapperBase.cs index 6315714..2901e40 100644 --- a/src/Editor/SOWrappers/WrapperBase.cs +++ b/src/Editor/SOWrappers/WrapperBase.cs @@ -10,6 +10,7 @@ namespace DCFApixels.DragonECS.Unity.Editors internal abstract class WrapperBase : ScriptableObject { public abstract object Data { get; } + public abstract bool IsExpanded { get; set; } public abstract SerializedObject SO { get; } public abstract SerializedProperty Property { get; } public abstract void Release(); @@ -21,8 +22,16 @@ namespace DCFApixels.DragonECS.Unity.Editors private SerializedObject _so; private SerializedProperty _property; + private bool _isDestroyed = false; private bool _isReleased = false; + private static Stack _wrappers = new Stack(); + + public override bool IsExpanded + { + get { return Property.isExpanded; } + set { Property.isExpanded = value; } + } public override SerializedObject SO { get { return _so; } @@ -31,7 +40,6 @@ namespace DCFApixels.DragonECS.Unity.Editors { get { return _property; } } - public static TSelf Take() { TSelf result; @@ -44,30 +52,33 @@ namespace DCFApixels.DragonECS.Unity.Editors else { result = _wrappers.Pop(); + if (result._isDestroyed) + { + result = Take(); + } } + result._isReleased = false; return result; } public static void Release(TSelf wrapper) { if (wrapper._isReleased) { - return; + throw new Exception(); } wrapper._isReleased = true; _wrappers.Push(wrapper); } + private void OnDestroy() + { + _isDestroyed = true; + } + public override void Release() { Release((TSelf)this); } } - - [Serializable] - public class EmptyDummy - { - public static readonly EmptyDummy Instance = new EmptyDummy(); - private EmptyDummy() { } - } } #endif From 21f041bd4436dfc25adcfb13d82b032f06484fb9 Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Mon, 4 Mar 2024 07:38:38 +0800 Subject: [PATCH 20/50] update --- src/Connectors/AutoEntityCreator.cs | 140 +++++++++------- src/Connectors/EcsEntityConnect.cs | 87 +++++----- src/Editor/EditorUtility.cs | 154 ++++++++---------- src/Editor/ExpandMatrix.cs | 2 +- src/Editor/RectUtility.cs | 41 +++++ src/Editor/RectUtility.cs.meta | 11 ++ src/Editor/SOWrappers/RefEditorWrapper.cs | 5 +- .../SOWrappers/UnityObjEditorWrapper.cs | 3 + src/Editor/SOWrappers/WrapperBase.cs | 8 + .../Editor/EntityTemplateEditor.cs | 14 +- 10 files changed, 266 insertions(+), 199 deletions(-) create mode 100644 src/Editor/RectUtility.cs create mode 100644 src/Editor/RectUtility.cs.meta diff --git a/src/Connectors/AutoEntityCreator.cs b/src/Connectors/AutoEntityCreator.cs index 18f423c..773360f 100644 --- a/src/Connectors/AutoEntityCreator.cs +++ b/src/Connectors/AutoEntityCreator.cs @@ -2,74 +2,96 @@ using UnityEngine; namespace DCFApixels.DragonECS { - public static class EcsDefaultWorldBuilder + public class AutoEntityCreator : MonoBehaviour { - public static EcsDefaultWorld Build() + [SerializeField] + private EcsEntityConnect _connect; + [SerializeField] + private EcsWorldProviderBase _world; + + private bool _created; + + #region Properties + public EcsEntityConnect Connect => _connect; + #endregion + + #region UnityEvents + private void OnValidate() { - return new EcsDefaultWorld(); + if (_world == null) + { + AutoResolveWorldProviderDependensy(); + } } - } - - namespace Project.Unity - { - public class AutoEntityCreator : MonoBehaviour + private void Start() { - [SerializeField] - private EcsEntityConnect _connect; - [SerializeField] - private EcsWorldProviderBase _world; - private bool _created; + CreateEntity(); + } + #endregion - #region Properties - public EcsEntityConnect Connect => _connect; - #endregion - - #region UnityEvents - private void OnValidate() + private void AutoResolveWorldProviderDependensy() + { + _world = EcsDefaultWorldSingletonProvider.Instance; + } + public void ManualStart() + { + CreateEntity(); + } + private void CreateEntity() + { + if (_created) { - if (_world == null) + return; + } + if (_world == null) + { + AutoResolveWorldProviderDependensy(); + } + else + { + InitConnect(_connect, _world.GetRaw()); + } + _created = true; + } + + private void InitConnect(EcsEntityConnect connect, EcsWorld world) + { + connect.ConnectWith(world.NewEntityLong()); + connect.ApplyTemplates(); + } + +#if UNITY_EDITOR + internal void Autoset_Editor() + { + _connect = GetComponentInChildren(); + } +#endif + } +} + +#if UNITY_EDITOR +namespace DCFApixels.DragonECS.Unity.Editors +{ + using UnityEditor; + + [CustomEditor(typeof(AutoEntityCreator))] + [CanEditMultipleObjects] + public class AutoEntityCreatorEditor : Editor + { + public override void OnInspectorGUI() + { + base.OnInspectorGUI(); + if (GUILayout.Button("Autoset")) + { + foreach (var tr in targets) { - AutoResolveWorldProviderDependensy(); + AutoEntityCreator creator = (AutoEntityCreator)tr; + creator.Autoset_Editor(); + EditorUtility.SetDirty(creator); } } - private void Start() - { - - CreateEntity(); - } - #endregion - - private void AutoResolveWorldProviderDependensy() - { - _world = EcsDefaultWorldSingletonProvider.Instance; - } - public void ManualStart() - { - CreateEntity(); - } - private void CreateEntity() - { - if (_created) - { - return; - } - if (_world == null) - { - AutoResolveWorldProviderDependensy(); - } - else - { - InitConnect(_connect, _world.GetRaw()); - } - _created = true; - } - - private void InitConnect(EcsEntityConnect connect, EcsWorld world) - { - connect.ConnectWith(world.NewEntityLong()); - connect.ApplyTemplates(); - } } } -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/src/Connectors/EcsEntityConnect.cs b/src/Connectors/EcsEntityConnect.cs index 5da7a36..de9aa1f 100644 --- a/src/Connectors/EcsEntityConnect.cs +++ b/src/Connectors/EcsEntityConnect.cs @@ -91,7 +91,9 @@ namespace DCFApixels.DragonECS #if UNITY_EDITOR namespace DCFApixels.DragonECS.Unity.Editors { + using DCFApixels.DragonECS.Unity.Internal; using UnityEditor; + using static Codice.CM.WorkspaceServer.WorkspaceTreeDataStore; [CustomEditor(typeof(EcsEntityConnect))] [CanEditMultipleObjects] @@ -120,8 +122,7 @@ namespace DCFApixels.DragonECS.Unity.Editors } DrawTop(); - DrawConnectStatus(targets); - DrawEntityInfo(); + DrawEntityInfo(targets); DrawTemplates(); @@ -132,57 +133,48 @@ namespace DCFApixels.DragonECS.Unity.Editors { var iterator = serializedObject.GetIterator(); iterator.NextVisible(true); - using (new EditorGUI.DisabledScope("m_Script" == iterator.propertyPath)) + using (new EditorGUI.DisabledScope(true)) { EditorGUILayout.PropertyField(iterator, true); } } - private void DrawConnectStatus(EcsEntityConnect[] targets) - { - bool isConnected = Target.IsConected; - for (int i = 0; i < targets.Length; i++) - { - if (isConnected != targets[i].IsConected) - { - isConnected = !Target.IsConected; - break; - } - } - if (isConnected == Target.IsConected) - { - EcsGUI.Layout.DrawConnectStatus(Target.IsConected); - } - else - { - EcsGUI.Layout.DrawUndeterminedConnectStatus(); - } - } - private void DrawEntityInfo() + private void DrawEntityInfo(EcsEntityConnect[] targets) { - GUILayout.Label(string.Empty); - Rect entityRect = GUILayoutUtility.GetLastRect(); - Rect idRect = entityRect; - idRect.xMax -= idRect.width / 2f; - Rect genRect = entityRect; - genRect.xMin = idRect.xMax; - genRect.xMax -= genRect.width / 2f; - Rect worldRect = genRect; - worldRect.x += worldRect.width; + float width = EditorGUIUtility.currentViewWidth; + float height = EditorGUIUtility.singleLineHeight; + Rect entityRect = GUILayoutUtility.GetRect(width, height + 3f); - if (IsMultipleTargets == false && Target.Entity.TryUnpack(out int id, out short gen, out short world)) + var (entityInfoRect, statusRect) = RectUtility.VerticalSliceBottom(entityRect, 3f); + + var (idRect, genWorldRect) = RectUtility.HorizontalSliceLerp(entityInfoRect, 0.5f); + var (genRect, worldRect) = RectUtility.HorizontalSliceLerp(genWorldRect, 0.5f); + + + + bool isConnected = Target.Entity.TryUnpack(out int id, out short gen, out short world); + + + if (IsMultipleTargets == false && isConnected) { + Color statusColor = EcsGUI.GreenColor; + statusColor.a = 0.32f; + EditorGUI.DrawRect(statusRect, statusColor); EditorGUI.IntField(idRect, id); EditorGUI.IntField(genRect, gen); EditorGUI.IntField(worldRect, world); } else { - GUI.enabled = false; - EditorGUI.TextField(idRect, "Entity ID"); - EditorGUI.TextField(genRect, "Gen"); - EditorGUI.TextField(worldRect, "World ID"); - GUI.enabled = true; + using (new EditorGUI.DisabledScope(true)) + { + Color statusColor = IsMultipleTargets ? EcsGUI.GrayColor : EcsGUI.RedColor; + statusColor.a = 0.32f; + EditorGUI.DrawRect(statusRect, statusColor); + EditorGUI.TextField(idRect, "Entity ID"); + EditorGUI.TextField(genRect, "Gen"); + EditorGUI.TextField(worldRect, "World ID"); + } } } @@ -193,22 +185,20 @@ namespace DCFApixels.DragonECS.Unity.Editors bool enterChildren = true; while (iterator.NextVisible(enterChildren)) { - using (new EditorGUI.DisabledScope("m_Script" == iterator.propertyPath)) - { - EditorGUILayout.PropertyField(iterator, true); - } + EditorGUILayout.PropertyField(iterator, true); enterChildren = false; } } private void DrawButtons() { - if (GUILayout.Button("Autoset Templates")) + GUILayout.BeginHorizontal(); + if (GUILayout.Button("Autoset")) { Target.SetTemplates_Editor(Target.GetComponents()); EditorUtility.SetDirty(target); } - if (GUILayout.Button("Autoset Templates Cascade")) + if (GUILayout.Button("Autoset Cascade")) { foreach (var item in Target.GetComponentsInChildren()) { @@ -216,6 +206,7 @@ namespace DCFApixels.DragonECS.Unity.Editors EditorUtility.SetDirty(item); } } + GUILayout.EndHorizontal(); } private void DrawComponents(EcsEntityConnect[] targets) @@ -227,13 +218,13 @@ namespace DCFApixels.DragonECS.Unity.Editors if (targets[i].IsConected == true) { EditorGUILayout.HelpBox("Multiple component editing is not available.", MessageType.Warning); - break; + return; } } } - if (Target.IsConected) + if (Target.Entity.TryUnpack(out int entityID, out EcsWorld world)) { - EcsGUI.Layout.DrawComponents(Target.Entity); + EcsGUI.Layout.DrawComponents(entityID, world); } } } diff --git a/src/Editor/EditorUtility.cs b/src/Editor/EditorUtility.cs index 7c07174..5272caa 100644 --- a/src/Editor/EditorUtility.cs +++ b/src/Editor/EditorUtility.cs @@ -1,7 +1,6 @@ #if UNITY_EDITOR using DCFApixels.DragonECS.Unity.Internal; using System; -using System.Collections.Generic; using System.Reflection; using System.Runtime.InteropServices; using System.Text; @@ -60,15 +59,15 @@ namespace DCFApixels.DragonECS.Unity.Editors } - public static class EcsGUI + internal static class EcsGUI { - private static Color _grayColor = new Color32(100, 100, 100, 100); - private static Color _greenColor = new Color32(75, 255, 0, 100); - private static Color _redColor = new Color32(255, 0, 75, 100); + internal readonly static Color GrayColor = new Color32(100, 100, 100, 255); + internal readonly static Color GreenColor = new Color32(75, 255, 0, 255); + internal readonly static Color RedColor = new Color32(255, 0, 75, 255); - private static GUIStyle _grayStyle; - private static GUIStyle _greenStyle; - private static GUIStyle _redStyle; + //private static GUIStyle _grayStyle; + //private static GUIStyle _greenStyle; + //private static GUIStyle _redStyle; private static GUILayoutOption[] _defaultParams; private static bool _isInit = false; @@ -81,62 +80,62 @@ namespace DCFApixels.DragonECS.Unity.Editors } _defaultParams = new GUILayoutOption[] { GUILayout.ExpandWidth(true) }; - _grayStyle = EcsEditor.GetStyle(_grayColor); - _greenStyle = EcsEditor.GetStyle(_greenColor); - _redStyle = EcsEditor.GetStyle(_redColor); + //_grayStyle = EcsEditor.GetStyle(GrayColor); + //_greenStyle = EcsEditor.GetStyle(GreenColor); + //_redStyle = EcsEditor.GetStyle(RedColor); _isInit = true; } - private const string CONNECTED = "Connected"; - private const string NOT_CONNECTED = "Not connected"; - private const string UNDETERMINED_CONNECTED = "---"; - public static void DrawConnectStatus(Rect position, bool status) - { - Init(); - if (status) - { - GUI.Box(position, CONNECTED, _greenStyle); - } - else - { - GUI.Box(position, NOT_CONNECTED, _redStyle); - } - } - - public static void DrawUndeterminedConnectStatus(Rect position) - { - Init(); - GUI.Box(position, UNDETERMINED_CONNECTED, _grayStyle); - } + //private const string CONNECTED = "Connected"; + //private const string NOT_CONNECTED = "Not connected"; + //private const string UNDETERMINED_CONNECTED = "---"; + //public static void DrawConnectStatus(Rect position, bool status) + //{ + // Init(); + // if (status) + // { + // GUI.Box(position, CONNECTED, _greenStyle); + // } + // else + // { + // GUI.Box(position, NOT_CONNECTED, _redStyle); + // } + //} + // + //public static void DrawUndeterminedConnectStatus(Rect position) + //{ + // Init(); + // GUI.Box(position, UNDETERMINED_CONNECTED, _grayStyle); + //} public static class Layout { - public static void DrawConnectStatus(bool status, params GUILayoutOption[] options) - { - Init(); - if (options == null || options.Length <= 0) - { - options = _defaultParams; - } - GUILayout.Box("", options); - Rect lastRect = GUILayoutUtility.GetLastRect(); - Color color = status ? _greenColor : _redColor; - string text = status ? CONNECTED : NOT_CONNECTED; - color.a = 0.6f; - EditorGUI.DrawRect(lastRect, color); - GUI.Box(lastRect, text); - } + //public static void DrawConnectStatus(bool status, params GUILayoutOption[] options) + //{ + // Init(); + // if (options == null || options.Length <= 0) + // { + // options = _defaultParams; + // } + // GUILayout.Box("", options); + // Rect lastRect = GUILayoutUtility.GetLastRect(); + // Color color = status ? GreenColor : RedColor; + // string text = status ? CONNECTED : NOT_CONNECTED; + // color.a = 0.6f; + // EditorGUI.DrawRect(lastRect, color); + // GUI.Box(lastRect, text); + //} - public static void DrawUndeterminedConnectStatus(params GUILayoutOption[] options) - { - Init(); - if (options == null || options.Length <= 0) - { - options = _defaultParams; - } - GUILayout.Box(UNDETERMINED_CONNECTED, _grayStyle, options); - } + //public static void DrawUndeterminedConnectStatus(params GUILayoutOption[] options) + //{ + // Init(); + // if (options == null || options.Length <= 0) + // { + // options = _defaultParams; + // } + // GUILayout.Box(UNDETERMINED_CONNECTED, _grayStyle, options); + //} public static void DrawComponents(entlong entity) { if (entity.TryUnpack(out int entityID, out EcsWorld world)) @@ -147,17 +146,18 @@ namespace DCFApixels.DragonECS.Unity.Editors public static void DrawComponents(int entityID, EcsWorld world) { var componentTypeIDs = world.GetComponentTypeIDs(entityID); - + GUILayout.BeginVertical(EcsEditor.GetStyle(Color.black, 0.2f)); foreach (var componentTypeID in componentTypeIDs) { var pool = world.GetPool(componentTypeID); { - DrawComponent(entityID, world, pool); + DrawComponent(entityID, pool); } } + GUILayout.EndVertical(); } private static readonly BindingFlags fieldFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; - private static void DrawComponent(int entityID, EcsWorld world, IEcsPool pool) + private static void DrawComponent(int entityID, IEcsPool pool) { object data = pool.GetRaw(entityID); var meta = data.GetMeta(); @@ -176,27 +176,19 @@ namespace DCFApixels.DragonECS.Unity.Editors GUILayout.EndVertical(); - Rect lineRect = GUILayoutUtility.GetLastRect(); - lineRect.y = lineRect.yMax; - lineRect.height = 3f; - Color rectColor = panelColor; - rectColor.a = 0.34f; - EditorGUI.DrawRect(lineRect, rectColor); - GUILayout.Space(2f); } private static bool DrawData(Type fieldType, GUIContent label, ExpandMatrix expandMatrix, object data, out object outData) { Type type = data.GetType(); - var uobj = data as UnityEngine.Object; + UnityEngine.Object uobj = data as UnityEngine.Object; ref bool isExpanded = ref expandMatrix.Down(); + bool changed = false; + outData = data; - if ((uobj == false && type.IsGenericType) || - (uobj == false && !type.IsSerializable)) + if (uobj == null && (type.IsGenericType || !type.IsSerializable)) { - bool result = false; - isExpanded = EditorGUILayout.Foldout(isExpanded, label); if (isExpanded) @@ -208,16 +200,13 @@ namespace DCFApixels.DragonECS.Unity.Editors if (DrawData(field.FieldType, subLabel, expandMatrix, field.GetValue(data), out object fieldData)) { field.SetValue(data, fieldData); - result = true; + + outData = fieldData; + changed = true; } } EditorGUI.indentLevel--; } - - expandMatrix.Up(); - - outData = data; - return result; } else { @@ -228,19 +217,16 @@ namespace DCFApixels.DragonECS.Unity.Editors EditorGUILayout.PropertyField(w.Property, label, true); isExpanded = w.IsExpanded; - w.Release(); - expandMatrix.Up(); - if (EditorGUI.EndChangeCheck()) { w.SO.ApplyModifiedProperties(); outData = w.Data; - return true; + changed = true; } - - outData = data; - return false; } + + expandMatrix.Up(); + return changed; } } } diff --git a/src/Editor/ExpandMatrix.cs b/src/Editor/ExpandMatrix.cs index b3afb6d..8bf25c0 100644 --- a/src/Editor/ExpandMatrix.cs +++ b/src/Editor/ExpandMatrix.cs @@ -11,7 +11,7 @@ namespace DCFApixels.DragonECS.Unity.Editors private static Dictionary _instances = new Dictionary(); public static ExpandMatrix Take(Type type) { - if(_instances.TryGetValue(type, out ExpandMatrix result) == false) + if (_instances.TryGetValue(type, out ExpandMatrix result) == false) { result = new ExpandMatrix(); _instances.Add(type, result); diff --git a/src/Editor/RectUtility.cs b/src/Editor/RectUtility.cs new file mode 100644 index 0000000..97c99af --- /dev/null +++ b/src/Editor/RectUtility.cs @@ -0,0 +1,41 @@ +using UnityEngine; + +namespace DCFApixels.DragonECS.Unity.Internal +{ + internal static class RectUtility + { + public static (Rect, Rect) HorizontalSliceLerp(Rect rect, float t) + { + Rect l = rect; + Rect r = rect; + l.xMax -= rect.width * (1f - t); + r.xMin += rect.width * t; + return (l, r); + } + public static (Rect, Rect) HorizontalSliceLeft(Rect rect, float with) + { + Rect l = rect; + Rect r = rect; + l.xMax = l.xMin + with; + r.xMin += with; + return (l, r); + } + public static (Rect, Rect) HorizontalSliceRight(Rect rect, float with) + { + Rect l = rect; + Rect r = rect; + l.xMax -= with; + r.xMin = r.xMax - with; + return (l, r); + } + + public static (Rect, Rect) VerticalSliceBottom(Rect rect, float height) + { + Rect t = rect; + Rect b = rect; + t.yMax -= height; + b.yMin = b.yMax - height; + return (t, b); + } + } +} diff --git a/src/Editor/RectUtility.cs.meta b/src/Editor/RectUtility.cs.meta new file mode 100644 index 0000000..f61539f --- /dev/null +++ b/src/Editor/RectUtility.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8e275376d670bdd4c986d661838ed6b4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/Editor/SOWrappers/RefEditorWrapper.cs b/src/Editor/SOWrappers/RefEditorWrapper.cs index 8a5c40e..9ba3369 100644 --- a/src/Editor/SOWrappers/RefEditorWrapper.cs +++ b/src/Editor/SOWrappers/RefEditorWrapper.cs @@ -1,5 +1,6 @@ -#if UNITY_EDITOR + #if UNITY_EDITOR using System; +using System.Runtime.CompilerServices; using UnityEngine; namespace DCFApixels.DragonECS.Unity.Editors @@ -12,8 +13,10 @@ namespace DCFApixels.DragonECS.Unity.Editors public override object Data { + [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return data; } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static RefEditorWrapper Take(object data) { var result = Take(); diff --git a/src/Editor/SOWrappers/UnityObjEditorWrapper.cs b/src/Editor/SOWrappers/UnityObjEditorWrapper.cs index 385c092..fdb96d6 100644 --- a/src/Editor/SOWrappers/UnityObjEditorWrapper.cs +++ b/src/Editor/SOWrappers/UnityObjEditorWrapper.cs @@ -1,5 +1,6 @@ #if UNITY_EDITOR using System; +using System.Runtime.CompilerServices; using UnityEngine; namespace DCFApixels.DragonECS.Unity.Editors @@ -12,8 +13,10 @@ namespace DCFApixels.DragonECS.Unity.Editors public override object Data { + [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return data; } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static UnityObjEditorWrapper Take(UnityEngine.Object data) { var result = Take(); diff --git a/src/Editor/SOWrappers/WrapperBase.cs b/src/Editor/SOWrappers/WrapperBase.cs index 2901e40..d068d01 100644 --- a/src/Editor/SOWrappers/WrapperBase.cs +++ b/src/Editor/SOWrappers/WrapperBase.cs @@ -1,6 +1,7 @@ #if UNITY_EDITOR using System; using System.Collections.Generic; +using System.Runtime.CompilerServices; using UnityEditor; using UnityEngine; @@ -29,17 +30,22 @@ namespace DCFApixels.DragonECS.Unity.Editors public override bool IsExpanded { + [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return Property.isExpanded; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] set { Property.isExpanded = value; } } public override SerializedObject SO { + [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return _so; } } public override SerializedProperty Property { + [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return _property; } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static TSelf Take() { TSelf result; @@ -60,6 +66,7 @@ namespace DCFApixels.DragonECS.Unity.Editors result._isReleased = false; return result; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Release(TSelf wrapper) { if (wrapper._isReleased) @@ -75,6 +82,7 @@ namespace DCFApixels.DragonECS.Unity.Editors _isDestroyed = true; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public override void Release() { Release((TSelf)this); diff --git a/src/EntityTemplate/Editor/EntityTemplateEditor.cs b/src/EntityTemplate/Editor/EntityTemplateEditor.cs index 1ef2a86..5b98b33 100644 --- a/src/EntityTemplate/Editor/EntityTemplateEditor.cs +++ b/src/EntityTemplate/Editor/EntityTemplateEditor.cs @@ -99,11 +99,13 @@ namespace DCFApixels.DragonECS.Unity.Editors return; DrawTop(target); + GUILayout.BeginVertical(EcsEditor.GetStyle(Color.black, 0.2f)); for (int i = 0; i < componentsProp.arraySize; i++) { DrawComponentData(componentsProp.GetArrayElementAtIndex(i), i); GUILayout.Space(EditorGUIUtility.standardVerticalSpacing * 2); } + GUILayout.EndVertical(); DrawFooter(target); } private void DrawTop(ITemplateInternal target) @@ -183,12 +185,12 @@ namespace DCFApixels.DragonECS.Unity.Editors removeButtonRect.center = new Vector2(lastrect.xMax + removeButtonRect.width, lastrect.yMin + removeButtonRect.height / 2f); GUILayout.EndVertical(); - Rect lineRect = GUILayoutUtility.GetLastRect(); - lineRect.y = lineRect.yMax; - lineRect.height = 3f; - Color rectColor = panelColor; - rectColor.a = 0.34f; - EditorGUI.DrawRect(lineRect, rectColor); + //Rect lineRect = GUILayoutUtility.GetLastRect(); + //lineRect.y = lineRect.yMax; + //lineRect.height = 3f; + //Color rectColor = panelColor; + //rectColor.a = 0.34f; + //EditorGUI.DrawRect(lineRect, rectColor); GUILayout.Label("", GUILayout.Width(removeButtonRect.width)); if (GUI.Button(removeButtonRect, "x", removeButtonStyle)) From 4afce1c4487d0f4b6e4bd41750b55dc21b26bd33 Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Mon, 4 Mar 2024 08:01:49 +0800 Subject: [PATCH 21/50] Update EditorUtility.cs --- src/Editor/EditorUtility.cs | 113 +++++++++++------------------------- 1 file changed, 33 insertions(+), 80 deletions(-) diff --git a/src/Editor/EditorUtility.cs b/src/Editor/EditorUtility.cs index 5272caa..3f02756 100644 --- a/src/Editor/EditorUtility.cs +++ b/src/Editor/EditorUtility.cs @@ -65,77 +65,25 @@ namespace DCFApixels.DragonECS.Unity.Editors internal readonly static Color GreenColor = new Color32(75, 255, 0, 255); internal readonly static Color RedColor = new Color32(255, 0, 75, 255); - //private static GUIStyle _grayStyle; - //private static GUIStyle _greenStyle; - //private static GUIStyle _redStyle; - private static GUILayoutOption[] _defaultParams; - - private static bool _isInit = false; - - private static void Init() - { - if (_isInit) - { - return; - } - - _defaultParams = new GUILayoutOption[] { GUILayout.ExpandWidth(true) }; - //_grayStyle = EcsEditor.GetStyle(GrayColor); - //_greenStyle = EcsEditor.GetStyle(GreenColor); - //_redStyle = EcsEditor.GetStyle(RedColor); - _isInit = true; - } - - - //private const string CONNECTED = "Connected"; - //private const string NOT_CONNECTED = "Not connected"; - //private const string UNDETERMINED_CONNECTED = "---"; - //public static void DrawConnectStatus(Rect position, bool status) + //private static GUILayoutOption[] _defaultParams; + //private static bool _isInit = false; + //private static void Init() //{ - // Init(); - // if (status) + // if (_isInit) // { - // GUI.Box(position, CONNECTED, _greenStyle); + // return; // } - // else - // { - // GUI.Box(position, NOT_CONNECTED, _redStyle); - // } - //} - // - //public static void DrawUndeterminedConnectStatus(Rect position) - //{ - // Init(); - // GUI.Box(position, UNDETERMINED_CONNECTED, _grayStyle); + // _defaultParams = new GUILayoutOption[] { GUILayout.ExpandWidth(true) }; + // _isInit = true; //} public static class Layout { - //public static void DrawConnectStatus(bool status, params GUILayoutOption[] options) - //{ - // Init(); - // if (options == null || options.Length <= 0) - // { - // options = _defaultParams; - // } - // GUILayout.Box("", options); - // Rect lastRect = GUILayoutUtility.GetLastRect(); - // Color color = status ? GreenColor : RedColor; - // string text = status ? CONNECTED : NOT_CONNECTED; - // color.a = 0.6f; - // EditorGUI.DrawRect(lastRect, color); - // GUI.Box(lastRect, text); - //} - - //public static void DrawUndeterminedConnectStatus(params GUILayoutOption[] options) - //{ - // Init(); - // if (options == null || options.Length <= 0) - // { - // options = _defaultParams; - // } - // GUILayout.Box(UNDETERMINED_CONNECTED, _grayStyle, options); - //} + private static bool IsShowHidden + { + get { return DebugMonitorPrefs.instance.IsShowHidden; } + set { DebugMonitorPrefs.instance.IsShowHidden = value; } + } public static void DrawComponents(entlong entity) { if (entity.TryUnpack(out int entityID, out EcsWorld world)) @@ -146,7 +94,11 @@ namespace DCFApixels.DragonECS.Unity.Editors public static void DrawComponents(int entityID, EcsWorld world) { var componentTypeIDs = world.GetComponentTypeIDs(entityID); + GUILayout.BeginVertical(EcsEditor.GetStyle(Color.black, 0.2f)); + GUILayout.Label("COMPONENTS"); + IsShowHidden = EditorGUILayout.Toggle("Show Hidden", IsShowHidden); + foreach (var componentTypeID in componentTypeIDs) { var pool = world.GetPool(componentTypeID); @@ -159,24 +111,25 @@ namespace DCFApixels.DragonECS.Unity.Editors private static readonly BindingFlags fieldFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; private static void DrawComponent(int entityID, IEcsPool pool) { - object data = pool.GetRaw(entityID); - var meta = data.GetMeta(); - - Color panelColor = meta.Color.ToUnityColor(); - GUILayout.BeginVertical(EcsEditor.GetStyle(panelColor, 0.22f)); - EditorGUI.BeginChangeCheck(); - - Type componentType = pool.ComponentType; - ExpandMatrix expandMatrix = ExpandMatrix.Take(componentType); - bool changed = DrawData(componentType, new GUIContent(meta.Name), expandMatrix, data, out object resultData); - if (changed) + var meta = pool.ComponentType.ToMeta(); + if (meta.IsHidden == false || IsShowHidden) { - pool.SetRaw(entityID, resultData); + object data = pool.GetRaw(entityID); + Color panelColor = meta.Color.ToUnityColor(); + GUILayout.BeginVertical(EcsEditor.GetStyle(panelColor, 0.22f)); + EditorGUI.BeginChangeCheck(); + + Type componentType = pool.ComponentType; + ExpandMatrix expandMatrix = ExpandMatrix.Take(componentType); + bool changed = DrawData(componentType, new GUIContent(meta.Name), expandMatrix, data, out object resultData); + if (changed) + { + pool.SetRaw(entityID, resultData); + } + + GUILayout.EndVertical(); + GUILayout.Space(2f); } - - GUILayout.EndVertical(); - - GUILayout.Space(2f); } private static bool DrawData(Type fieldType, GUIContent label, ExpandMatrix expandMatrix, object data, out object outData) From 1176853cd5fe699ccb37412f029ee52964792e45 Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Mon, 4 Mar 2024 08:21:01 +0800 Subject: [PATCH 22/50] upddate --- .../EcsDefaultWorldSingletonProvider.cs | 2 +- src/Connectors/AutoEntityCreator.cs | 1 + src/Connectors/EcsEntityConnect.cs | 2 +- src/Debug/Editor/DebugMonitorPrefs.cs | 24 ++++++++++++-- src/Editor/EditorUtility.cs | 33 ++++++++++++------- 5 files changed, 45 insertions(+), 17 deletions(-) diff --git a/src/Buildin/EcsDefaultWorldSingletonProvider.cs b/src/Buildin/EcsDefaultWorldSingletonProvider.cs index 956c326..c05aecc 100644 --- a/src/Buildin/EcsDefaultWorldSingletonProvider.cs +++ b/src/Buildin/EcsDefaultWorldSingletonProvider.cs @@ -9,7 +9,7 @@ { if (_instance == null) { - _instance = FindOrCreateSingleton("DefaultSingletonProvider"); + _instance = FindOrCreateSingleton("SingletonDefaultWorld"); } return _instance; } diff --git a/src/Connectors/AutoEntityCreator.cs b/src/Connectors/AutoEntityCreator.cs index 773360f..14ae2d7 100644 --- a/src/Connectors/AutoEntityCreator.cs +++ b/src/Connectors/AutoEntityCreator.cs @@ -65,6 +65,7 @@ namespace DCFApixels.DragonECS internal void Autoset_Editor() { _connect = GetComponentInChildren(); + AutoResolveWorldProviderDependensy(); } #endif } diff --git a/src/Connectors/EcsEntityConnect.cs b/src/Connectors/EcsEntityConnect.cs index de9aa1f..1e66505 100644 --- a/src/Connectors/EcsEntityConnect.cs +++ b/src/Connectors/EcsEntityConnect.cs @@ -224,7 +224,7 @@ namespace DCFApixels.DragonECS.Unity.Editors } if (Target.Entity.TryUnpack(out int entityID, out EcsWorld world)) { - EcsGUI.Layout.DrawComponents(entityID, world); + EcsGUI.Layout.DrawRuntimeComponents(entityID, world); } } } diff --git a/src/Debug/Editor/DebugMonitorPrefs.cs b/src/Debug/Editor/DebugMonitorPrefs.cs index b6385e7..5b2e722 100644 --- a/src/Debug/Editor/DebugMonitorPrefs.cs +++ b/src/Debug/Editor/DebugMonitorPrefs.cs @@ -1,4 +1,5 @@ #if UNITY_EDITOR +using UnityEngine; using UnityEditor; namespace DCFApixels.DragonECS.Unity.Editors @@ -6,29 +7,46 @@ namespace DCFApixels.DragonECS.Unity.Editors [FilePath(EcsConsts.FRAMEWORK_NAME + "/" + nameof(DebugMonitorPrefs) + ".prefs", FilePathAttribute.Location.ProjectFolder)] public class DebugMonitorPrefs : ScriptableSingleton { + [SerializeField] private bool _isShowInterfaces = false; public bool IsShowInterfaces { - get => _isShowInterfaces; set + get => _isShowInterfaces; + set { _isShowInterfaces = value; Save(false); } } + [SerializeField] private bool _isShowHidden = false; public bool IsShowHidden { - get => _isShowHidden; set + get => _isShowHidden; + set { _isShowHidden = value; Save(false); } } + [SerializeField] + private bool _isShowRuntimeComponents = true; + public bool IsShowRuntimeComponents + { + get => _isShowRuntimeComponents; + set + { + _isShowRuntimeComponents = value; + Save(false); + } + } + [SerializeField] private bool _poolsToggle = false; public bool PoolsToggle { - get => _poolsToggle; set + get => _poolsToggle; + set { _poolsToggle = value; Save(false); diff --git a/src/Editor/EditorUtility.cs b/src/Editor/EditorUtility.cs index 3f02756..f17bc5b 100644 --- a/src/Editor/EditorUtility.cs +++ b/src/Editor/EditorUtility.cs @@ -84,32 +84,41 @@ namespace DCFApixels.DragonECS.Unity.Editors get { return DebugMonitorPrefs.instance.IsShowHidden; } set { DebugMonitorPrefs.instance.IsShowHidden = value; } } - public static void DrawComponents(entlong entity) + private static bool IsShowRuntimeComponents + { + get { return DebugMonitorPrefs.instance.IsShowRuntimeComponents; } + set { DebugMonitorPrefs.instance.IsShowRuntimeComponents = value; } + } + public static void DrawRuntimeComponents(entlong entity) { if (entity.TryUnpack(out int entityID, out EcsWorld world)) { - DrawComponents(entityID, world); + DrawRuntimeComponents(entityID, world); } } - public static void DrawComponents(int entityID, EcsWorld world) + public static void DrawRuntimeComponents(int entityID, EcsWorld world) { var componentTypeIDs = world.GetComponentTypeIDs(entityID); GUILayout.BeginVertical(EcsEditor.GetStyle(Color.black, 0.2f)); - GUILayout.Label("COMPONENTS"); - IsShowHidden = EditorGUILayout.Toggle("Show Hidden", IsShowHidden); - foreach (var componentTypeID in componentTypeIDs) + IsShowRuntimeComponents = EditorGUILayout.Foldout(IsShowRuntimeComponents, "RUNTIME COMPONENTS"); + if (IsShowRuntimeComponents) { - var pool = world.GetPool(componentTypeID); + //TODO галочкаслишком чернаяя, невидно + IsShowHidden = EditorGUILayout.Toggle("Show Hidden", IsShowHiddens); + foreach (var componentTypeID in componentTypeIDs) { - DrawComponent(entityID, pool); + var pool = world.GetPool(componentTypeID); + { + DrawRuntimeComponent(entityID, pool); + } } } GUILayout.EndVertical(); } private static readonly BindingFlags fieldFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; - private static void DrawComponent(int entityID, IEcsPool pool) + private static void DrawRuntimeComponent(int entityID, IEcsPool pool) { var meta = pool.ComponentType.ToMeta(); if (meta.IsHidden == false || IsShowHidden) @@ -121,7 +130,7 @@ namespace DCFApixels.DragonECS.Unity.Editors Type componentType = pool.ComponentType; ExpandMatrix expandMatrix = ExpandMatrix.Take(componentType); - bool changed = DrawData(componentType, new GUIContent(meta.Name), expandMatrix, data, out object resultData); + bool changed = DrawRuntimeData(componentType, new GUIContent(meta.Name), expandMatrix, data, out object resultData); if (changed) { pool.SetRaw(entityID, resultData); @@ -132,7 +141,7 @@ namespace DCFApixels.DragonECS.Unity.Editors } } - private static bool DrawData(Type fieldType, GUIContent label, ExpandMatrix expandMatrix, object data, out object outData) + private static bool DrawRuntimeData(Type fieldType, GUIContent label, ExpandMatrix expandMatrix, object data, out object outData) { Type type = data.GetType(); UnityEngine.Object uobj = data as UnityEngine.Object; @@ -150,7 +159,7 @@ namespace DCFApixels.DragonECS.Unity.Editors foreach (var field in type.GetFields(fieldFlags)) { GUIContent subLabel = new GUIContent(EcsUnityEditorUtility.TransformFieldName(field.Name)); - if (DrawData(field.FieldType, subLabel, expandMatrix, field.GetValue(data), out object fieldData)) + if (DrawRuntimeData(field.FieldType, subLabel, expandMatrix, field.GetValue(data), out object fieldData)) { field.SetValue(data, fieldData); From 8bba0a01f818ab0b638139b340885ca7902ff7a4 Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Tue, 5 Mar 2024 00:46:47 +0800 Subject: [PATCH 23/50] update --- src/Editor/ColorUtility.cs | 20 +++++ src/Editor/ColorUtility.cs.meta | 11 +++ src/Editor/EditorUtility.cs | 12 +-- src/Editor/EscEditorConsts.cs | 14 ++++ src/Editor/EscEditorConsts.cs.meta | 11 +++ src/Editor/RectUtility.cs | 22 ++++++ .../Editor/EntityTemplateEditor.cs | 75 +++++++++---------- 7 files changed, 122 insertions(+), 43 deletions(-) create mode 100644 src/Editor/ColorUtility.cs create mode 100644 src/Editor/ColorUtility.cs.meta create mode 100644 src/Editor/EscEditorConsts.cs create mode 100644 src/Editor/EscEditorConsts.cs.meta diff --git a/src/Editor/ColorUtility.cs b/src/Editor/ColorUtility.cs new file mode 100644 index 0000000..ca9f91d --- /dev/null +++ b/src/Editor/ColorUtility.cs @@ -0,0 +1,20 @@ +using UnityEngine; + +namespace DCFApixels.DragonECS.Unity.Internal +{ + internal static class ColorUtility + { + public static Color Desaturate(this Color self, float t) + { + float r = self.r; + float g = self.g; + float b = self.b; + //float gray = r * 0.299f + g * 0.587f + b * 0.114f; + float gray = r * 0.3333333f + g * 0.3333333f + b * 0.3333333f; + r = r + (gray - r) * (1 - t); + g = g + (gray - g) * (1 - t); + b = b + (gray - b) * (1 - t); + return new Color(r, g, b); + } + } +} \ No newline at end of file diff --git a/src/Editor/ColorUtility.cs.meta b/src/Editor/ColorUtility.cs.meta new file mode 100644 index 0000000..22a57a0 --- /dev/null +++ b/src/Editor/ColorUtility.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: daa1178cae0d21643b233d22f2c3e867 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/Editor/EditorUtility.cs b/src/Editor/EditorUtility.cs index f17bc5b..36c126b 100644 --- a/src/Editor/EditorUtility.cs +++ b/src/Editor/EditorUtility.cs @@ -1,4 +1,5 @@ #if UNITY_EDITOR +using Codice.Utils; using DCFApixels.DragonECS.Unity.Internal; using System; using System.Reflection; @@ -105,8 +106,8 @@ namespace DCFApixels.DragonECS.Unity.Editors IsShowRuntimeComponents = EditorGUILayout.Foldout(IsShowRuntimeComponents, "RUNTIME COMPONENTS"); if (IsShowRuntimeComponents) { - //TODO галочкаслишком чернаяя, невидно - IsShowHidden = EditorGUILayout.Toggle("Show Hidden", IsShowHiddens); + GUILayout.Box("", EcsEditor.GetStyle(GUI.color, 0.16f), GUILayout.ExpandWidth(true)); + IsShowHidden = EditorGUI.Toggle(GUILayoutUtility.GetLastRect(), "Show Hidden", IsShowHidden); foreach (var componentTypeID in componentTypeIDs) { var pool = world.GetPool(componentTypeID); @@ -124,8 +125,8 @@ namespace DCFApixels.DragonECS.Unity.Editors if (meta.IsHidden == false || IsShowHidden) { object data = pool.GetRaw(entityID); - Color panelColor = meta.Color.ToUnityColor(); - GUILayout.BeginVertical(EcsEditor.GetStyle(panelColor, 0.22f)); + Color panelColor = meta.Color.ToUnityColor().Desaturate(EscEditorConsts.COMPONENT_DRAWER_DESATURATE); + GUILayout.BeginVertical(EcsEditor.GetStyle(panelColor, EscEditorConsts.COMPONENT_DRAWER_ALPHA)); EditorGUI.BeginChangeCheck(); Type componentType = pool.ComponentType; @@ -151,7 +152,8 @@ namespace DCFApixels.DragonECS.Unity.Editors if (uobj == null && (type.IsGenericType || !type.IsSerializable)) { - isExpanded = EditorGUILayout.Foldout(isExpanded, label); + isExpanded = EditorGUILayout.BeginFoldoutHeaderGroup(isExpanded, label, EditorStyles.foldout); + EditorGUILayout.EndFoldoutHeaderGroup(); if (isExpanded) { diff --git a/src/Editor/EscEditorConsts.cs b/src/Editor/EscEditorConsts.cs new file mode 100644 index 0000000..e6ff535 --- /dev/null +++ b/src/Editor/EscEditorConsts.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DCFApixels.DragonECS.Unity.Editors +{ + internal static class EscEditorConsts + { + public const float COMPONENT_DRAWER_ALPHA = 0.26f; + public const float COMPONENT_DRAWER_DESATURATE = 0.86f; + } +} diff --git a/src/Editor/EscEditorConsts.cs.meta b/src/Editor/EscEditorConsts.cs.meta new file mode 100644 index 0000000..e704e9c --- /dev/null +++ b/src/Editor/EscEditorConsts.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b0bed74c1b3b07d44b9ea1ea917809e4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/Editor/RectUtility.cs b/src/Editor/RectUtility.cs index 97c99af..76d7825 100644 --- a/src/Editor/RectUtility.cs +++ b/src/Editor/RectUtility.cs @@ -29,6 +29,14 @@ namespace DCFApixels.DragonECS.Unity.Internal return (l, r); } + public static (Rect, Rect) VerticalSliceTop(Rect rect, float height) + { + Rect t = rect; + Rect b = rect; + t.yMax = t.yMin + height; + b.yMin += height; + return (t, b); + } public static (Rect, Rect) VerticalSliceBottom(Rect rect, float height) { Rect t = rect; @@ -37,5 +45,19 @@ namespace DCFApixels.DragonECS.Unity.Internal b.yMin = b.yMax - height; return (t, b); } + + public static Rect AddPadding(Rect rect, float verticalHorizontal) + { + return AddPadding(rect, verticalHorizontal, verticalHorizontal); + } + + public static Rect AddPadding(Rect rect, float vertical, float horizontal) + { + rect.xMax -= horizontal; + rect.xMin += horizontal; + rect.yMax -= vertical; + rect.yMin += vertical; + return rect; + } } } diff --git a/src/EntityTemplate/Editor/EntityTemplateEditor.cs b/src/EntityTemplate/Editor/EntityTemplateEditor.cs index 5b98b33..1eda107 100644 --- a/src/EntityTemplate/Editor/EntityTemplateEditor.cs +++ b/src/EntityTemplate/Editor/EntityTemplateEditor.cs @@ -10,8 +10,8 @@ namespace DCFApixels.DragonECS.Unity.Editors public abstract class EntityTemplateEditorBase : Editor { - private static readonly Rect RemoveButtonRect = new Rect(0f, 0f, 15f, 15f); - private static readonly Rect TooltipIconRect = new Rect(0f, 0f, 15f, 15f); + private static readonly Rect RemoveButtonRect = new Rect(0f, 0f, 17f, 19f); + private static readonly Rect TooltipIconRect = new Rect(0f, 0f, 21f, 15f); private GUIStyle removeButtonStyle; private GenericMenu genericMenu; @@ -96,14 +96,15 @@ namespace DCFApixels.DragonECS.Unity.Editors Init(); SerializedProperty componentsProp = serializedObject.FindProperty(target.ComponentsPropertyName); if (componentsProp == null) + { return; + } DrawTop(target); GUILayout.BeginVertical(EcsEditor.GetStyle(Color.black, 0.2f)); for (int i = 0; i < componentsProp.arraySize; i++) { DrawComponentData(componentsProp.GetArrayElementAtIndex(i), i); - GUILayout.Space(EditorGUIUtility.standardVerticalSpacing * 2); } GUILayout.EndVertical(); DrawFooter(target); @@ -140,72 +141,70 @@ namespace DCFApixels.DragonECS.Unity.Editors return; } - Type initializerType; Type componentType; SerializedProperty componentProperty = componentRefProp; ComponentTemplateBase customInitializer = componentProperty.managedReferenceValue as ComponentTemplateBase; if (customInitializer != null) { componentProperty = componentRefProp.FindPropertyRelative("component"); - initializerType = customInitializer.Type; componentType = customInitializer.GetType().GetField("component", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FieldType; } else { - initializerType = componentProperty.managedReferenceValue.GetType(); - componentType = initializerType; + componentType = componentProperty.managedReferenceValue.GetType(); ; } string name = template.Name; string description = template.Description; - Color panelColor = template.Color; - - GUILayout.BeginHorizontal(); - - GUILayout.BeginVertical(EcsEditor.GetStyle(panelColor, 0.22f)); + Color panelColor = template.Color.Desaturate(EscEditorConsts.COMPONENT_DRAWER_DESATURATE); EditorGUI.BeginChangeCheck(); + GUIContent label = new GUIContent(name); - if (componentType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Length <= 0) + bool isEmpty = componentType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Length <= 0; + + float width = EditorGUIUtility.currentViewWidth; + float height = isEmpty ? EditorGUIUtility.singleLineHeight : EditorGUI.GetPropertyHeight(componentProperty, label, true); + float padding = EditorGUIUtility.standardVerticalSpacing; + + Rect propertyFullRect = GUILayoutUtility.GetRect(width, height + padding * 3f); + propertyFullRect = RectUtility.AddPadding(propertyFullRect, padding / 2f); + Color alphaPanelColor = panelColor; + alphaPanelColor.a = EscEditorConsts.COMPONENT_DRAWER_ALPHA; + + var (propertyRect, controlRect) = RectUtility.HorizontalSliceRight(propertyFullRect, RemoveButtonRect.width); + var (removeButtonRect, _) = RectUtility.VerticalSliceTop(controlRect, RemoveButtonRect.height); + + #region Draw Component Block + EditorGUI.DrawRect(propertyFullRect, alphaPanelColor); + propertyRect = RectUtility.AddPadding(propertyRect, padding); + if (isEmpty) { - GUILayout.Label(label); + GUI.Label(propertyRect, label); } else { - EditorGUILayout.PropertyField(componentProperty, label, true); + EditorGUI.PropertyField(propertyRect, componentProperty, label, true); } - if (EditorGUI.EndChangeCheck()) - { - componentProperty.serializedObject.ApplyModifiedProperties(); - EditorUtility.SetDirty(componentProperty.serializedObject.targetObject); - } - - Rect lastrect = GUILayoutUtility.GetLastRect(); - Rect removeButtonRect = RemoveButtonRect; - removeButtonRect.center = new Vector2(lastrect.xMax + removeButtonRect.width, lastrect.yMin + removeButtonRect.height / 2f); - - GUILayout.EndVertical(); - //Rect lineRect = GUILayoutUtility.GetLastRect(); - //lineRect.y = lineRect.yMax; - //lineRect.height = 3f; - //Color rectColor = panelColor; - //rectColor.a = 0.34f; - //EditorGUI.DrawRect(lineRect, rectColor); - GUILayout.Label("", GUILayout.Width(removeButtonRect.width)); - - if (GUI.Button(removeButtonRect, "x", removeButtonStyle)) + if (GUI.Button(removeButtonRect, "x")) { OnRemoveComponentAt(index); } + #endregion if (!string.IsNullOrEmpty(description)) { Rect tooltipIconRect = TooltipIconRect; - tooltipIconRect.center = new Vector2(lastrect.xMax - removeButtonRect.width / 2f, lastrect.yMin + removeButtonRect.height / 2f); - GUIContent descriptionLabel = new GUIContent(EcsUnityConsts.INFO_MARK, description); + tooltipIconRect.center = new Vector2(propertyRect.xMax - removeButtonRect.width / 2f, propertyRect.yMin + removeButtonRect.height / 2f); + GUIContent descriptionLabel = new GUIContent("( i )", description); GUI.Label(tooltipIconRect, descriptionLabel, EditorStyles.boldLabel); } - GUILayout.EndHorizontal(); + + if (EditorGUI.EndChangeCheck()) + { + componentProperty.serializedObject.ApplyModifiedProperties(); + componentProperty.serializedObject.SetIsDifferentCacheDirty(); + } } private void DrawDamagedComponent(SerializedProperty componentRefProp, int index) From b13f7eaa4c61e8ffdb1015e6e200dd50c545ffa3 Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Tue, 5 Mar 2024 03:35:38 +0800 Subject: [PATCH 24/50] update --- src/Connectors/EcsEntityConnect.cs | 64 +++++++++++-------- src/Editor/EditorUtility.cs | 41 ++++++++---- src/Editor/RectUtility.cs | 15 +++-- .../Editor/EntityTemplateEditor.cs | 10 ++- 4 files changed, 81 insertions(+), 49 deletions(-) diff --git a/src/Connectors/EcsEntityConnect.cs b/src/Connectors/EcsEntityConnect.cs index 1e66505..7b610fc 100644 --- a/src/Connectors/EcsEntityConnect.cs +++ b/src/Connectors/EcsEntityConnect.cs @@ -120,8 +120,6 @@ namespace DCFApixels.DragonECS.Unity.Editors { targets[i] = (EcsEntityConnect)this.targets[i]; } - DrawTop(); - DrawEntityInfo(targets); DrawTemplates(); @@ -129,52 +127,64 @@ namespace DCFApixels.DragonECS.Unity.Editors DrawButtons(); DrawComponents(targets); } - private void DrawTop() - { - var iterator = serializedObject.GetIterator(); - iterator.NextVisible(true); - using (new EditorGUI.DisabledScope(true)) - { - EditorGUILayout.PropertyField(iterator, true); - } - } + private const float line1 = 1f; + private const float line2 = 2f; private void DrawEntityInfo(EcsEntityConnect[] targets) { float width = EditorGUIUtility.currentViewWidth; float height = EditorGUIUtility.singleLineHeight; - Rect entityRect = GUILayoutUtility.GetRect(width, height + 3f); + Rect entityRect = GUILayoutUtility.GetRect(width, height + line2 * 2f); - var (entityInfoRect, statusRect) = RectUtility.VerticalSliceBottom(entityRect, 3f); + Color w = Color.gray; + w.a = 0.6f; + Color b = Color.black; + b.a = 0.55f; + EditorGUI.DrawRect(entityRect, w); + + entityRect = RectUtility.AddPadding(entityRect, line1, line1, line2, 0); + var (entityInfoRect, statusRect) = RectUtility.VerticalSliceBottom(entityRect, line2); var (idRect, genWorldRect) = RectUtility.HorizontalSliceLerp(entityInfoRect, 0.5f); var (genRect, worldRect) = RectUtility.HorizontalSliceLerp(genWorldRect, 0.5f); + idRect = RectUtility.AddPadding(idRect, line1, 0); + genRect = RectUtility.AddPadding(genRect, line1, 0); + worldRect = RectUtility.AddPadding(worldRect, line1, 0); + + EditorGUI.DrawRect(idRect, b); + EditorGUI.DrawRect(genRect, b); + EditorGUI.DrawRect(worldRect, b); bool isConnected = Target.Entity.TryUnpack(out int id, out short gen, out short world); - + GUIStyle style = new GUIStyle(EditorStyles.boldLabel); + style.alignment = TextAnchor.MiddleCenter; if (IsMultipleTargets == false && isConnected) { Color statusColor = EcsGUI.GreenColor; - statusColor.a = 0.32f; + statusColor.a = 0.4f; EditorGUI.DrawRect(statusRect, statusColor); - EditorGUI.IntField(idRect, id); - EditorGUI.IntField(genRect, gen); - EditorGUI.IntField(worldRect, world); + + EditorGUI.IntField(idRect, id, style); + EditorGUI.IntField(genRect, gen, style); + EditorGUI.IntField(worldRect, world, style); } else { - using (new EditorGUI.DisabledScope(true)) - { - Color statusColor = IsMultipleTargets ? EcsGUI.GrayColor : EcsGUI.RedColor; - statusColor.a = 0.32f; - EditorGUI.DrawRect(statusRect, statusColor); - EditorGUI.TextField(idRect, "Entity ID"); - EditorGUI.TextField(genRect, "Gen"); - EditorGUI.TextField(worldRect, "World ID"); - } + Color statusColor = IsMultipleTargets ? new Color32(200, 200, 200, 255) : EcsGUI.RedColor; + statusColor.a = 0.4f; + EditorGUI.DrawRect(statusRect, statusColor); + + Color dc = GUI.color; + Color ndc = Color.white; + ndc.a = 0.4f; + GUI.color = ndc; + GUI.Label(idRect, "Entity ID", EditorStyles.boldLabel); + GUI.Label(genRect, "Generation", EditorStyles.boldLabel); + GUI.Label(worldRect, "World ID", EditorStyles.boldLabel); + GUI.color = dc; } } diff --git a/src/Editor/EditorUtility.cs b/src/Editor/EditorUtility.cs index 36c126b..c0bc07c 100644 --- a/src/Editor/EditorUtility.cs +++ b/src/Editor/EditorUtility.cs @@ -138,19 +138,18 @@ namespace DCFApixels.DragonECS.Unity.Editors } GUILayout.EndVertical(); - GUILayout.Space(2f); } } private static bool DrawRuntimeData(Type fieldType, GUIContent label, ExpandMatrix expandMatrix, object data, out object outData) { Type type = data.GetType(); - UnityEngine.Object uobj = data as UnityEngine.Object; + bool isUnityObject = typeof(UnityEngine.Object).IsAssignableFrom(fieldType); ref bool isExpanded = ref expandMatrix.Down(); bool changed = false; outData = data; - if (uobj == null && (type.IsGenericType || !type.IsSerializable)) + if (isUnityObject == false && (type.IsGenericType || !type.IsSerializable)) { isExpanded = EditorGUILayout.BeginFoldoutHeaderGroup(isExpanded, label, EditorStyles.foldout); EditorGUILayout.EndFoldoutHeaderGroup(); @@ -174,18 +173,32 @@ namespace DCFApixels.DragonECS.Unity.Editors } else { - EditorGUI.BeginChangeCheck(); - WrapperBase w = uobj == null ? RefEditorWrapper.Take(data) : UnityObjEditorWrapper.Take(uobj); - - w.IsExpanded = isExpanded; - EditorGUILayout.PropertyField(w.Property, label, true); - isExpanded = w.IsExpanded; - - if (EditorGUI.EndChangeCheck()) + if (isUnityObject) { - w.SO.ApplyModifiedProperties(); - outData = w.Data; - changed = true; + EditorGUI.BeginChangeCheck(); + UnityEngine.Object uobj = (UnityEngine.Object)data; + uobj = EditorGUILayout.ObjectField(label, uobj, fieldType, true); + if (EditorGUI.EndChangeCheck()) + { + outData = uobj; + changed = true; + } + } + else + { + EditorGUI.BeginChangeCheck(); + WrapperBase w = RefEditorWrapper.Take(data); + + w.IsExpanded = isExpanded; + EditorGUILayout.PropertyField(w.Property, label, true); + isExpanded = w.IsExpanded; + + if (EditorGUI.EndChangeCheck()) + { + w.SO.ApplyModifiedProperties(); + outData = w.Data; + changed = true; + } } } diff --git a/src/Editor/RectUtility.cs b/src/Editor/RectUtility.cs index 76d7825..53fe4dd 100644 --- a/src/Editor/RectUtility.cs +++ b/src/Editor/RectUtility.cs @@ -48,15 +48,18 @@ namespace DCFApixels.DragonECS.Unity.Internal public static Rect AddPadding(Rect rect, float verticalHorizontal) { - return AddPadding(rect, verticalHorizontal, verticalHorizontal); + return AddPadding(rect, verticalHorizontal, verticalHorizontal, verticalHorizontal, verticalHorizontal); } - public static Rect AddPadding(Rect rect, float vertical, float horizontal) { - rect.xMax -= horizontal; - rect.xMin += horizontal; - rect.yMax -= vertical; - rect.yMin += vertical; + return AddPadding(rect, vertical, vertical, horizontal, horizontal); + } + public static Rect AddPadding(Rect rect, float left, float right, float top, float bottom) + { + rect.xMin += left; + rect.xMax -= right; + rect.yMin += top; + rect.yMax -= bottom; return rect; } } diff --git a/src/EntityTemplate/Editor/EntityTemplateEditor.cs b/src/EntityTemplate/Editor/EntityTemplateEditor.cs index 1eda107..ec40dd5 100644 --- a/src/EntityTemplate/Editor/EntityTemplateEditor.cs +++ b/src/EntityTemplate/Editor/EntityTemplateEditor.cs @@ -178,15 +178,21 @@ namespace DCFApixels.DragonECS.Unity.Editors #region Draw Component Block EditorGUI.DrawRect(propertyFullRect, alphaPanelColor); propertyRect = RectUtility.AddPadding(propertyRect, padding); + bool isRemoveComponent = false; + if (GUI.Button(removeButtonRect, "x")) + { + isRemoveComponent = true; + } + if (isEmpty) { GUI.Label(propertyRect, label); } else { - EditorGUI.PropertyField(propertyRect, componentProperty, label, true); + EditorGUI.PropertyField(propertyFullRect, componentProperty, label, true); } - if (GUI.Button(removeButtonRect, "x")) + if (isRemoveComponent) { OnRemoveComponentAt(index); } From f172b8212bc4ccebd9a331dcd80d2982034ce210 Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Tue, 5 Mar 2024 04:00:28 +0800 Subject: [PATCH 25/50] update --- src/Connectors/EcsEntityConnect.cs | 42 ++++++++++++------------------ 1 file changed, 17 insertions(+), 25 deletions(-) diff --git a/src/Connectors/EcsEntityConnect.cs b/src/Connectors/EcsEntityConnect.cs index 7b610fc..9d5b8b9 100644 --- a/src/Connectors/EcsEntityConnect.cs +++ b/src/Connectors/EcsEntityConnect.cs @@ -93,7 +93,6 @@ namespace DCFApixels.DragonECS.Unity.Editors { using DCFApixels.DragonECS.Unity.Internal; using UnityEditor; - using static Codice.CM.WorkspaceServer.WorkspaceTreeDataStore; [CustomEditor(typeof(EcsEntityConnect))] [CanEditMultipleObjects] @@ -128,43 +127,38 @@ namespace DCFApixels.DragonECS.Unity.Editors DrawComponents(targets); } - private const float line1 = 1f; - private const float line2 = 2f; private void DrawEntityInfo(EcsEntityConnect[] targets) { float width = EditorGUIUtility.currentViewWidth; float height = EditorGUIUtility.singleLineHeight; - Rect entityRect = GUILayoutUtility.GetRect(width, height + line2 * 2f); + Rect entityRect = GUILayoutUtility.GetRect(width, height + 3f); + var (entityInfoRect, statusRect) = RectUtility.VerticalSliceBottom(entityRect, 3f); Color w = Color.gray; w.a = 0.6f; Color b = Color.black; b.a = 0.55f; - EditorGUI.DrawRect(entityRect, w); - - entityRect = RectUtility.AddPadding(entityRect, line1, line1, line2, 0); - var (entityInfoRect, statusRect) = RectUtility.VerticalSliceBottom(entityRect, line2); + EditorGUI.DrawRect(entityInfoRect, w); var (idRect, genWorldRect) = RectUtility.HorizontalSliceLerp(entityInfoRect, 0.5f); var (genRect, worldRect) = RectUtility.HorizontalSliceLerp(genWorldRect, 0.5f); - - idRect = RectUtility.AddPadding(idRect, line1, 0); - genRect = RectUtility.AddPadding(genRect, line1, 0); - worldRect = RectUtility.AddPadding(worldRect, line1, 0); - + + idRect = RectUtility.AddPadding(idRect, 2, 1, 0, 0); + genRect = RectUtility.AddPadding(genRect, 1, 1, 0, 0); + worldRect = RectUtility.AddPadding(worldRect, 1, 2, 0, 0); EditorGUI.DrawRect(idRect, b); EditorGUI.DrawRect(genRect, b); EditorGUI.DrawRect(worldRect, b); - bool isConnected = Target.Entity.TryUnpack(out int id, out short gen, out short world); - GUIStyle style = new GUIStyle(EditorStyles.boldLabel); + GUIStyle style = new GUIStyle(EditorStyles.numberField); style.alignment = TextAnchor.MiddleCenter; + style.font = EditorStyles.boldFont; if (IsMultipleTargets == false && isConnected) { Color statusColor = EcsGUI.GreenColor; - statusColor.a = 0.4f; + statusColor.a = 0.6f; EditorGUI.DrawRect(statusRect, statusColor); EditorGUI.IntField(idRect, id, style); @@ -174,17 +168,15 @@ namespace DCFApixels.DragonECS.Unity.Editors else { Color statusColor = IsMultipleTargets ? new Color32(200, 200, 200, 255) : EcsGUI.RedColor; - statusColor.a = 0.4f; + statusColor.a = 0.6f; EditorGUI.DrawRect(statusRect, statusColor); - Color dc = GUI.color; - Color ndc = Color.white; - ndc.a = 0.4f; - GUI.color = ndc; - GUI.Label(idRect, "Entity ID", EditorStyles.boldLabel); - GUI.Label(genRect, "Generation", EditorStyles.boldLabel); - GUI.Label(worldRect, "World ID", EditorStyles.boldLabel); - GUI.color = dc; + using (new EditorGUI.DisabledScope(true)) + { + GUI.Label(idRect, "Entity ID", style); + GUI.Label(genRect, "Generation", style); + GUI.Label(worldRect, "World ID", style); + } } } From 3701423bf622196dbcfda25e2a0236eeb94dcb31 Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Wed, 6 Mar 2024 21:37:21 +0800 Subject: [PATCH 26/50] update --- src/Connectors/AutoEntityCreator.cs | 28 +--- src/Connectors/EcsEntityConnect.cs | 148 +----------------- src/Connectors/EcsWorldProvider.cs | 30 +--- src/Connectors/Editor.meta | 8 + .../Editor/AutoEntityCreatorEditor.cs | 26 +++ .../Editor/AutoEntityCreatorEditor.cs.meta | 11 ++ .../Editor/EcsEntityConnectEditor.cs | 146 +++++++++++++++++ .../Editor/EcsEntityConnectEditor.cs.meta | 11 ++ .../Editor/EcsWorldProviderBaseEditor.cs | 30 ++++ .../Editor/EcsWorldProviderBaseEditor.cs.meta | 11 ++ src/Debug/Editor/DebugMonitorPrefs.cs | 4 +- src/EcsUnityConsts.cs | 2 +- src/Editor/EditorUtility.cs | 3 +- src/Editor/EscEditorConsts.cs | 8 +- src/Editor/SOWrappers/RefEditorWrapper.cs | 2 +- src/Editor/Utils.meta | 8 + src/Editor/{ => Utils}/ColorUtility.cs | 0 src/Editor/{ => Utils}/ColorUtility.cs.meta | 2 +- src/Editor/{ => Utils}/RectUtility.cs | 0 src/Editor/{ => Utils}/RectUtility.cs.meta | 2 +- .../Editor/EntityTemplateEditor.cs | 42 ++--- .../Templates/ComponentTemplateBase.cs | 4 +- 22 files changed, 288 insertions(+), 238 deletions(-) create mode 100644 src/Connectors/Editor.meta create mode 100644 src/Connectors/Editor/AutoEntityCreatorEditor.cs create mode 100644 src/Connectors/Editor/AutoEntityCreatorEditor.cs.meta create mode 100644 src/Connectors/Editor/EcsEntityConnectEditor.cs create mode 100644 src/Connectors/Editor/EcsEntityConnectEditor.cs.meta create mode 100644 src/Connectors/Editor/EcsWorldProviderBaseEditor.cs create mode 100644 src/Connectors/Editor/EcsWorldProviderBaseEditor.cs.meta create mode 100644 src/Editor/Utils.meta rename src/Editor/{ => Utils}/ColorUtility.cs (100%) rename src/Editor/{ => Utils}/ColorUtility.cs.meta (83%) rename src/Editor/{ => Utils}/RectUtility.cs (100%) rename src/Editor/{ => Utils}/RectUtility.cs.meta (83%) diff --git a/src/Connectors/AutoEntityCreator.cs b/src/Connectors/AutoEntityCreator.cs index 14ae2d7..8953844 100644 --- a/src/Connectors/AutoEntityCreator.cs +++ b/src/Connectors/AutoEntityCreator.cs @@ -69,30 +69,4 @@ namespace DCFApixels.DragonECS } #endif } -} - -#if UNITY_EDITOR -namespace DCFApixels.DragonECS.Unity.Editors -{ - using UnityEditor; - - [CustomEditor(typeof(AutoEntityCreator))] - [CanEditMultipleObjects] - public class AutoEntityCreatorEditor : Editor - { - public override void OnInspectorGUI() - { - base.OnInspectorGUI(); - if (GUILayout.Button("Autoset")) - { - foreach (var tr in targets) - { - AutoEntityCreator creator = (AutoEntityCreator)tr; - creator.Autoset_Editor(); - EditorUtility.SetDirty(creator); - } - } - } - } -} -#endif \ No newline at end of file +} \ No newline at end of file diff --git a/src/Connectors/EcsEntityConnect.cs b/src/Connectors/EcsEntityConnect.cs index 9d5b8b9..6974007 100644 --- a/src/Connectors/EcsEntityConnect.cs +++ b/src/Connectors/EcsEntityConnect.cs @@ -85,150 +85,4 @@ namespace DCFApixels.DragonECS } } } -} - - -#if UNITY_EDITOR -namespace DCFApixels.DragonECS.Unity.Editors -{ - using DCFApixels.DragonECS.Unity.Internal; - using UnityEditor; - - [CustomEditor(typeof(EcsEntityConnect))] - [CanEditMultipleObjects] - public class EcsEntityEditor : Editor - { - private bool _isInit = false; - private EcsEntityConnect Target => (EcsEntityConnect)target; - private bool IsMultipleTargets => targets.Length > 1; - - private void Init() - { - if (_isInit) - { - return; - } - _isInit = true; - } - - public override void OnInspectorGUI() - { - Init(); - EcsEntityConnect[] targets = new EcsEntityConnect[this.targets.Length]; - for (int i = 0; i < targets.Length; i++) - { - targets[i] = (EcsEntityConnect)this.targets[i]; - } - DrawEntityInfo(targets); - - DrawTemplates(); - - DrawButtons(); - DrawComponents(targets); - } - - private void DrawEntityInfo(EcsEntityConnect[] targets) - { - float width = EditorGUIUtility.currentViewWidth; - float height = EditorGUIUtility.singleLineHeight; - Rect entityRect = GUILayoutUtility.GetRect(width, height + 3f); - var (entityInfoRect, statusRect) = RectUtility.VerticalSliceBottom(entityRect, 3f); - - Color w = Color.gray; - w.a = 0.6f; - Color b = Color.black; - b.a = 0.55f; - EditorGUI.DrawRect(entityInfoRect, w); - - var (idRect, genWorldRect) = RectUtility.HorizontalSliceLerp(entityInfoRect, 0.5f); - var (genRect, worldRect) = RectUtility.HorizontalSliceLerp(genWorldRect, 0.5f); - - idRect = RectUtility.AddPadding(idRect, 2, 1, 0, 0); - genRect = RectUtility.AddPadding(genRect, 1, 1, 0, 0); - worldRect = RectUtility.AddPadding(worldRect, 1, 2, 0, 0); - EditorGUI.DrawRect(idRect, b); - EditorGUI.DrawRect(genRect, b); - EditorGUI.DrawRect(worldRect, b); - - bool isConnected = Target.Entity.TryUnpack(out int id, out short gen, out short world); - - GUIStyle style = new GUIStyle(EditorStyles.numberField); - style.alignment = TextAnchor.MiddleCenter; - style.font = EditorStyles.boldFont; - if (IsMultipleTargets == false && isConnected) - { - Color statusColor = EcsGUI.GreenColor; - statusColor.a = 0.6f; - EditorGUI.DrawRect(statusRect, statusColor); - - EditorGUI.IntField(idRect, id, style); - EditorGUI.IntField(genRect, gen, style); - EditorGUI.IntField(worldRect, world, style); - } - else - { - Color statusColor = IsMultipleTargets ? new Color32(200, 200, 200, 255) : EcsGUI.RedColor; - statusColor.a = 0.6f; - EditorGUI.DrawRect(statusRect, statusColor); - - using (new EditorGUI.DisabledScope(true)) - { - GUI.Label(idRect, "Entity ID", style); - GUI.Label(genRect, "Generation", style); - GUI.Label(worldRect, "World ID", style); - } - } - } - - private void DrawTemplates() - { - var iterator = serializedObject.GetIterator(); - iterator.NextVisible(true); - bool enterChildren = true; - while (iterator.NextVisible(enterChildren)) - { - EditorGUILayout.PropertyField(iterator, true); - enterChildren = false; - } - } - - private void DrawButtons() - { - GUILayout.BeginHorizontal(); - if (GUILayout.Button("Autoset")) - { - Target.SetTemplates_Editor(Target.GetComponents()); - EditorUtility.SetDirty(target); - } - if (GUILayout.Button("Autoset Cascade")) - { - foreach (var item in Target.GetComponentsInChildren()) - { - item.SetTemplates_Editor(item.GetComponents()); - EditorUtility.SetDirty(item); - } - } - GUILayout.EndHorizontal(); - } - - private void DrawComponents(EcsEntityConnect[] targets) - { - if (IsMultipleTargets) - { - for (int i = 0; i < targets.Length; i++) - { - if (targets[i].IsConected == true) - { - EditorGUILayout.HelpBox("Multiple component editing is not available.", MessageType.Warning); - return; - } - } - } - if (Target.Entity.TryUnpack(out int entityID, out EcsWorld world)) - { - EcsGUI.Layout.DrawRuntimeComponents(entityID, world); - } - } - } -} -#endif \ No newline at end of file +} \ No newline at end of file diff --git a/src/Connectors/EcsWorldProvider.cs b/src/Connectors/EcsWorldProvider.cs index 48cbbbd..bd16af8 100644 --- a/src/Connectors/EcsWorldProvider.cs +++ b/src/Connectors/EcsWorldProvider.cs @@ -79,32 +79,4 @@ namespace DCFApixels.DragonECS protected virtual void OnWorldCreated(TWorld world) { } #endregion } -} - -#if UNITY_EDITOR -namespace DCFApixels.DragonECS.Unity.Editors -{ - [CustomEditor(typeof(EcsWorldProviderBase), true)] - [CanEditMultipleObjects] - public class EcsWorldProviderBaseEditor : Editor - { - private EcsWorldProviderBase Target => (EcsWorldProviderBase)target; - - public override void OnInspectorGUI() - { - base.OnInspectorGUI(); - if (Target.IsEmpty) - { - var style = EcsEditor.GetStyle(new Color32(255, 0, 75, 100)); - GUILayout.Box("Is Empty", style, GUILayout.ExpandWidth(true)); - } - else - { - var style = EcsEditor.GetStyle(new Color32(75, 255, 0, 100)); - EcsWorld world = Target.GetRaw(); - GUILayout.Box($"{world.GetMeta().Name} ( {world.id} )", style, GUILayout.ExpandWidth(true)); - } - } - } -} -#endif \ No newline at end of file +} \ No newline at end of file diff --git a/src/Connectors/Editor.meta b/src/Connectors/Editor.meta new file mode 100644 index 0000000..310c075 --- /dev/null +++ b/src/Connectors/Editor.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 2593ccf9a57f4f045a7e3bf6a839f3c3 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/Connectors/Editor/AutoEntityCreatorEditor.cs b/src/Connectors/Editor/AutoEntityCreatorEditor.cs new file mode 100644 index 0000000..07155c8 --- /dev/null +++ b/src/Connectors/Editor/AutoEntityCreatorEditor.cs @@ -0,0 +1,26 @@ +#if UNITY_EDITOR +using UnityEditor; +using UnityEngine; + +namespace DCFApixels.DragonECS.Unity.Editors +{ + [CustomEditor(typeof(AutoEntityCreator))] + [CanEditMultipleObjects] + public class AutoEntityCreatorEditor : Editor + { + public override void OnInspectorGUI() + { + base.OnInspectorGUI(); + if (GUILayout.Button("Autoset")) + { + foreach (var tr in targets) + { + AutoEntityCreator creator = (AutoEntityCreator)tr; + creator.Autoset_Editor(); + EditorUtility.SetDirty(creator); + } + } + } + } +} +#endif \ No newline at end of file diff --git a/src/Connectors/Editor/AutoEntityCreatorEditor.cs.meta b/src/Connectors/Editor/AutoEntityCreatorEditor.cs.meta new file mode 100644 index 0000000..ab1c1f5 --- /dev/null +++ b/src/Connectors/Editor/AutoEntityCreatorEditor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7e21fcbcfdafbb64d86bf965cd16c6b0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/Connectors/Editor/EcsEntityConnectEditor.cs b/src/Connectors/Editor/EcsEntityConnectEditor.cs new file mode 100644 index 0000000..72b4f81 --- /dev/null +++ b/src/Connectors/Editor/EcsEntityConnectEditor.cs @@ -0,0 +1,146 @@ +#if UNITY_EDITOR +using DCFApixels.DragonECS.Unity.Internal; +using UnityEditor; +using UnityEngine; + +namespace DCFApixels.DragonECS.Unity.Editors +{ + [CustomEditor(typeof(EcsEntityConnect))] + [CanEditMultipleObjects] + public class EcsEntityConnectEditor : Editor + { + private bool _isInit = false; + private EcsEntityConnect Target => (EcsEntityConnect)target; + private bool IsMultipleTargets => targets.Length > 1; + + private void Init() + { + if (_isInit) + { + return; + } + _isInit = true; + } + + public override void OnInspectorGUI() + { + Init(); + EcsEntityConnect[] targets = new EcsEntityConnect[this.targets.Length]; + for (int i = 0; i < targets.Length; i++) + { + targets[i] = (EcsEntityConnect)this.targets[i]; + } + DrawEntityInfo(targets); + + DrawTemplates(); + + DrawButtons(); + DrawComponents(targets); + } + + private void DrawEntityInfo(EcsEntityConnect[] targets) + { + //TODO Отрефакторить + float width = EditorGUIUtility.currentViewWidth; + float height = EditorGUIUtility.singleLineHeight; + Rect entityRect = GUILayoutUtility.GetRect(width, height + 3f); + var (entityInfoRect, statusRect) = RectUtility.VerticalSliceBottom(entityRect, 3f); + + Color w = Color.gray; + w.a = 0.6f; + Color b = Color.black; + b.a = 0.55f; + EditorGUI.DrawRect(entityInfoRect, w); + + var (idRect, genWorldRect) = RectUtility.HorizontalSliceLerp(entityInfoRect, 0.5f); + var (genRect, worldRect) = RectUtility.HorizontalSliceLerp(genWorldRect, 0.5f); + + idRect = RectUtility.AddPadding(idRect, 2, 1, 0, 0); + genRect = RectUtility.AddPadding(genRect, 1, 1, 0, 0); + worldRect = RectUtility.AddPadding(worldRect, 1, 2, 0, 0); + EditorGUI.DrawRect(idRect, b); + EditorGUI.DrawRect(genRect, b); + EditorGUI.DrawRect(worldRect, b); + + bool isConnected = Target.Entity.TryUnpack(out int id, out short gen, out short world); + + GUIStyle style = new GUIStyle(EditorStyles.numberField); + style.alignment = TextAnchor.MiddleCenter; + style.font = EditorStyles.boldFont; + if (IsMultipleTargets == false && isConnected) + { + Color statusColor = EcsGUI.GreenColor; + statusColor.a = 0.6f; + EditorGUI.DrawRect(statusRect, statusColor); + + EditorGUI.IntField(idRect, id, style); + EditorGUI.IntField(genRect, gen, style); + EditorGUI.IntField(worldRect, world, style); + } + else + { + Color statusColor = IsMultipleTargets ? new Color32(200, 200, 200, 255) : EcsGUI.RedColor; + statusColor.a = 0.6f; + EditorGUI.DrawRect(statusRect, statusColor); + + using (new EditorGUI.DisabledScope(true)) + { + GUI.Label(idRect, "Entity ID", style); + GUI.Label(genRect, "Generation", style); + GUI.Label(worldRect, "World ID", style); + } + } + } + + private void DrawTemplates() + { + var iterator = serializedObject.GetIterator(); + iterator.NextVisible(true); + bool enterChildren = true; + while (iterator.NextVisible(enterChildren)) + { + EditorGUILayout.PropertyField(iterator, true); + enterChildren = false; + } + } + + private void DrawButtons() + { + GUILayout.BeginHorizontal(); + if (GUILayout.Button("Autoset")) + { + Target.SetTemplates_Editor(Target.GetComponents()); + EditorUtility.SetDirty(target); + } + if (GUILayout.Button("Autoset Cascade")) + { + foreach (var item in Target.GetComponentsInChildren()) + { + item.SetTemplates_Editor(item.GetComponents()); + EditorUtility.SetDirty(item); + } + } + GUILayout.EndHorizontal(); + } + + private void DrawComponents(EcsEntityConnect[] targets) + { + if (IsMultipleTargets) + { + for (int i = 0; i < targets.Length; i++) + { + if (targets[i].IsConected == true) + { + EditorGUILayout.HelpBox("Multiple component editing is not available.", MessageType.Warning); + return; + } + } + } + if (Target.Entity.TryUnpack(out int entityID, out EcsWorld world)) + { + EcsGUI.Layout.DrawRuntimeComponents(entityID, world); + } + } + } +} +#endif \ No newline at end of file diff --git a/src/Connectors/Editor/EcsEntityConnectEditor.cs.meta b/src/Connectors/Editor/EcsEntityConnectEditor.cs.meta new file mode 100644 index 0000000..497dfeb --- /dev/null +++ b/src/Connectors/Editor/EcsEntityConnectEditor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 846d3d07f90835048902b412bfac73aa +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/Connectors/Editor/EcsWorldProviderBaseEditor.cs b/src/Connectors/Editor/EcsWorldProviderBaseEditor.cs new file mode 100644 index 0000000..427660a --- /dev/null +++ b/src/Connectors/Editor/EcsWorldProviderBaseEditor.cs @@ -0,0 +1,30 @@ +#if UNITY_EDITOR +using UnityEditor; +using UnityEngine; + +namespace DCFApixels.DragonECS.Unity.Editors +{ + [CustomEditor(typeof(EcsWorldProviderBase), true)] + [CanEditMultipleObjects] + public class EcsWorldProviderBaseEditor : Editor + { + private EcsWorldProviderBase Target => (EcsWorldProviderBase)target; + + public override void OnInspectorGUI() + { + base.OnInspectorGUI(); + if (Target.IsEmpty) + { + var style = EcsEditor.GetStyle(new Color32(255, 0, 75, 100)); + GUILayout.Box("Is Empty", style, GUILayout.ExpandWidth(true)); + } + else + { + var style = EcsEditor.GetStyle(new Color32(75, 255, 0, 100)); + EcsWorld world = Target.GetRaw(); + GUILayout.Box($"{world.GetMeta().Name} ( {world.id} )", style, GUILayout.ExpandWidth(true)); + } + } + } +} +#endif \ No newline at end of file diff --git a/src/Connectors/Editor/EcsWorldProviderBaseEditor.cs.meta b/src/Connectors/Editor/EcsWorldProviderBaseEditor.cs.meta new file mode 100644 index 0000000..34cddd1 --- /dev/null +++ b/src/Connectors/Editor/EcsWorldProviderBaseEditor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1db1c2bb174625249a07a4cef8eff757 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/Debug/Editor/DebugMonitorPrefs.cs b/src/Debug/Editor/DebugMonitorPrefs.cs index 5b2e722..2923965 100644 --- a/src/Debug/Editor/DebugMonitorPrefs.cs +++ b/src/Debug/Editor/DebugMonitorPrefs.cs @@ -1,6 +1,6 @@ #if UNITY_EDITOR -using UnityEngine; using UnityEditor; +using UnityEngine; namespace DCFApixels.DragonECS.Unity.Editors { @@ -22,7 +22,7 @@ namespace DCFApixels.DragonECS.Unity.Editors private bool _isShowHidden = false; public bool IsShowHidden { - get => _isShowHidden; + get => _isShowHidden; set { _isShowHidden = value; diff --git a/src/EcsUnityConsts.cs b/src/EcsUnityConsts.cs index 72a6350..fda3692 100644 --- a/src/EcsUnityConsts.cs +++ b/src/EcsUnityConsts.cs @@ -2,6 +2,6 @@ { public static class EcsUnityConsts { - public const string INFO_MARK = "[i]"; + public const string INFO_MARK = "[D]"; } } diff --git a/src/Editor/EditorUtility.cs b/src/Editor/EditorUtility.cs index c0bc07c..8de4122 100644 --- a/src/Editor/EditorUtility.cs +++ b/src/Editor/EditorUtility.cs @@ -1,5 +1,4 @@ #if UNITY_EDITOR -using Codice.Utils; using DCFApixels.DragonECS.Unity.Internal; using System; using System.Reflection; @@ -201,7 +200,7 @@ namespace DCFApixels.DragonECS.Unity.Editors } } } - + expandMatrix.Up(); return changed; } diff --git a/src/Editor/EscEditorConsts.cs b/src/Editor/EscEditorConsts.cs index e6ff535..9307e9a 100644 --- a/src/Editor/EscEditorConsts.cs +++ b/src/Editor/EscEditorConsts.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace DCFApixels.DragonECS.Unity.Editors +namespace DCFApixels.DragonECS.Unity.Editors { internal static class EscEditorConsts { diff --git a/src/Editor/SOWrappers/RefEditorWrapper.cs b/src/Editor/SOWrappers/RefEditorWrapper.cs index 9ba3369..bab9af6 100644 --- a/src/Editor/SOWrappers/RefEditorWrapper.cs +++ b/src/Editor/SOWrappers/RefEditorWrapper.cs @@ -1,4 +1,4 @@ - #if UNITY_EDITOR +#if UNITY_EDITOR using System; using System.Runtime.CompilerServices; using UnityEngine; diff --git a/src/Editor/Utils.meta b/src/Editor/Utils.meta new file mode 100644 index 0000000..1ae538d --- /dev/null +++ b/src/Editor/Utils.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c36fbe915640753488e69c6e5d6efe92 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/Editor/ColorUtility.cs b/src/Editor/Utils/ColorUtility.cs similarity index 100% rename from src/Editor/ColorUtility.cs rename to src/Editor/Utils/ColorUtility.cs diff --git a/src/Editor/ColorUtility.cs.meta b/src/Editor/Utils/ColorUtility.cs.meta similarity index 83% rename from src/Editor/ColorUtility.cs.meta rename to src/Editor/Utils/ColorUtility.cs.meta index 22a57a0..c29ec5c 100644 --- a/src/Editor/ColorUtility.cs.meta +++ b/src/Editor/Utils/ColorUtility.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: daa1178cae0d21643b233d22f2c3e867 +guid: ff5cb33212a8c8a4eb5111cc17759e47 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/src/Editor/RectUtility.cs b/src/Editor/Utils/RectUtility.cs similarity index 100% rename from src/Editor/RectUtility.cs rename to src/Editor/Utils/RectUtility.cs diff --git a/src/Editor/RectUtility.cs.meta b/src/Editor/Utils/RectUtility.cs.meta similarity index 83% rename from src/Editor/RectUtility.cs.meta rename to src/Editor/Utils/RectUtility.cs.meta index f61539f..6a31900 100644 --- a/src/Editor/RectUtility.cs.meta +++ b/src/Editor/Utils/RectUtility.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 8e275376d670bdd4c986d661838ed6b4 +guid: a08af8a9e1192f44c8aedf88340cb663 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/src/EntityTemplate/Editor/EntityTemplateEditor.cs b/src/EntityTemplate/Editor/EntityTemplateEditor.cs index ec40dd5..b403085 100644 --- a/src/EntityTemplate/Editor/EntityTemplateEditor.cs +++ b/src/EntityTemplate/Editor/EntityTemplateEditor.cs @@ -68,7 +68,9 @@ namespace DCFApixels.DragonECS.Unity.Editors for (int i = 0; i < componentsProp.arraySize; i++) { if (componentsProp.GetArrayElementAtIndex(i).managedReferenceValue.GetType() == componentType) + { return; + } } componentsProp.InsertArrayElementAtIndex(0); @@ -102,6 +104,7 @@ namespace DCFApixels.DragonECS.Unity.Editors DrawTop(target); GUILayout.BeginVertical(EcsEditor.GetStyle(Color.black, 0.2f)); + GUILayout.Label("", GUILayout.Height(0), GUILayout.ExpandWidth(true)); for (int i = 0; i < componentsProp.arraySize; i++) { DrawComponentData(componentsProp.GetArrayElementAtIndex(i), i); @@ -158,27 +161,23 @@ namespace DCFApixels.DragonECS.Unity.Editors string description = template.Description; Color panelColor = template.Color.Desaturate(EscEditorConsts.COMPONENT_DRAWER_DESATURATE); - EditorGUI.BeginChangeCheck(); + Rect removeButtonRect = GUILayoutUtility.GetLastRect(); GUIContent label = new GUIContent(name); bool isEmpty = componentType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Length <= 0; - - float width = EditorGUIUtility.currentViewWidth; - float height = isEmpty ? EditorGUIUtility.singleLineHeight : EditorGUI.GetPropertyHeight(componentProperty, label, true); float padding = EditorGUIUtility.standardVerticalSpacing; - - Rect propertyFullRect = GUILayoutUtility.GetRect(width, height + padding * 3f); - propertyFullRect = RectUtility.AddPadding(propertyFullRect, padding / 2f); Color alphaPanelColor = panelColor; alphaPanelColor.a = EscEditorConsts.COMPONENT_DRAWER_ALPHA; - var (propertyRect, controlRect) = RectUtility.HorizontalSliceRight(propertyFullRect, RemoveButtonRect.width); - var (removeButtonRect, _) = RectUtility.VerticalSliceTop(controlRect, RemoveButtonRect.height); + EditorGUI.BeginChangeCheck(); + GUILayout.BeginVertical(EcsEditor.GetStyle(alphaPanelColor)); #region Draw Component Block - EditorGUI.DrawRect(propertyFullRect, alphaPanelColor); - propertyRect = RectUtility.AddPadding(propertyRect, padding); bool isRemoveComponent = false; + removeButtonRect.yMin = removeButtonRect.yMax; + removeButtonRect.yMax += RemoveButtonRect.height; + removeButtonRect.xMin = removeButtonRect.xMax - RemoveButtonRect.width; + removeButtonRect.center += Vector2.up * padding * 2f; if (GUI.Button(removeButtonRect, "x")) { isRemoveComponent = true; @@ -186,30 +185,31 @@ namespace DCFApixels.DragonECS.Unity.Editors if (isEmpty) { - GUI.Label(propertyRect, label); + GUILayout.Label(label); } else { - EditorGUI.PropertyField(propertyFullRect, componentProperty, label, true); + EditorGUILayout.PropertyField(componentProperty, label, true); } if (isRemoveComponent) { OnRemoveComponentAt(index); } - #endregion - if (!string.IsNullOrEmpty(description)) { Rect tooltipIconRect = TooltipIconRect; - tooltipIconRect.center = new Vector2(propertyRect.xMax - removeButtonRect.width / 2f, propertyRect.yMin + removeButtonRect.height / 2f); - GUIContent descriptionLabel = new GUIContent("( i )", description); + tooltipIconRect.center = removeButtonRect.center; + tooltipIconRect.center -= Vector2.right * tooltipIconRect.width; + GUIContent descriptionLabel = new GUIContent(EcsUnityConsts.INFO_MARK, description); GUI.Label(tooltipIconRect, descriptionLabel, EditorStyles.boldLabel); } + #endregion + GUILayout.EndVertical(); if (EditorGUI.EndChangeCheck()) { componentProperty.serializedObject.ApplyModifiedProperties(); - componentProperty.serializedObject.SetIsDifferentCacheDirty(); + EditorUtility.SetDirty(componentProperty.serializedObject.targetObject); } } @@ -225,7 +225,9 @@ namespace DCFApixels.DragonECS.Unity.Editors GUILayout.Label("", GUILayout.Width(removeButtonRect.width)); if (GUI.Button(removeButtonRect, "x", removeButtonStyle)) + { OnRemoveComponentAt(index); + } GUILayout.EndHorizontal(); } @@ -234,9 +236,13 @@ namespace DCFApixels.DragonECS.Unity.Editors { int lastSlashIndex = input.LastIndexOfAny(new char[] { '/', '\\' }); if (lastSlashIndex == -1) + { return input; + } else + { return input.Substring(lastSlashIndex + 1); + } } } diff --git a/src/EntityTemplate/Templates/ComponentTemplateBase.cs b/src/EntityTemplate/Templates/ComponentTemplateBase.cs index 9d12a76..0b5691e 100644 --- a/src/EntityTemplate/Templates/ComponentTemplateBase.cs +++ b/src/EntityTemplate/Templates/ComponentTemplateBase.cs @@ -56,7 +56,7 @@ namespace DCFApixels.DragonECS [Serializable] public abstract class ComponentTemplateBase : ComponentTemplateBase, IComponentTemplate { - private static TypeMetaDataCached _meta = EcsDebugUtility.GetCachedTypeMeta(); + private static TypeMeta _meta = EcsDebugUtility.GetTypeMeta(); [SerializeField] protected T component; @@ -142,7 +142,7 @@ namespace DCFApixels.DragonECS.Unity.Editors _types = types.ToArray(); foreach (var type in _types) { - EcsDebugUtility.GetCachedTypeMeta(type); + EcsDebugUtility.GetTypeMeta(type); } _dummies = new IComponentTemplate[_types.Length]; From 6e718691cdb075b4801575036406d4a1b663cb51 Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Wed, 6 Mar 2024 23:29:54 +0800 Subject: [PATCH 27/50] update --- src/Buildin/UnityComponents.cs | 34 ++++++++++----- .../Editor/EntityTemplateEditor.cs | 38 ++++++++-------- .../Templates/ComponentTemplateBase.cs | 43 ++++++++++--------- 3 files changed, 64 insertions(+), 51 deletions(-) diff --git a/src/Buildin/UnityComponents.cs b/src/Buildin/UnityComponents.cs index c645acb..5a531c8 100644 --- a/src/Buildin/UnityComponents.cs +++ b/src/Buildin/UnityComponents.cs @@ -5,6 +5,13 @@ using UnityEngine; namespace DCFApixels.DragonECS { + internal static class UnityComponentConsts + { + private const string UNITY_COMPONENT_NAME = "UnityComponent"; + public static readonly MetaGroup BaseGroup = new MetaGroupRef(UNITY_COMPONENT_NAME); + public static readonly MetaGroup ColliderGroup = new MetaGroupRef($"{UNITY_COMPONENT_NAME}/Collider/"); + public static readonly MetaGroup JointGroup = new MetaGroupRef($"{UNITY_COMPONENT_NAME}/Joint/"); + } [Serializable] [MetaColor(255 / 3, 255, 0)] public struct UnityComponent : IEcsComponent, IEnumerable//IntelliSense hack @@ -22,7 +29,14 @@ namespace DCFApixels.DragonECS #region Unity Component Templates public class UnityComponentTemplate : ComponentTemplateBase> where T : Component { - public override string Name => "UnityComponent/" + typeof(T).Name; + public override string Name + { + get { return typeof(T).Name; } + } + public override MetaGroup Group + { + get { return UnityComponentConsts.BaseGroup; } + } public sealed override void Apply(int worldID, int entityID) { EcsWorld.GetPool>>(worldID).TryAddOrGet(entityID) = component; @@ -51,27 +65,27 @@ namespace DCFApixels.DragonECS [Serializable] public sealed class UnityComponentColliderTemplate : UnityComponentTemplate { - public override string Name => "UnityComponent/Collider/" + nameof(Collider); + public override MetaGroup Group { get { return UnityComponentConsts.ColliderGroup; } } } [Serializable] public sealed class UnityComponentBoxColliderTemplate : UnityComponentTemplate { - public override string Name => "UnityComponent/Collider/" + nameof(BoxCollider); + public override MetaGroup Group { get { return UnityComponentConsts.ColliderGroup; } } } [Serializable] public sealed class UnityComponentSphereColliderTemplate : UnityComponentTemplate { - public override string Name => "UnityComponent/Collider/" + nameof(SphereCollider); + public override MetaGroup Group { get { return UnityComponentConsts.ColliderGroup; } } } [Serializable] public sealed class UnityComponentCapsuleColliderTemplate : UnityComponentTemplate { - public override string Name => "UnityComponent/Collider/" + nameof(CapsuleCollider); + public override MetaGroup Group { get { return UnityComponentConsts.ColliderGroup; } } } [Serializable] public sealed class UnityComponentMeshColliderTemplate : UnityComponentTemplate { - public override string Name => "UnityComponent/Collider/" + nameof(MeshCollider); + public override MetaGroup Group { get { return UnityComponentConsts.ColliderGroup; } } } #endregion @@ -79,22 +93,22 @@ namespace DCFApixels.DragonECS [Serializable] public sealed class UnityComponentJointTemplate : UnityComponentTemplate { - public override string Name => "UnityComponent/Joint/" + nameof(Joint); + public override MetaGroup Group { get { return UnityComponentConsts.JointGroup; } } } [Serializable] public sealed class UnityComponentFixedJointTemplate : UnityComponentTemplate { - public override string Name => "UnityComponent/Joint/" + nameof(FixedJoint); + public override MetaGroup Group { get { return UnityComponentConsts.JointGroup; } } } [Serializable] public sealed class UnityComponentCharacterJointTemplate : UnityComponentTemplate { - public override string Name => "UnityComponent/Joint/" + nameof(CharacterJoint); + public override MetaGroup Group { get { return UnityComponentConsts.JointGroup; } } } [Serializable] public sealed class UnityComponentConfigurableJointTemplate : UnityComponentTemplate { - public override string Name => "UnityComponent/Joint/" + nameof(ConfigurableJoint); + public override MetaGroup Group { get { return UnityComponentConsts.JointGroup; } } } #endregion } diff --git a/src/EntityTemplate/Editor/EntityTemplateEditor.cs b/src/EntityTemplate/Editor/EntityTemplateEditor.cs index b403085..cfc04cb 100644 --- a/src/EntityTemplate/Editor/EntityTemplateEditor.cs +++ b/src/EntityTemplate/Editor/EntityTemplateEditor.cs @@ -42,11 +42,19 @@ namespace DCFApixels.DragonECS.Unity.Editors genericMenu = new GenericMenu(); - var dummies = ComponentTemplateTypeCache.Dummies; - foreach (var dummy in dummies) + var componentTemplateDummies = ComponentTemplateTypeCache.Dummies; + foreach (var dummy in componentTemplateDummies) { - string name = dummy.Name; - string description = dummy.Description; + ITypeMeta meta = dummy is ITypeMeta metaOverride ? metaOverride : dummy.Type.ToMeta(); + string name = meta.Name; + string description = meta.Description; + MetaGroup group = meta.Group; + + if(group.Name.Length > 0) + { + name = group.Name + name; + } + if (string.IsNullOrEmpty(description) == false) { name = $"{name} {EcsUnityConsts.INFO_MARK}"; @@ -156,10 +164,11 @@ namespace DCFApixels.DragonECS.Unity.Editors { componentType = componentProperty.managedReferenceValue.GetType(); ; } - - string name = template.Name; - string description = template.Description; - Color panelColor = template.Color.Desaturate(EscEditorConsts.COMPONENT_DRAWER_DESATURATE); + + ITypeMeta meta = template is ITypeMeta metaOverride ? metaOverride : template.Type.ToMeta(); + string name = meta.Name; + string description = meta.Description; + Color panelColor = meta.Color.ToUnityColor().Desaturate(EscEditorConsts.COMPONENT_DRAWER_DESATURATE); Rect removeButtonRect = GUILayoutUtility.GetLastRect(); @@ -231,19 +240,6 @@ namespace DCFApixels.DragonECS.Unity.Editors GUILayout.EndHorizontal(); } - - public string GetLastPathComponent(string input) - { - int lastSlashIndex = input.LastIndexOfAny(new char[] { '/', '\\' }); - if (lastSlashIndex == -1) - { - return input; - } - else - { - return input.Substring(lastSlashIndex + 1); - } - } } [CustomEditor(typeof(ScriptableEntityTemplate), true)] diff --git a/src/EntityTemplate/Templates/ComponentTemplateBase.cs b/src/EntityTemplate/Templates/ComponentTemplateBase.cs index 0b5691e..845a1d8 100644 --- a/src/EntityTemplate/Templates/ComponentTemplateBase.cs +++ b/src/EntityTemplate/Templates/ComponentTemplateBase.cs @@ -1,4 +1,5 @@ -using System; +using Codice.Utils; +using System; using System.Collections.Generic; using System.Linq; using System.Reflection; @@ -11,11 +12,6 @@ namespace DCFApixels.DragonECS { #region Properties Type Type { get; } - string Name { get; } - MetaGroup Group { get; } - string Description { get; } - IReadOnlyCollection Tags { get; } - Color Color { get; } #endregion #region Methods @@ -31,17 +27,18 @@ namespace DCFApixels.DragonECS Selected } } + public interface IComponentTemplateWithMetaOverride : IComponentTemplate, ITypeMeta { } [Serializable] - public abstract class ComponentTemplateBase : IComponentTemplate + public abstract class ComponentTemplateBase : IComponentTemplateWithMetaOverride { #region Properties public abstract Type Type { get; } public virtual string Name { get { return string.Empty; } } - public virtual MetaGroup Group { get { return default; } } + public virtual MetaColor Color { get { return new MetaColor(MetaColor.Black); } } + public virtual MetaGroup Group { get { return MetaGroup.Empty; } } public virtual string Description { get { return string.Empty; } } public virtual IReadOnlyCollection Tags { get { return Array.Empty(); } } - public virtual Color Color { get { return Color.black; } } #endregion #region Methods @@ -54,19 +51,19 @@ namespace DCFApixels.DragonECS #endregion } [Serializable] - public abstract class ComponentTemplateBase : ComponentTemplateBase, IComponentTemplate + public abstract class ComponentTemplateBase : ComponentTemplateBase { - private static TypeMeta _meta = EcsDebugUtility.GetTypeMeta(); + protected static TypeMeta Meta = EcsDebugUtility.GetTypeMeta(); [SerializeField] protected T component; #region Properties public override Type Type { get { return typeof(T); } } - public override string Name { get { return _meta.Name; } } - public override MetaGroup Group { get { return _meta.Group; } } - public override string Description { get { return _meta.Description; } } - public override IReadOnlyCollection Tags { get { return _meta.Tags; } } - public override Color Color { get { return _meta.Color.ToUnityColor(); } } + public override string Name { get { return Meta.Name; } } + public override MetaGroup Group { get { return Meta.Group; } } + public override string Description { get { return Meta.Description; } } + public override IReadOnlyCollection Tags { get { return Meta.Tags; } } + public override MetaColor Color { get { return Meta.Color; } } #endregion #region Methods @@ -81,7 +78,7 @@ namespace DCFApixels.DragonECS #endregion } - public abstract class ComponentTemplate : ComponentTemplateBase, IComponentTemplate + public abstract class ComponentTemplate : ComponentTemplateBase where T : struct, IEcsComponent { public override void Apply(int worldID, int entityID) @@ -89,7 +86,7 @@ namespace DCFApixels.DragonECS EcsWorld.GetPool>(worldID).TryAddOrGet(entityID) = component; } } - public abstract class TagComponentTemplate : ComponentTemplateBase, IComponentTemplate + public abstract class TagComponentTemplate : ComponentTemplateBase where T : struct, IEcsTagComponent { public override void Apply(int worldID, int entityID) @@ -118,8 +115,14 @@ namespace DCFApixels.DragonECS.Unity.Editors { private static Type[] _types; private static IComponentTemplate[] _dummies; - internal static ReadOnlySpan Types => _types; - internal static ReadOnlySpan Dummies => _dummies; + internal static ReadOnlySpan Types + { + get { return _types; } + } + internal static ReadOnlySpan Dummies + { + get { return _dummies; } + } static ComponentTemplateTypeCache() { From ade0db2b0c3184b5903d8bbde67d0857d64c5064 Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Thu, 7 Mar 2024 03:18:00 +0800 Subject: [PATCH 28/50] update --- src/Buildin/EcsDefaultWorldProvider.cs | 16 +- .../EcsDefaultWorldSingletonProvider.cs | 5 - src/Connectors/EcsWorldProvider.cs | 29 ++- .../Editor/EcsWorldProviderBaseEditor.cs | 24 ++- src/Debug/UnityDebugService.cs | 7 +- .../Editor/EntityTemplateEditor.cs | 34 ++- .../Templates/ComponentTemplateBase.cs | 3 +- src/Internal.meta | 8 + src/{Utils => Internal}/BitMask.cs | 0 src/{Utils => Internal}/BitMask.cs.meta | 0 src/{ => Internal}/Editor.meta | 2 +- .../Editor/EcsGUI.cs} | 196 +++--------------- .../Editor/EcsGUI.cs.meta} | 2 +- src/{ => Internal}/Editor/ExpandMatrix.cs | 0 .../Editor/ExpandMatrix.cs.meta | 0 src/{ => Internal}/Editor/SOWrappers.meta | 0 .../Editor/SOWrappers/RefEditorWrapper.cs | 12 +- .../SOWrappers/RefEditorWrapper.cs.meta | 0 .../SOWrappers/UnityObjEditorWrapper.cs | 0 .../SOWrappers/UnityObjEditorWrapper.cs.meta | 0 .../Editor/SOWrappers/WrapperBase.cs | 0 .../Editor/SOWrappers/WrapperBase.cs.meta | 0 src/Internal/Editor/UnityEditorUtility.cs | 160 ++++++++++++++ .../Editor/UnityEditorUtility.cs.meta | 11 + src/{Editor => Internal}/EscEditorConsts.cs | 0 .../EscEditorConsts.cs.meta | 0 src/Internal/ReflectionExtensions.cs | 20 ++ src/Internal/ReflectionExtensions.cs.meta | 11 + src/{Utils => Internal}/SparseArray.cs | 5 +- src/{Utils => Internal}/SparseArray.cs.meta | 0 src/{Editor => Internal}/Utils.meta | 0 .../Utils/ColorUtility.cs | 0 .../Utils/ColorUtility.cs.meta | 0 src/{Editor => Internal}/Utils/RectUtility.cs | 0 .../Utils/RectUtility.cs.meta | 0 35 files changed, 323 insertions(+), 222 deletions(-) create mode 100644 src/Internal.meta rename src/{Utils => Internal}/BitMask.cs (100%) rename src/{Utils => Internal}/BitMask.cs.meta (100%) rename src/{ => Internal}/Editor.meta (77%) rename src/{Editor/EditorUtility.cs => Internal/Editor/EcsGUI.cs} (50%) rename src/{Editor/EditorUtility.cs.meta => Internal/Editor/EcsGUI.cs.meta} (83%) rename src/{ => Internal}/Editor/ExpandMatrix.cs (100%) rename src/{ => Internal}/Editor/ExpandMatrix.cs.meta (100%) rename src/{ => Internal}/Editor/SOWrappers.meta (100%) rename src/{ => Internal}/Editor/SOWrappers/RefEditorWrapper.cs (81%) rename src/{ => Internal}/Editor/SOWrappers/RefEditorWrapper.cs.meta (100%) rename src/{ => Internal}/Editor/SOWrappers/UnityObjEditorWrapper.cs (100%) rename src/{ => Internal}/Editor/SOWrappers/UnityObjEditorWrapper.cs.meta (100%) rename src/{ => Internal}/Editor/SOWrappers/WrapperBase.cs (100%) rename src/{ => Internal}/Editor/SOWrappers/WrapperBase.cs.meta (100%) create mode 100644 src/Internal/Editor/UnityEditorUtility.cs create mode 100644 src/Internal/Editor/UnityEditorUtility.cs.meta rename src/{Editor => Internal}/EscEditorConsts.cs (100%) rename src/{Editor => Internal}/EscEditorConsts.cs.meta (100%) create mode 100644 src/Internal/ReflectionExtensions.cs create mode 100644 src/Internal/ReflectionExtensions.cs.meta rename src/{Utils => Internal}/SparseArray.cs (96%) rename src/{Utils => Internal}/SparseArray.cs.meta (100%) rename src/{Editor => Internal}/Utils.meta (100%) rename src/{Editor => Internal}/Utils/ColorUtility.cs (100%) rename src/{Editor => Internal}/Utils/ColorUtility.cs.meta (100%) rename src/{Editor => Internal}/Utils/RectUtility.cs (100%) rename src/{Editor => Internal}/Utils/RectUtility.cs.meta (100%) diff --git a/src/Buildin/EcsDefaultWorldProvider.cs b/src/Buildin/EcsDefaultWorldProvider.cs index 35d4f40..dcd6b34 100644 --- a/src/Buildin/EcsDefaultWorldProvider.cs +++ b/src/Buildin/EcsDefaultWorldProvider.cs @@ -3,19 +3,5 @@ namespace DCFApixels.DragonECS { [CreateAssetMenu(fileName = nameof(EcsDefaultWorldProvider), menuName = EcsConsts.FRAMEWORK_NAME + "/WorldProviders/" + nameof(EcsDefaultWorldProvider), order = 1)] - public class EcsDefaultWorldProvider : EcsWorldProvider - { - //private static EcsDefaultWorldProvider _singleInstance; - //public static EcsDefaultWorldProvider SingletonInstance - //{ - // get - // { - // if (_singleInstance == null) - // { - // _singleInstance = FindOrCreateSingleton(); - // } - // return _singleInstance; - // } - //} - } + public class EcsDefaultWorldProvider : EcsWorldProvider { } } diff --git a/src/Buildin/EcsDefaultWorldSingletonProvider.cs b/src/Buildin/EcsDefaultWorldSingletonProvider.cs index c05aecc..cccf86b 100644 --- a/src/Buildin/EcsDefaultWorldSingletonProvider.cs +++ b/src/Buildin/EcsDefaultWorldSingletonProvider.cs @@ -14,10 +14,5 @@ return _instance; } } - - protected override EcsDefaultWorld BuildWorld() - { - return new EcsDefaultWorld(); - } } } diff --git a/src/Connectors/EcsWorldProvider.cs b/src/Connectors/EcsWorldProvider.cs index bd16af8..a0b096f 100644 --- a/src/Connectors/EcsWorldProvider.cs +++ b/src/Connectors/EcsWorldProvider.cs @@ -16,8 +16,29 @@ namespace DCFApixels.DragonECS [Serializable] public abstract class EcsWorldProvider : EcsWorldProviderBase where TWorld : EcsWorld { + private readonly static EcsWorldConfig _emptyConfig = new EcsWorldConfig(); private TWorld _world; + [SerializeField] + public short _worldID = -1; + + [Header("Default Configs")] + [Header("Entites")] + [SerializeField] + private int EntitiesCapacity = _emptyConfig.Get_EntitiesCapacity(); + + [Header("Groups")] + [SerializeField] + private int GroupCapacity = _emptyConfig.Get_GroupCapacity(); + + [Header("Pools/Components")] + [SerializeField] + private int PoolsCapacity = _emptyConfig.Get_PoolsCapacity(); + [SerializeField] + private int PoolComponentsCapacity = _emptyConfig.Get_PoolComponentsCapacity(); + [SerializeField] + private int PoolRecycledComponentsCapacity = _emptyConfig.Get_PoolRecycledComponentsCapacity(); + #region Properties public sealed override bool IsEmpty { @@ -74,7 +95,13 @@ namespace DCFApixels.DragonECS #region Events protected virtual TWorld BuildWorld() { - return (TWorld)Activator.CreateInstance(typeof(TWorld), new object[] { null, -1 }); + EcsWorldConfig config = new EcsWorldConfig(); + config.Set_EntitiesCapacity(EntitiesCapacity); + config.Set_GroupCapacity(GroupCapacity); + config.Set_PoolComponentsCapacity(PoolComponentsCapacity); + config.Set_PoolRecycledComponentsCapacity(PoolRecycledComponentsCapacity); + config.Set_PoolsCapacity(PoolsCapacity); + return (TWorld)Activator.CreateInstance(typeof(TWorld), new object[] { config, _worldID }); } protected virtual void OnWorldCreated(TWorld world) { } #endregion diff --git a/src/Connectors/Editor/EcsWorldProviderBaseEditor.cs b/src/Connectors/Editor/EcsWorldProviderBaseEditor.cs index 427660a..aba9bfe 100644 --- a/src/Connectors/Editor/EcsWorldProviderBaseEditor.cs +++ b/src/Connectors/Editor/EcsWorldProviderBaseEditor.cs @@ -12,18 +12,36 @@ namespace DCFApixels.DragonECS.Unity.Editors public override void OnInspectorGUI() { - base.OnInspectorGUI(); if (Target.IsEmpty) { - var style = EcsEditor.GetStyle(new Color32(255, 0, 75, 100)); + var style = UnityEditorUtility.GetStyle(new Color32(255, 0, 75, 100)); GUILayout.Box("Is Empty", style, GUILayout.ExpandWidth(true)); } else { - var style = EcsEditor.GetStyle(new Color32(75, 255, 0, 100)); + var style = UnityEditorUtility.GetStyle(new Color32(75, 255, 0, 100)); EcsWorld world = Target.GetRaw(); GUILayout.Box($"{world.GetMeta().Name} ( {world.id} )", style, GUILayout.ExpandWidth(true)); } + base.OnInspectorGUI(); + + GUILayout.Space(10); + + if (GUILayout.Button("Destroy")) + { + var w = Target.GetRaw(); + if (w != null && w.IsDestroyed == false) + { + w.Destroy(); + } + Target.SetRaw(null); + } + + Rect r = GUILayoutUtility.GetRect(EditorGUIUtility.currentViewWidth, 2f); + Color c = Color.white; + c.a = 0.3f; + EditorGUI.DrawRect(r, c); + GUILayout.Space(10); } } } diff --git a/src/Debug/UnityDebugService.cs b/src/Debug/UnityDebugService.cs index 20d3097..f29ed63 100644 --- a/src/Debug/UnityDebugService.cs +++ b/src/Debug/UnityDebugService.cs @@ -1,13 +1,18 @@ using System; using Unity.Profiling; +using UnityEditor; using UnityEngine; namespace DCFApixels.DragonECS { + [InitializeOnLoad] public class UnityDebugService : DebugService { private ProfilerMarker[] _profilerMarkers = new ProfilerMarker[64]; - + static UnityDebugService() + { + Activate(); + } public static void Activate() { Set(); diff --git a/src/EntityTemplate/Editor/EntityTemplateEditor.cs b/src/EntityTemplate/Editor/EntityTemplateEditor.cs index cfc04cb..f517417 100644 --- a/src/EntityTemplate/Editor/EntityTemplateEditor.cs +++ b/src/EntityTemplate/Editor/EntityTemplateEditor.cs @@ -1,13 +1,12 @@ -using DCFApixels.DragonECS.Unity.Internal; +#if UNITY_EDITOR +using DCFApixels.DragonECS.Unity.Internal; using System; using System.Reflection; +using UnityEditor; +using UnityEngine; -#if UNITY_EDITOR namespace DCFApixels.DragonECS.Unity.Editors { - using UnityEditor; - using UnityEngine; - public abstract class EntityTemplateEditorBase : Editor { private static readonly Rect RemoveButtonRect = new Rect(0f, 0f, 17f, 19f); @@ -20,13 +19,11 @@ namespace DCFApixels.DragonECS.Unity.Editors #region Init private void Init() { - if (genericMenu == null) - _isInit = false; - if (_isInit) - return; + if (genericMenu == null) { _isInit = false; } + if (_isInit) { return; } - var tmpstylebase = EcsEditor.GetStyle(new Color(0.9f, 0f, 0.22f), 0.5f); - var tmpStyle = EcsEditor.GetStyle(new Color(1f, 0.5f, 0.7f), 0.5f); + var tmpstylebase = UnityEditorUtility.GetStyle(new Color(0.9f, 0f, 0.22f), 0.5f); + var tmpStyle = UnityEditorUtility.GetStyle(new Color(1f, 0.5f, 0.7f), 0.5f); removeButtonStyle = new GUIStyle(EditorStyles.linkLabel); removeButtonStyle.alignment = TextAnchor.MiddleCenter; @@ -50,7 +47,7 @@ namespace DCFApixels.DragonECS.Unity.Editors string description = meta.Description; MetaGroup group = meta.Group; - if(group.Name.Length > 0) + if (group.Name.Length > 0) { name = group.Name + name; } @@ -111,7 +108,7 @@ namespace DCFApixels.DragonECS.Unity.Editors } DrawTop(target); - GUILayout.BeginVertical(EcsEditor.GetStyle(Color.black, 0.2f)); + GUILayout.BeginVertical(UnityEditorUtility.GetStyle(Color.black, 0.2f)); GUILayout.Label("", GUILayout.Height(0), GUILayout.ExpandWidth(true)); for (int i = 0; i < componentsProp.arraySize; i++) { @@ -164,7 +161,7 @@ namespace DCFApixels.DragonECS.Unity.Editors { componentType = componentProperty.managedReferenceValue.GetType(); ; } - + ITypeMeta meta = template is ITypeMeta metaOverride ? metaOverride : template.Type.ToMeta(); string name = meta.Name; string description = meta.Description; @@ -172,14 +169,15 @@ namespace DCFApixels.DragonECS.Unity.Editors Rect removeButtonRect = GUILayoutUtility.GetLastRect(); - GUIContent label = new GUIContent(name); + //GUIContent label = new GUIContent(name); + GUIContent label = UnityEditorUtility.GetLabel(name); bool isEmpty = componentType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Length <= 0; float padding = EditorGUIUtility.standardVerticalSpacing; Color alphaPanelColor = panelColor; alphaPanelColor.a = EscEditorConsts.COMPONENT_DRAWER_ALPHA; EditorGUI.BeginChangeCheck(); - GUILayout.BeginVertical(EcsEditor.GetStyle(alphaPanelColor)); + GUILayout.BeginVertical(UnityEditorUtility.GetStyle(alphaPanelColor)); #region Draw Component Block bool isRemoveComponent = false; @@ -204,12 +202,12 @@ namespace DCFApixels.DragonECS.Unity.Editors { OnRemoveComponentAt(index); } - if (!string.IsNullOrEmpty(description)) + if (string.IsNullOrEmpty(description) == false) { Rect tooltipIconRect = TooltipIconRect; tooltipIconRect.center = removeButtonRect.center; tooltipIconRect.center -= Vector2.right * tooltipIconRect.width; - GUIContent descriptionLabel = new GUIContent(EcsUnityConsts.INFO_MARK, description); + GUIContent descriptionLabel = UnityEditorUtility.GetLabel(EcsUnityConsts.INFO_MARK, description); GUI.Label(tooltipIconRect, descriptionLabel, EditorStyles.boldLabel); } #endregion diff --git a/src/EntityTemplate/Templates/ComponentTemplateBase.cs b/src/EntityTemplate/Templates/ComponentTemplateBase.cs index 845a1d8..b4a3e6b 100644 --- a/src/EntityTemplate/Templates/ComponentTemplateBase.cs +++ b/src/EntityTemplate/Templates/ComponentTemplateBase.cs @@ -1,5 +1,4 @@ -using Codice.Utils; -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Reflection; diff --git a/src/Internal.meta b/src/Internal.meta new file mode 100644 index 0000000..8241104 --- /dev/null +++ b/src/Internal.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: fc246fdeda320b649899ee44aca24e18 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/Utils/BitMask.cs b/src/Internal/BitMask.cs similarity index 100% rename from src/Utils/BitMask.cs rename to src/Internal/BitMask.cs diff --git a/src/Utils/BitMask.cs.meta b/src/Internal/BitMask.cs.meta similarity index 100% rename from src/Utils/BitMask.cs.meta rename to src/Internal/BitMask.cs.meta diff --git a/src/Editor.meta b/src/Internal/Editor.meta similarity index 77% rename from src/Editor.meta rename to src/Internal/Editor.meta index 336de05..732f508 100644 --- a/src/Editor.meta +++ b/src/Internal/Editor.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 7ff185425dcbca44f820bfc6c564d1d2 +guid: 93ac43c51e44bbb459de81017f530fbe folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/src/Editor/EditorUtility.cs b/src/Internal/Editor/EcsGUI.cs similarity index 50% rename from src/Editor/EditorUtility.cs rename to src/Internal/Editor/EcsGUI.cs index 8de4122..ec16950 100644 --- a/src/Editor/EditorUtility.cs +++ b/src/Internal/Editor/EcsGUI.cs @@ -2,63 +2,11 @@ using DCFApixels.DragonECS.Unity.Internal; using System; using System.Reflection; -using System.Runtime.InteropServices; -using System.Text; using UnityEditor; using UnityEngine; namespace DCFApixels.DragonECS.Unity.Editors { - internal static class EcsUnityEditorUtility - { - public static string TransformFieldName(string name) - { - if (name.Length <= 0) - { - return name; - } - StringBuilder b = new StringBuilder(); - bool nextWorld = true; - bool prewIsUpper = false; - - - for (int i = 0; i < name.Length; i++) - { - char c = name[i]; - if (char.IsLetter(c) == false) - { - nextWorld = true; - prewIsUpper = false; - continue; - } - - bool isUpper = char.IsUpper(c); - if (isUpper) - { - if (nextWorld == false && prewIsUpper == false) - { - b.Append(' '); - nextWorld = true; - } - } - - if (nextWorld) - { - b.Append(char.ToUpper(c)); - } - else - { - b.Append(c); - } - nextWorld = false; - prewIsUpper = isUpper; - } - - return b.ToString(); - } - } - - internal static class EcsGUI { internal readonly static Color GrayColor = new Color32(100, 100, 100, 255); @@ -89,23 +37,27 @@ namespace DCFApixels.DragonECS.Unity.Editors get { return DebugMonitorPrefs.instance.IsShowRuntimeComponents; } set { DebugMonitorPrefs.instance.IsShowRuntimeComponents = value; } } - public static void DrawRuntimeComponents(entlong entity) + public static void DrawRuntimeComponents(entlong entity, bool isWithFoldout = true) { if (entity.TryUnpack(out int entityID, out EcsWorld world)) { - DrawRuntimeComponents(entityID, world); + DrawRuntimeComponents(entityID, world, isWithFoldout); } } - public static void DrawRuntimeComponents(int entityID, EcsWorld world) + public static void DrawRuntimeComponents(int entityID, EcsWorld world, bool isWithFoldout = true) { var componentTypeIDs = world.GetComponentTypeIDs(entityID); - GUILayout.BeginVertical(EcsEditor.GetStyle(Color.black, 0.2f)); + GUILayout.BeginVertical(UnityEditorUtility.GetStyle(Color.black, 0.2f)); - IsShowRuntimeComponents = EditorGUILayout.Foldout(IsShowRuntimeComponents, "RUNTIME COMPONENTS"); - if (IsShowRuntimeComponents) + if (isWithFoldout) { - GUILayout.Box("", EcsEditor.GetStyle(GUI.color, 0.16f), GUILayout.ExpandWidth(true)); + IsShowRuntimeComponents = EditorGUILayout.BeginFoldoutHeaderGroup(IsShowRuntimeComponents, "RUNTIME COMPONENTS", EditorStyles.foldout); + EditorGUILayout.EndFoldoutHeaderGroup(); + } + if (isWithFoldout == false || IsShowRuntimeComponents) + { + GUILayout.Box("", UnityEditorUtility.GetStyle(GUI.color, 0.16f), GUILayout.ExpandWidth(true)); IsShowHidden = EditorGUI.Toggle(GUILayoutUtility.GetLastRect(), "Show Hidden", IsShowHidden); foreach (var componentTypeID in componentTypeIDs) { @@ -125,12 +77,12 @@ namespace DCFApixels.DragonECS.Unity.Editors { object data = pool.GetRaw(entityID); Color panelColor = meta.Color.ToUnityColor().Desaturate(EscEditorConsts.COMPONENT_DRAWER_DESATURATE); - GUILayout.BeginVertical(EcsEditor.GetStyle(panelColor, EscEditorConsts.COMPONENT_DRAWER_ALPHA)); + GUILayout.BeginVertical(UnityEditorUtility.GetStyle(panelColor, EscEditorConsts.COMPONENT_DRAWER_ALPHA)); EditorGUI.BeginChangeCheck(); Type componentType = pool.ComponentType; ExpandMatrix expandMatrix = ExpandMatrix.Take(componentType); - bool changed = DrawRuntimeData(componentType, new GUIContent(meta.Name), expandMatrix, data, out object resultData); + bool changed = DrawRuntimeData(componentType, UnityEditorUtility.GetLabel(meta.Name), expandMatrix, data, out object resultData); if (changed) { pool.SetRaw(entityID, resultData); @@ -158,12 +110,11 @@ namespace DCFApixels.DragonECS.Unity.Editors EditorGUI.indentLevel++; foreach (var field in type.GetFields(fieldFlags)) { - GUIContent subLabel = new GUIContent(EcsUnityEditorUtility.TransformFieldName(field.Name)); + GUIContent subLabel = UnityEditorUtility.GetLabel(UnityEditorUtility.TransformFieldName(field.Name)); if (DrawRuntimeData(field.FieldType, subLabel, expandMatrix, field.GetValue(data), out object fieldData)) { field.SetValue(data, fieldData); - - outData = fieldData; + outData = data; changed = true; } } @@ -175,8 +126,21 @@ namespace DCFApixels.DragonECS.Unity.Editors if (isUnityObject) { EditorGUI.BeginChangeCheck(); - UnityEngine.Object uobj = (UnityEngine.Object)data; - uobj = EditorGUILayout.ObjectField(label, uobj, fieldType, true); + var uobj = (UnityEngine.Object)data; + + bool isComponent = (typeof(UnityEngine.Component)).IsAssignableFrom(fieldType); + if (isComponent) + { + uobj = EditorGUILayout.ObjectField(label, uobj, typeof(UnityEngine.Object), true); + } + else + { + uobj = EditorGUILayout.ObjectField(label, uobj, fieldType, true); + } + if (isComponent && uobj is GameObject go) + { + uobj = go.GetComponent(fieldType); + } if (EditorGUI.EndChangeCheck()) { outData = uobj; @@ -198,6 +162,7 @@ namespace DCFApixels.DragonECS.Unity.Editors outData = w.Data; changed = true; } + w.Release(); } } @@ -206,104 +171,5 @@ namespace DCFApixels.DragonECS.Unity.Editors } } } - - - [InitializeOnLoad] - public static class EcsEditor - { - static EcsEditor() - { - colorBoxeStyles = new SparseArray(); - } - private static SparseArray colorBoxeStyles = new SparseArray(); - public static GUIStyle GetStyle(Color color, float alphaMultiplier) - { - color.a *= alphaMultiplier; - return GetStyle(color); - } - public static GUIStyle GetStyle(Color32 color32) - { - int colorCode = new Color32Union(color32).colorCode; - if (colorBoxeStyles.TryGetValue(colorCode, out GUIStyle style)) - { - if (style == null || style.normal.background == null) - { - style = CreateStyle(color32, colorCode); - colorBoxeStyles[colorCode] = style; - } - return style; - } - - style = CreateStyle(color32, colorCode); - colorBoxeStyles.Add(colorCode, style); - return style; - } - private static GUIStyle CreateStyle(Color32 color32, int colorCode) - { - GUIStyle result = new GUIStyle(GUI.skin.box); - Color componentColor = color32; - Texture2D texture2D = CreateTexture(2, 2, componentColor); - result.hover.background = texture2D; - result.focused.background = texture2D; - result.active.background = texture2D; - result.normal.background = texture2D; - return result; - } - private static Texture2D CreateTexture(int width, int height, Color color) - { - var pixels = new Color[width * height]; - for (var i = 0; i < pixels.Length; ++i) - pixels[i] = color; - - var result = new Texture2D(width, height); - result.SetPixels(pixels); - result.Apply(); - return result; - } - - #region Utils - [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 4)] - private readonly ref struct Color32Union - { - [FieldOffset(0)] - public readonly int colorCode; - [FieldOffset(0)] - public readonly byte r; - [FieldOffset(1)] - public readonly byte g; - [FieldOffset(2)] - public readonly byte b; - [FieldOffset(3)] - public readonly byte a; - public Color32Union(byte r, byte g, byte b, byte a) : this() - { - this.r = r; - this.g = g; - this.b = b; - this.a = a; - } - public Color32Union(Color32 color) : this() - { - r = color.r; - g = color.g; - b = color.b; - a = color.a; - } - } - #endregion - } - - public static class ReflectionExtensions - { - public static bool TryGetAttribute(this MemberInfo self, out T attrbiute) where T : Attribute - { - attrbiute = self.GetCustomAttribute(); - return attrbiute != null; - } - public static bool HasAttribute(this MemberInfo self) where T : Attribute - { - return self.GetCustomAttribute() != null; - } - } } #endif diff --git a/src/Editor/EditorUtility.cs.meta b/src/Internal/Editor/EcsGUI.cs.meta similarity index 83% rename from src/Editor/EditorUtility.cs.meta rename to src/Internal/Editor/EcsGUI.cs.meta index 1ab7889..40c8707 100644 --- a/src/Editor/EditorUtility.cs.meta +++ b/src/Internal/Editor/EcsGUI.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: f72bc8ca8108c2b4aac41df126dba1e1 +guid: f27d7dd0452a826479d2b19d7885ce49 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/src/Editor/ExpandMatrix.cs b/src/Internal/Editor/ExpandMatrix.cs similarity index 100% rename from src/Editor/ExpandMatrix.cs rename to src/Internal/Editor/ExpandMatrix.cs diff --git a/src/Editor/ExpandMatrix.cs.meta b/src/Internal/Editor/ExpandMatrix.cs.meta similarity index 100% rename from src/Editor/ExpandMatrix.cs.meta rename to src/Internal/Editor/ExpandMatrix.cs.meta diff --git a/src/Editor/SOWrappers.meta b/src/Internal/Editor/SOWrappers.meta similarity index 100% rename from src/Editor/SOWrappers.meta rename to src/Internal/Editor/SOWrappers.meta diff --git a/src/Editor/SOWrappers/RefEditorWrapper.cs b/src/Internal/Editor/SOWrappers/RefEditorWrapper.cs similarity index 81% rename from src/Editor/SOWrappers/RefEditorWrapper.cs rename to src/Internal/Editor/SOWrappers/RefEditorWrapper.cs index bab9af6..6025990 100644 --- a/src/Editor/SOWrappers/RefEditorWrapper.cs +++ b/src/Internal/Editor/SOWrappers/RefEditorWrapper.cs @@ -25,12 +25,12 @@ namespace DCFApixels.DragonECS.Unity.Editors return result; } } -} -[Serializable] -public class EmptyDummy -{ - public static readonly EmptyDummy Instance = new EmptyDummy(); - private EmptyDummy() { } + [Serializable] + internal class EmptyDummy + { + public static readonly EmptyDummy Instance = new EmptyDummy(); + private EmptyDummy() { } + } } #endif diff --git a/src/Editor/SOWrappers/RefEditorWrapper.cs.meta b/src/Internal/Editor/SOWrappers/RefEditorWrapper.cs.meta similarity index 100% rename from src/Editor/SOWrappers/RefEditorWrapper.cs.meta rename to src/Internal/Editor/SOWrappers/RefEditorWrapper.cs.meta diff --git a/src/Editor/SOWrappers/UnityObjEditorWrapper.cs b/src/Internal/Editor/SOWrappers/UnityObjEditorWrapper.cs similarity index 100% rename from src/Editor/SOWrappers/UnityObjEditorWrapper.cs rename to src/Internal/Editor/SOWrappers/UnityObjEditorWrapper.cs diff --git a/src/Editor/SOWrappers/UnityObjEditorWrapper.cs.meta b/src/Internal/Editor/SOWrappers/UnityObjEditorWrapper.cs.meta similarity index 100% rename from src/Editor/SOWrappers/UnityObjEditorWrapper.cs.meta rename to src/Internal/Editor/SOWrappers/UnityObjEditorWrapper.cs.meta diff --git a/src/Editor/SOWrappers/WrapperBase.cs b/src/Internal/Editor/SOWrappers/WrapperBase.cs similarity index 100% rename from src/Editor/SOWrappers/WrapperBase.cs rename to src/Internal/Editor/SOWrappers/WrapperBase.cs diff --git a/src/Editor/SOWrappers/WrapperBase.cs.meta b/src/Internal/Editor/SOWrappers/WrapperBase.cs.meta similarity index 100% rename from src/Editor/SOWrappers/WrapperBase.cs.meta rename to src/Internal/Editor/SOWrappers/WrapperBase.cs.meta diff --git a/src/Internal/Editor/UnityEditorUtility.cs b/src/Internal/Editor/UnityEditorUtility.cs new file mode 100644 index 0000000..2ad3da0 --- /dev/null +++ b/src/Internal/Editor/UnityEditorUtility.cs @@ -0,0 +1,160 @@ +#if UNITY_EDITOR +using DCFApixels.DragonECS.Unity.Internal; +using System.Runtime.InteropServices; +using System.Text; +using UnityEditor; +using UnityEngine; + +namespace DCFApixels.DragonECS.Unity.Editors +{ + [InitializeOnLoad] + internal static class UnityEditorUtility + { + static UnityEditorUtility() + { + colorBoxeStyles = new SparseArray(); + } + private static SparseArray colorBoxeStyles = new SparseArray(); + private static GUIContent _singletonContent = null; + + #region TransformFieldName + public static string TransformFieldName(string name) + { + if (name.Length <= 0) + { + return name; + } + StringBuilder b = new StringBuilder(); + bool nextWorld = true; + bool prewIsUpper = false; + + + for (int i = 0; i < name.Length; i++) + { + char c = name[i]; + if (char.IsLetter(c) == false) + { + nextWorld = true; + prewIsUpper = false; + continue; + } + + bool isUpper = char.IsUpper(c); + if (isUpper) + { + if (nextWorld == false && prewIsUpper == false) + { + b.Append(' '); + nextWorld = true; + } + } + + if (nextWorld) + { + b.Append(char.ToUpper(c)); + } + else + { + b.Append(c); + } + nextWorld = false; + prewIsUpper = isUpper; + } + + return b.ToString(); + } + #endregion + + #region Label + public static GUIContent GetLabel(string name, string tooltip = null) + { + if (_singletonContent == null) + { + _singletonContent = new GUIContent(); + } + _singletonContent.text = name; + _singletonContent.tooltip = tooltip; + return _singletonContent; + } + #endregion + + #region GetStyle + public static GUIStyle GetStyle(Color color, float alphaMultiplier) + { + color.a *= alphaMultiplier; + return GetStyle(color); + } + public static GUIStyle GetStyle(Color32 color32) + { + int colorCode = new Color32Union(color32).colorCode; + if (colorBoxeStyles.TryGetValue(colorCode, out GUIStyle style)) + { + if (style == null || style.normal.background == null) + { + style = CreateStyle(color32, colorCode); + colorBoxeStyles[colorCode] = style; + } + return style; + } + + style = CreateStyle(color32, colorCode); + colorBoxeStyles.Add(colorCode, style); + return style; + } + private static GUIStyle CreateStyle(Color32 color32, int colorCode) + { + GUIStyle result = new GUIStyle(GUI.skin.box); + Color componentColor = color32; + Texture2D texture2D = CreateTexture(2, 2, componentColor); + result.hover.background = texture2D; + result.focused.background = texture2D; + result.active.background = texture2D; + result.normal.background = texture2D; + return result; + } + private static Texture2D CreateTexture(int width, int height, Color color) + { + var pixels = new Color[width * height]; + for (var i = 0; i < pixels.Length; ++i) + pixels[i] = color; + + var result = new Texture2D(width, height); + result.SetPixels(pixels); + result.Apply(); + return result; + } + #endregion + + #region Utils + [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 4)] + private readonly ref struct Color32Union + { + [FieldOffset(0)] + public readonly int colorCode; + [FieldOffset(0)] + public readonly byte r; + [FieldOffset(1)] + public readonly byte g; + [FieldOffset(2)] + public readonly byte b; + [FieldOffset(3)] + public readonly byte a; + public Color32Union(byte r, byte g, byte b, byte a) : this() + { + this.r = r; + this.g = g; + this.b = b; + this.a = a; + } + public Color32Union(Color32 color) : this() + { + r = color.r; + g = color.g; + b = color.b; + a = color.a; + } + } + #endregion + } +} +#endif diff --git a/src/Internal/Editor/UnityEditorUtility.cs.meta b/src/Internal/Editor/UnityEditorUtility.cs.meta new file mode 100644 index 0000000..520c132 --- /dev/null +++ b/src/Internal/Editor/UnityEditorUtility.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6f06edb81ead46c49895b58f42772b32 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/Editor/EscEditorConsts.cs b/src/Internal/EscEditorConsts.cs similarity index 100% rename from src/Editor/EscEditorConsts.cs rename to src/Internal/EscEditorConsts.cs diff --git a/src/Editor/EscEditorConsts.cs.meta b/src/Internal/EscEditorConsts.cs.meta similarity index 100% rename from src/Editor/EscEditorConsts.cs.meta rename to src/Internal/EscEditorConsts.cs.meta diff --git a/src/Internal/ReflectionExtensions.cs b/src/Internal/ReflectionExtensions.cs new file mode 100644 index 0000000..dfd0800 --- /dev/null +++ b/src/Internal/ReflectionExtensions.cs @@ -0,0 +1,20 @@ +#if UNITY_EDITOR +using System; +using System.Reflection; + +namespace DCFApixels.DragonECS.Unity.Internal +{ + internal static class ReflectionExtensions + { + public static bool TryGetAttribute(this MemberInfo self, out T attrbiute) where T : Attribute + { + attrbiute = self.GetCustomAttribute(); + return attrbiute != null; + } + public static bool HasAttribute(this MemberInfo self) where T : Attribute + { + return self.GetCustomAttribute() != null; + } + } +} +#endif diff --git a/src/Internal/ReflectionExtensions.cs.meta b/src/Internal/ReflectionExtensions.cs.meta new file mode 100644 index 0000000..00f17aa --- /dev/null +++ b/src/Internal/ReflectionExtensions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5d6a12b84f1e0254b8c57e1a2f2bf8a1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/Utils/SparseArray.cs b/src/Internal/SparseArray.cs similarity index 96% rename from src/Utils/SparseArray.cs rename to src/Internal/SparseArray.cs index 340f17f..102d9ff 100644 --- a/src/Utils/SparseArray.cs +++ b/src/Internal/SparseArray.cs @@ -1,7 +1,4 @@ -//SparseArray. Analogous to Dictionary, but faster. -//Benchmark result of indexer.get speed test with 300 elements: -//[Dictinary: 5.786us] [SparseArray: 2.047us]. -using System; +using System; using System.Diagnostics.Contracts; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; diff --git a/src/Utils/SparseArray.cs.meta b/src/Internal/SparseArray.cs.meta similarity index 100% rename from src/Utils/SparseArray.cs.meta rename to src/Internal/SparseArray.cs.meta diff --git a/src/Editor/Utils.meta b/src/Internal/Utils.meta similarity index 100% rename from src/Editor/Utils.meta rename to src/Internal/Utils.meta diff --git a/src/Editor/Utils/ColorUtility.cs b/src/Internal/Utils/ColorUtility.cs similarity index 100% rename from src/Editor/Utils/ColorUtility.cs rename to src/Internal/Utils/ColorUtility.cs diff --git a/src/Editor/Utils/ColorUtility.cs.meta b/src/Internal/Utils/ColorUtility.cs.meta similarity index 100% rename from src/Editor/Utils/ColorUtility.cs.meta rename to src/Internal/Utils/ColorUtility.cs.meta diff --git a/src/Editor/Utils/RectUtility.cs b/src/Internal/Utils/RectUtility.cs similarity index 100% rename from src/Editor/Utils/RectUtility.cs rename to src/Internal/Utils/RectUtility.cs diff --git a/src/Editor/Utils/RectUtility.cs.meta b/src/Internal/Utils/RectUtility.cs.meta similarity index 100% rename from src/Editor/Utils/RectUtility.cs.meta rename to src/Internal/Utils/RectUtility.cs.meta From 23527c018325364c755ad4de1c108140a80364a1 Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Thu, 7 Mar 2024 03:24:02 +0800 Subject: [PATCH 29/50] rename GetPool to GetPoolInstance --- src/Buildin/UnityComponents.cs | 2 +- src/EntityTemplate/Templates/ComponentTemplateBase.cs | 4 ++-- src/Internal/Editor/EcsGUI.cs | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Buildin/UnityComponents.cs b/src/Buildin/UnityComponents.cs index 5a531c8..aa79743 100644 --- a/src/Buildin/UnityComponents.cs +++ b/src/Buildin/UnityComponents.cs @@ -39,7 +39,7 @@ namespace DCFApixels.DragonECS } public sealed override void Apply(int worldID, int entityID) { - EcsWorld.GetPool>>(worldID).TryAddOrGet(entityID) = component; + EcsWorld.GetPoolInstance>>(worldID).TryAddOrGet(entityID) = component; } public override void OnValidate(UnityEngine.Object obj) { diff --git a/src/EntityTemplate/Templates/ComponentTemplateBase.cs b/src/EntityTemplate/Templates/ComponentTemplateBase.cs index b4a3e6b..288b663 100644 --- a/src/EntityTemplate/Templates/ComponentTemplateBase.cs +++ b/src/EntityTemplate/Templates/ComponentTemplateBase.cs @@ -82,7 +82,7 @@ namespace DCFApixels.DragonECS { public override void Apply(int worldID, int entityID) { - EcsWorld.GetPool>(worldID).TryAddOrGet(entityID) = component; + EcsWorld.GetPoolInstance>(worldID).TryAddOrGet(entityID) = component; } } public abstract class TagComponentTemplate : ComponentTemplateBase @@ -90,7 +90,7 @@ namespace DCFApixels.DragonECS { public override void Apply(int worldID, int entityID) { - EcsWorld.GetPool>(worldID).Set(entityID, true); + EcsWorld.GetPoolInstance>(worldID).Set(entityID, true); } } } diff --git a/src/Internal/Editor/EcsGUI.cs b/src/Internal/Editor/EcsGUI.cs index ec16950..433a0f8 100644 --- a/src/Internal/Editor/EcsGUI.cs +++ b/src/Internal/Editor/EcsGUI.cs @@ -46,7 +46,7 @@ namespace DCFApixels.DragonECS.Unity.Editors } public static void DrawRuntimeComponents(int entityID, EcsWorld world, bool isWithFoldout = true) { - var componentTypeIDs = world.GetComponentTypeIDs(entityID); + var componentTypeIDs = world.GetComponentTypeIDsFor(entityID); GUILayout.BeginVertical(UnityEditorUtility.GetStyle(Color.black, 0.2f)); @@ -61,7 +61,7 @@ namespace DCFApixels.DragonECS.Unity.Editors IsShowHidden = EditorGUI.Toggle(GUILayoutUtility.GetLastRect(), "Show Hidden", IsShowHidden); foreach (var componentTypeID in componentTypeIDs) { - var pool = world.GetPool(componentTypeID); + var pool = world.GetPoolInstance(componentTypeID); { DrawRuntimeComponent(entityID, pool); } From a356d31937c6d427275673400189c94b9311d008 Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Thu, 7 Mar 2024 08:26:42 +0800 Subject: [PATCH 30/50] Update EcsWorldProvider.cs --- src/Connectors/EcsWorldProvider.cs | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/src/Connectors/EcsWorldProvider.cs b/src/Connectors/EcsWorldProvider.cs index a0b096f..f01c77c 100644 --- a/src/Connectors/EcsWorldProvider.cs +++ b/src/Connectors/EcsWorldProvider.cs @@ -16,7 +16,6 @@ namespace DCFApixels.DragonECS [Serializable] public abstract class EcsWorldProvider : EcsWorldProviderBase where TWorld : EcsWorld { - private readonly static EcsWorldConfig _emptyConfig = new EcsWorldConfig(); private TWorld _world; [SerializeField] @@ -25,19 +24,19 @@ namespace DCFApixels.DragonECS [Header("Default Configs")] [Header("Entites")] [SerializeField] - private int EntitiesCapacity = _emptyConfig.Get_EntitiesCapacity(); + private int EntitiesCapacity = EcsWorldConfig.Default.EntitiesCapacity; [Header("Groups")] [SerializeField] - private int GroupCapacity = _emptyConfig.Get_GroupCapacity(); + private int GroupCapacity = EcsWorldConfig.Default.GroupCapacity; [Header("Pools/Components")] [SerializeField] - private int PoolsCapacity = _emptyConfig.Get_PoolsCapacity(); + private int PoolsCapacity = EcsWorldConfig.Default.PoolsCapacity; [SerializeField] - private int PoolComponentsCapacity = _emptyConfig.Get_PoolComponentsCapacity(); + private int PoolComponentsCapacity = EcsWorldConfig.Default.PoolComponentsCapacity; [SerializeField] - private int PoolRecycledComponentsCapacity = _emptyConfig.Get_PoolRecycledComponentsCapacity(); + private int PoolRecycledComponentsCapacity = EcsWorldConfig.Default.PoolRecycledComponentsCapacity; #region Properties public sealed override bool IsEmpty @@ -95,13 +94,9 @@ namespace DCFApixels.DragonECS #region Events protected virtual TWorld BuildWorld() { - EcsWorldConfig config = new EcsWorldConfig(); - config.Set_EntitiesCapacity(EntitiesCapacity); - config.Set_GroupCapacity(GroupCapacity); - config.Set_PoolComponentsCapacity(PoolComponentsCapacity); - config.Set_PoolRecycledComponentsCapacity(PoolRecycledComponentsCapacity); - config.Set_PoolsCapacity(PoolsCapacity); - return (TWorld)Activator.CreateInstance(typeof(TWorld), new object[] { config, _worldID }); + EcsWorldConfig config = new EcsWorldConfig(EntitiesCapacity, GroupCapacity, PoolsCapacity, PoolComponentsCapacity, PoolRecycledComponentsCapacity); + ConfigContainer configs = new ConfigContainer().Set(config); + return (TWorld)Activator.CreateInstance(typeof(TWorld), new object[] { configs, _worldID }); } protected virtual void OnWorldCreated(TWorld world) { } #endregion From cb4ef1c85321da5a1eb039c1653c50d6b430d6d1 Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Thu, 7 Mar 2024 21:22:48 +0800 Subject: [PATCH 31/50] add runtime editing --- src/Connectors/EcsWorldProvider.cs | 32 +++++-- .../Editor/EntityTemplateEditor.cs | 36 +++---- src/Internal/Editor/EcsGUI.cs | 34 ++++++- src/Internal/Editor/UnityEditorUtility.cs | 94 ++++++++++++++++++- 4 files changed, 169 insertions(+), 27 deletions(-) diff --git a/src/Connectors/EcsWorldProvider.cs b/src/Connectors/EcsWorldProvider.cs index f01c77c..1f044fa 100644 --- a/src/Connectors/EcsWorldProvider.cs +++ b/src/Connectors/EcsWorldProvider.cs @@ -24,25 +24,45 @@ namespace DCFApixels.DragonECS [Header("Default Configs")] [Header("Entites")] [SerializeField] - private int EntitiesCapacity = EcsWorldConfig.Default.EntitiesCapacity; + private int _entitiesCapacity = EcsWorldConfig.Default.EntitiesCapacity; [Header("Groups")] [SerializeField] - private int GroupCapacity = EcsWorldConfig.Default.GroupCapacity; + private int _groupCapacity = EcsWorldConfig.Default.GroupCapacity; [Header("Pools/Components")] [SerializeField] - private int PoolsCapacity = EcsWorldConfig.Default.PoolsCapacity; + private int _poolsCapacity = EcsWorldConfig.Default.PoolsCapacity; [SerializeField] - private int PoolComponentsCapacity = EcsWorldConfig.Default.PoolComponentsCapacity; + private int _poolComponentsCapacity = EcsWorldConfig.Default.PoolComponentsCapacity; [SerializeField] - private int PoolRecycledComponentsCapacity = EcsWorldConfig.Default.PoolRecycledComponentsCapacity; + private int _poolRecycledComponentsCapacity = EcsWorldConfig.Default.PoolRecycledComponentsCapacity; #region Properties public sealed override bool IsEmpty { get { return _world == null; } } + public int EntitiesCapacity + { + get { return _entitiesCapacity; } + } + public int GroupCapacity + { + get { return _groupCapacity; } + } + public int PoolsCapacity + { + get { return _poolsCapacity; } + } + public int PoolComponentsCapacity + { + get { return _poolComponentsCapacity; } + } + public int PoolRecycledComponentsCapacity + { + get { return _poolRecycledComponentsCapacity; } + } #endregion #region Methods @@ -94,7 +114,7 @@ namespace DCFApixels.DragonECS #region Events protected virtual TWorld BuildWorld() { - EcsWorldConfig config = new EcsWorldConfig(EntitiesCapacity, GroupCapacity, PoolsCapacity, PoolComponentsCapacity, PoolRecycledComponentsCapacity); + EcsWorldConfig config = new EcsWorldConfig(_entitiesCapacity, _groupCapacity, _poolsCapacity, _poolComponentsCapacity, _poolRecycledComponentsCapacity); ConfigContainer configs = new ConfigContainer().Set(config); return (TWorld)Activator.CreateInstance(typeof(TWorld), new object[] { configs, _worldID }); } diff --git a/src/EntityTemplate/Editor/EntityTemplateEditor.cs b/src/EntityTemplate/Editor/EntityTemplateEditor.cs index f517417..054fdba 100644 --- a/src/EntityTemplate/Editor/EntityTemplateEditor.cs +++ b/src/EntityTemplate/Editor/EntityTemplateEditor.cs @@ -12,32 +12,32 @@ namespace DCFApixels.DragonECS.Unity.Editors private static readonly Rect RemoveButtonRect = new Rect(0f, 0f, 17f, 19f); private static readonly Rect TooltipIconRect = new Rect(0f, 0f, 21f, 15f); - private GUIStyle removeButtonStyle; - private GenericMenu genericMenu; + private GUIStyle _removeButtonStyle; + private GenericMenu _genericMenu; private bool _isInit = false; #region Init private void Init() { - if (genericMenu == null) { _isInit = false; } + if (_genericMenu == null) { _isInit = false; } if (_isInit) { return; } var tmpstylebase = UnityEditorUtility.GetStyle(new Color(0.9f, 0f, 0.22f), 0.5f); var tmpStyle = UnityEditorUtility.GetStyle(new Color(1f, 0.5f, 0.7f), 0.5f); - removeButtonStyle = new GUIStyle(EditorStyles.linkLabel); - removeButtonStyle.alignment = TextAnchor.MiddleCenter; + _removeButtonStyle = new GUIStyle(EditorStyles.linkLabel); + _removeButtonStyle.alignment = TextAnchor.MiddleCenter; - removeButtonStyle.normal = tmpstylebase.normal; - removeButtonStyle.hover = tmpStyle.normal; - removeButtonStyle.active = tmpStyle.normal; - removeButtonStyle.focused = tmpStyle.normal; + _removeButtonStyle.normal = tmpstylebase.normal; + _removeButtonStyle.hover = tmpStyle.normal; + _removeButtonStyle.active = tmpStyle.normal; + _removeButtonStyle.focused = tmpStyle.normal; - removeButtonStyle.padding = new RectOffset(0, 0, 0, 0); - removeButtonStyle.margin = new RectOffset(0, 0, 0, 0); - removeButtonStyle.border = new RectOffset(0, 0, 0, 0); + _removeButtonStyle.padding = new RectOffset(0, 0, 0, 0); + _removeButtonStyle.margin = new RectOffset(0, 0, 0, 0); + _removeButtonStyle.border = new RectOffset(0, 0, 0, 0); - genericMenu = new GenericMenu(); + _genericMenu = new GenericMenu(); var componentTemplateDummies = ComponentTemplateTypeCache.Dummies; foreach (var dummy in componentTemplateDummies) @@ -56,7 +56,7 @@ namespace DCFApixels.DragonECS.Unity.Editors { name = $"{name} {EcsUnityConsts.INFO_MARK}"; } - genericMenu.AddItem(new GUIContent(name, description), false, OnAddComponent, dummy); + _genericMenu.AddItem(new GUIContent(name, description), false, OnAddComponent, dummy); } _isInit = true; @@ -122,7 +122,7 @@ namespace DCFApixels.DragonECS.Unity.Editors if (GUILayout.Button("Add Component", GUILayout.Height(24f))) { Init(); - genericMenu.ShowAsContext(); + _genericMenu.ShowAsContext(); } } private void DrawFooter(ITemplateInternal target) @@ -167,8 +167,6 @@ namespace DCFApixels.DragonECS.Unity.Editors string description = meta.Description; Color panelColor = meta.Color.ToUnityColor().Desaturate(EscEditorConsts.COMPONENT_DRAWER_DESATURATE); - Rect removeButtonRect = GUILayoutUtility.GetLastRect(); - //GUIContent label = new GUIContent(name); GUIContent label = UnityEditorUtility.GetLabel(name); bool isEmpty = componentType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Length <= 0; @@ -176,6 +174,8 @@ namespace DCFApixels.DragonECS.Unity.Editors Color alphaPanelColor = panelColor; alphaPanelColor.a = EscEditorConsts.COMPONENT_DRAWER_ALPHA; + Rect removeButtonRect = GUILayoutUtility.GetLastRect(); + EditorGUI.BeginChangeCheck(); GUILayout.BeginVertical(UnityEditorUtility.GetStyle(alphaPanelColor)); @@ -231,7 +231,7 @@ namespace DCFApixels.DragonECS.Unity.Editors removeButtonRect.center = new Vector2(lastrect.xMax + removeButtonRect.width, lastrect.yMin + removeButtonRect.height / 2f); GUILayout.Label("", GUILayout.Width(removeButtonRect.width)); - if (GUI.Button(removeButtonRect, "x", removeButtonStyle)) + if (GUI.Button(removeButtonRect, "x", _removeButtonStyle)) { OnRemoveComponentAt(index); } diff --git a/src/Internal/Editor/EcsGUI.cs b/src/Internal/Editor/EcsGUI.cs index 433a0f8..41d866b 100644 --- a/src/Internal/Editor/EcsGUI.cs +++ b/src/Internal/Editor/EcsGUI.cs @@ -13,6 +13,8 @@ namespace DCFApixels.DragonECS.Unity.Editors internal readonly static Color GreenColor = new Color32(75, 255, 0, 255); internal readonly static Color RedColor = new Color32(255, 0, 75, 255); + private static readonly Rect RemoveButtonRect = new Rect(0f, 0f, 17f, 19f); + private static readonly Rect TooltipIconRect = new Rect(0f, 0f, 21f, 15f); //private static GUILayoutOption[] _defaultParams; //private static bool _isInit = false; //private static void Init() @@ -68,6 +70,13 @@ namespace DCFApixels.DragonECS.Unity.Editors } } GUILayout.EndVertical(); + + if (GUILayout.Button("Add Component", GUILayout.Height(24f))) + { + GenericMenu genericMenu = RuntimeComponentsUtility.GetAddComponentGenericMenu(world); + RuntimeComponentsUtility.CurrentEntityID = entityID; + genericMenu.ShowAsContext(); + } } private static readonly BindingFlags fieldFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; private static void DrawRuntimeComponent(int entityID, IEcsPool pool) @@ -77,15 +86,36 @@ namespace DCFApixels.DragonECS.Unity.Editors { object data = pool.GetRaw(entityID); Color panelColor = meta.Color.ToUnityColor().Desaturate(EscEditorConsts.COMPONENT_DRAWER_DESATURATE); + + float padding = EditorGUIUtility.standardVerticalSpacing; + Rect removeButtonRect = GUILayoutUtility.GetLastRect(); + GUILayout.BeginVertical(UnityEditorUtility.GetStyle(panelColor, EscEditorConsts.COMPONENT_DRAWER_ALPHA)); EditorGUI.BeginChangeCheck(); + bool isRemoveComponent = false; + removeButtonRect.yMin = removeButtonRect.yMax; + removeButtonRect.yMax += RemoveButtonRect.height; + removeButtonRect.xMin = removeButtonRect.xMax - RemoveButtonRect.width; + removeButtonRect.center += Vector2.up * padding * 2f; + if (GUI.Button(removeButtonRect, "x")) + { + isRemoveComponent = true; + } + Type componentType = pool.ComponentType; ExpandMatrix expandMatrix = ExpandMatrix.Take(componentType); bool changed = DrawRuntimeData(componentType, UnityEditorUtility.GetLabel(meta.Name), expandMatrix, data, out object resultData); - if (changed) + if (changed || isRemoveComponent) { - pool.SetRaw(entityID, resultData); + if (isRemoveComponent) + { + pool.Del(entityID); + } + else + { + pool.SetRaw(entityID, resultData); + } } GUILayout.EndVertical(); diff --git a/src/Internal/Editor/UnityEditorUtility.cs b/src/Internal/Editor/UnityEditorUtility.cs index 2ad3da0..5a4a43b 100644 --- a/src/Internal/Editor/UnityEditorUtility.cs +++ b/src/Internal/Editor/UnityEditorUtility.cs @@ -1,5 +1,7 @@ #if UNITY_EDITOR using DCFApixels.DragonECS.Unity.Internal; +using System; +using System.Collections.Generic; using System.Runtime.InteropServices; using System.Text; using UnityEditor; @@ -156,5 +158,95 @@ namespace DCFApixels.DragonECS.Unity.Editors } #endregion } + + internal static class RuntimeComponentsUtility + { + public struct WorldData + { + public GenericMenu addComponentGenericMenu; + public int poolsCount; + public WorldData(GenericMenu addComponentGenericMenu, int poolsCount) + { + this.addComponentGenericMenu = addComponentGenericMenu; + this.poolsCount = poolsCount; + } + } + //world id + private static Dictionary _worldDatas = new Dictionary(); + + public static GenericMenu GetAddComponentGenericMenu(EcsWorld world) + { + if (_worldDatas.TryGetValue(world, out WorldData data)) + { + if (data.poolsCount != world.PoolsCount) + { + data = CreateWorldData(world); + _worldDatas[world] = data; + } + } + else + { + data = CreateWorldData(world); + _worldDatas[world] = data; + world.AddListener(new Listener(world)); + } + + return data.addComponentGenericMenu; + } + + private static WorldData CreateWorldData(EcsWorld world) + { + GenericMenu genericMenu = new GenericMenu(); + + var pools = world.AllPools; + for (int i = 0; i < world.PoolsCount; i++) + { + var pool = pools[i]; + if (pool.IsNullOrDummy()) + { + i--; + continue; + } + var meta = pool.ComponentType.ToMeta(); + + genericMenu.AddItem(new GUIContent(meta.Name, meta.Description), false, OnAddComponent, pool); + } + return new WorldData(genericMenu, world.PoolsCount); + } + + public static int CurrentEntityID = 0; + + private static void OnAddComponent(object userData) + { + IEcsPool pool = (IEcsPool)userData; + if (pool.World.IsUsed(CurrentEntityID) == false) + { + return; + } + if (pool.Has(CurrentEntityID) == false) + { + pool.AddRaw(CurrentEntityID, Activator.CreateInstance(pool.ComponentType)); + } + else + { + Debug.LogWarning($"Entity({CurrentEntityID}) already has component {EcsDebugUtility.GetGenericTypeName(pool.ComponentType)}."); + } + } + + private class Listener : IEcsWorldEventListener + { + private EcsWorld _world; + public Listener(EcsWorld world) + { + _world = world; + } + public void OnReleaseDelEntityBuffer(ReadOnlySpan buffer) { } + public void OnWorldDestroy() + { + _worldDatas.Remove(_world); + } + public void OnWorldResize(int newSize) { } + } + } } -#endif +#endif \ No newline at end of file From a2340ae3c3a8742bb1b14777284623cb042f55b5 Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Sat, 9 Mar 2024 03:35:01 +0800 Subject: [PATCH 32/50] update --- src/Buildin/UnityComponents.cs | 10 +- src/Buildin/UnityGameCyclieProcesses.cs | 244 +++++++++--------- src/Connectors/EcsEntityConnect.cs | 63 +++-- .../Editor/EcsEntityConnectEditor.cs | 40 ++- .../Editor/EntityTemplateEditor.cs | 34 +-- src/Internal/Editor/EcsGUI.cs | 80 ++++-- 6 files changed, 284 insertions(+), 187 deletions(-) diff --git a/src/Buildin/UnityComponents.cs b/src/Buildin/UnityComponents.cs index aa79743..57f5e73 100644 --- a/src/Buildin/UnityComponents.cs +++ b/src/Buildin/UnityComponents.cs @@ -22,8 +22,14 @@ namespace DCFApixels.DragonECS { this.obj = obj; } - IEnumerator IEnumerable.GetEnumerator() => throw new NotImplementedException(); //IntelliSense hack - IEnumerator IEnumerable.GetEnumerator() => throw new NotImplementedException(); //IntelliSense hack + IEnumerator IEnumerable.GetEnumerator() //IntelliSense hack + { + throw new NotImplementedException(); + } + IEnumerator IEnumerable.GetEnumerator() //IntelliSense hack + { + throw new NotImplementedException(); + } } #region Unity Component Templates diff --git a/src/Buildin/UnityGameCyclieProcesses.cs b/src/Buildin/UnityGameCyclieProcesses.cs index aa086c1..12a1f0e 100644 --- a/src/Buildin/UnityGameCyclieProcesses.cs +++ b/src/Buildin/UnityGameCyclieProcesses.cs @@ -1,139 +1,141 @@ -using DCFApixels.DragonECS.Internal; -using DCFApixels.DragonECS.RunnersCore; +using DCFApixels.DragonECS.RunnersCore; +using DCFApixels.DragonECS.Unity.Internal; namespace DCFApixels.DragonECS { + [MetaName(nameof(DrawGizmos))] + [MetaColor(MetaColor.Orange)] public interface IEcsGizmosProcess : IEcsProcess { - public void DrawGizmos(EcsPipeline pipeline); + public void DrawGizmos(); } - public static class IEcsGizmosProcessExtensions - { - public static void DrawGizmos(this EcsPipeline systems) - { - systems.GetRunnerInstance().DrawGizmos(systems); - } - } - + [MetaName(nameof(LateRun))] + [MetaColor(MetaColor.Orange)] public interface IEcsLateRunProcess : IEcsProcess { - public void LateRun(EcsPipeline pipeline); - } - public static class IEcsLateRunSystemExtensions - { - public static void LateRun(this EcsPipeline pipeline) - { - pipeline.GetRunnerInstance().LateRun(pipeline); - } + public void LateRun(); } + [MetaName(nameof(FixedRun))] + [MetaColor(MetaColor.Orange)] public interface IEcsFixedRunProcess : IEcsProcess { - public void FixedRun(EcsPipeline pipeline); + public void FixedRun(); } - public static class IEcsFixedRunSystemExtensions + + public static class UnityProcessExtensions { + public static void DrawGizmos(this EcsPipeline pipeline) + { + pipeline.GetRunnerInstance().DrawGizmos(); + } + public static void LateRun(this EcsPipeline pipeline) + { + pipeline.GetRunnerInstance().LateRun(); + } public static void FixedRun(this EcsPipeline pipeline) { - pipeline.GetRunnerInstance().FixedRun(pipeline); - } - } - - namespace Internal - { - [MetaColor(MetaColor.Orange)] - public class EcsLateGizmosRunner : EcsRunner, IEcsGizmosProcess - { -#if DEBUG && !DISABLE_DEBUG - private EcsProfilerMarker[] _markers; -#endif - public void DrawGizmos(EcsPipeline pipeline) - { -#if DEBUG && !DISABLE_DEBUG - for (int i = 0; i < Process.Length; i++) - { - using (_markers[i].Auto()) - Process[i].DrawGizmos(pipeline); - } -#else - foreach (var item in targets) item.DrawGizmos(pipeline); -#endif - } - -#if DEBUG && !DISABLE_DEBUG - protected override void OnSetup() - { - _markers = new EcsProfilerMarker[Process.Length]; - for (int i = 0; i < Process.Length; i++) - { - _markers[i] = new EcsProfilerMarker($"{Process[i].GetType().Name}.{nameof(DrawGizmos)}"); - } - } -#endif - } - - [MetaColor(MetaColor.Orange)] - public class EcsLateRunRunner : EcsRunner, IEcsLateRunProcess - { -#if DEBUG && !DISABLE_DEBUG - private EcsProfilerMarker[] _markers; -#endif - public void LateRun(EcsPipeline pipeline) - { -#if DEBUG && !DISABLE_DEBUG - for (int i = 0; i < Process.Length; i++) - { - using (_markers[i].Auto()) - { - Process[i].LateRun(pipeline); - } - } -#else - foreach (var item in targets) item.LateRun(pipeline); -#endif - } - -#if DEBUG && !DISABLE_DEBUG - protected override void OnSetup() - { - _markers = new EcsProfilerMarker[Process.Length]; - for (int i = 0; i < Process.Length; i++) - { - _markers[i] = new EcsProfilerMarker($"EcsRunner.{Process[i].GetType().Name}.{nameof(LateRun)}"); - } - } -#endif - } - [MetaColor(MetaColor.Orange)] - public class EcsFixedRunRunner : EcsRunner, IEcsFixedRunProcess - { -#if DEBUG && !DISABLE_DEBUG - private EcsProfilerMarker[] _markers; -#endif - public void FixedRun(EcsPipeline pipeline) - { -#if DEBUG && !DISABLE_DEBUG - for (int i = 0; i < Process.Length; i++) - { - using (_markers[i].Auto()) - { - Process[i].FixedRun(pipeline); - } - } -#else - foreach (var item in targets) item.FixedRun(pipeline); -#endif - } - -#if DEBUG && !DISABLE_DEBUG - protected override void OnSetup() - { - _markers = new EcsProfilerMarker[Process.Length]; - for (int i = 0; i < Process.Length; i++) - { - _markers[i] = new EcsProfilerMarker($"EcsRunner.{Process[i].GetType().Name}.{nameof(FixedRun)}"); - } - } -#endif + pipeline.GetRunnerInstance().FixedRun(); } } } +namespace DCFApixels.DragonECS.Unity.Internal +{ + + [MetaColor(MetaColor.Orange)] + public class EcsLateGizmosRunner : EcsRunner, IEcsGizmosProcess + { +#if DEBUG && !DISABLE_DEBUG + private EcsProfilerMarker[] _markers; +#endif + public void DrawGizmos() + { +#if DEBUG && !DISABLE_DEBUG + for (int i = 0; i < Process.Length; i++) + { + using (_markers[i].Auto()) + { + Process[i].DrawGizmos(); + } + } +#else + foreach (var item in targets) item.DrawGizmos(); +#endif + } + +#if DEBUG && !DISABLE_DEBUG + protected override void OnSetup() + { + _markers = new EcsProfilerMarker[Process.Length]; + for (int i = 0; i < Process.Length; i++) + { + _markers[i] = new EcsProfilerMarker($"{Process[i].GetType().Name}.{nameof(DrawGizmos)}"); + } + } +#endif + } + + [MetaColor(MetaColor.Orange)] + public class EcsLateRunRunner : EcsRunner, IEcsLateRunProcess + { +#if DEBUG && !DISABLE_DEBUG + private EcsProfilerMarker[] _markers; +#endif + public void LateRun() + { +#if DEBUG && !DISABLE_DEBUG + for (int i = 0; i < Process.Length; i++) + { + using (_markers[i].Auto()) + { + Process[i].LateRun(); + } + } +#else + foreach (var item in targets) item.LateRun(); +#endif + } + +#if DEBUG && !DISABLE_DEBUG + protected override void OnSetup() + { + _markers = new EcsProfilerMarker[Process.Length]; + for (int i = 0; i < Process.Length; i++) + { + _markers[i] = new EcsProfilerMarker($"EcsRunner.{Process[i].GetType().Name}.{nameof(LateRun)}"); + } + } +#endif + } + [MetaColor(MetaColor.Orange)] + public class EcsFixedRunRunner : EcsRunner, IEcsFixedRunProcess + { +#if DEBUG && !DISABLE_DEBUG + private EcsProfilerMarker[] _markers; +#endif + public void FixedRun() + { +#if DEBUG && !DISABLE_DEBUG + for (int i = 0; i < Process.Length; i++) + { + using (_markers[i].Auto()) + { + Process[i].FixedRun(); + } + } +#else + foreach (var item in targets) item.FixedRun(); +#endif + } + +#if DEBUG && !DISABLE_DEBUG + protected override void OnSetup() + { + _markers = new EcsProfilerMarker[Process.Length]; + for (int i = 0; i < Process.Length; i++) + { + _markers[i] = new EcsProfilerMarker($"EcsRunner.{Process[i].GetType().Name}.{nameof(FixedRun)}"); + } + } +#endif + } +} diff --git a/src/Connectors/EcsEntityConnect.cs b/src/Connectors/EcsEntityConnect.cs index 6974007..f12313f 100644 --- a/src/Connectors/EcsEntityConnect.cs +++ b/src/Connectors/EcsEntityConnect.cs @@ -1,3 +1,5 @@ +using System.Collections.Generic; +using System.Linq; using System.Runtime.CompilerServices; using UnityEngine; @@ -7,8 +9,8 @@ namespace DCFApixels.DragonECS { private sealed class Aspect : EcsAspect { - public readonly EcsPool unityGameObjects; - public Aspect(Builder b) + public EcsPool unityGameObjects; + protected override void Init(Builder b) { unityGameObjects = b.Include(); } @@ -22,16 +24,11 @@ namespace DCFApixels.DragonECS [SerializeField] private MonoEntityTemplate[] _monoTemplates; - internal void SetTemplates_Editor(MonoEntityTemplate[] tempaltes) - { - _monoTemplates = tempaltes; - } - #region Properties public entlong Entity { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => _entity; + get { return _entity; } } public EcsWorld World { @@ -43,46 +40,74 @@ namespace DCFApixels.DragonECS [MethodImpl(MethodImplOptions.AggressiveInlining)] get => _entity.IsAlive; } + public IEnumerable ScriptableTemplates + { + get { return _scriptableTemplates; } + } + public IEnumerable MonoTemplates + { + get { return _monoTemplates; } + } + public IEnumerable AllTemplates + { + get { return ((IEnumerable)_scriptableTemplates).Concat(_monoTemplates); } + } #endregion + #region Connect public void ConnectWith(entlong entity, bool applyTemplates = false) { - if (_entity.TryGetID(out int oldE) && _world != null) + if (_entity.TryGetID(out int oldEntityID) && _world != null) { - var s = _world.GetAspect(); - s.unityGameObjects.Del(oldE); + var a = _world.GetAspect(); + a.unityGameObjects.Del(oldEntityID); } _world = null; - if (entity.TryGetID(out int newE)) + if (entity.TryGetID(out int newEntityID)) { _entity = entity; _world = _entity.World; - var s = _world.GetAspect(); - if (!s.unityGameObjects.Has(newE)) s.unityGameObjects.Add(newE) = new UnityGameObject(gameObject); - + var a = _world.GetAspect(); + if (!a.unityGameObjects.Has(newEntityID)) + { + a.unityGameObjects.Add(newEntityID) = new UnityGameObject(gameObject); + } if (applyTemplates) + { ApplyTemplates(); + } } else { _entity = entlong.NULL; } } + #endregion + + #region ApplyTemplates public void ApplyTemplates() { ApplyTemplatesFor(_entity.ID); } public void ApplyTemplatesFor(int entityID) { - foreach (var t in _scriptableTemplates) + foreach (var template in _scriptableTemplates) { - t.Apply(_world.id, entityID); + template.Apply(_world.id, entityID); } - foreach (var t in _monoTemplates) + foreach (var template in _monoTemplates) { - t.Apply(_world.id, entityID); + template.Apply(_world.id, entityID); } } + #endregion + + #region Editor + internal void SetTemplates_Editor(MonoEntityTemplate[] tempaltes) + { + _monoTemplates = tempaltes; + } + #endregion } } \ No newline at end of file diff --git a/src/Connectors/Editor/EcsEntityConnectEditor.cs b/src/Connectors/Editor/EcsEntityConnectEditor.cs index 72b4f81..491f731 100644 --- a/src/Connectors/Editor/EcsEntityConnectEditor.cs +++ b/src/Connectors/Editor/EcsEntityConnectEditor.cs @@ -1,7 +1,10 @@ #if UNITY_EDITOR using DCFApixels.DragonECS.Unity.Internal; +using System.Collections.Generic; +using System.Linq; using UnityEditor; using UnityEngine; +using static PlasticGui.LaunchDiffParameters; namespace DCFApixels.DragonECS.Unity.Editors { @@ -94,14 +97,39 @@ namespace DCFApixels.DragonECS.Unity.Editors private void DrawTemplates() { + EditorGUI.BeginChangeCheck(); var iterator = serializedObject.GetIterator(); iterator.NextVisible(true); - bool enterChildren = true; - while (iterator.NextVisible(enterChildren)) + while (iterator.NextVisible(false)) { EditorGUILayout.PropertyField(iterator, true); - enterChildren = false; } + if (EditorGUI.EndChangeCheck()) + { + serializedObject.ApplyModifiedProperties(); + } + } + + private void Autoset(EcsEntityConnect target) + { + var result = target.MonoTemplates.Where(o => o != null).Union(GetTemplatesFor(target.transform)); + + target.SetTemplates_Editor(result.ToArray()); + EditorUtility.SetDirty(target); + } + private IEnumerable GetTemplatesFor(Transform parent) + { + IEnumerable result = parent.GetComponents(); + for (int i = 0; i < parent.childCount; i++) + { + var child = parent.GetChild(i); + if (child.TryGetComponent(out _)) + { + return Enumerable.Empty(); + } + result = result.Concat(GetTemplatesFor(child)); + } + return result; } private void DrawButtons() @@ -109,15 +137,13 @@ namespace DCFApixels.DragonECS.Unity.Editors GUILayout.BeginHorizontal(); if (GUILayout.Button("Autoset")) { - Target.SetTemplates_Editor(Target.GetComponents()); - EditorUtility.SetDirty(target); + Autoset(Target); } if (GUILayout.Button("Autoset Cascade")) { foreach (var item in Target.GetComponentsInChildren()) { - item.SetTemplates_Editor(item.GetComponents()); - EditorUtility.SetDirty(item); + Autoset(item); } } GUILayout.EndHorizontal(); diff --git a/src/EntityTemplate/Editor/EntityTemplateEditor.cs b/src/EntityTemplate/Editor/EntityTemplateEditor.cs index 054fdba..6787868 100644 --- a/src/EntityTemplate/Editor/EntityTemplateEditor.cs +++ b/src/EntityTemplate/Editor/EntityTemplateEditor.cs @@ -107,43 +107,35 @@ namespace DCFApixels.DragonECS.Unity.Editors return; } - DrawTop(target); GUILayout.BeginVertical(UnityEditorUtility.GetStyle(Color.black, 0.2f)); + DrawTop(target); GUILayout.Label("", GUILayout.Height(0), GUILayout.ExpandWidth(true)); for (int i = 0; i < componentsProp.arraySize; i++) { DrawComponentData(componentsProp.GetArrayElementAtIndex(i), i); } GUILayout.EndVertical(); - DrawFooter(target); } private void DrawTop(ITemplateInternal target) { - if (GUILayout.Button("Add Component", GUILayout.Height(24f))) + switch (EcsGUI.Layout.AddClearComponentButtons()) { - Init(); - _genericMenu.ShowAsContext(); - } - } - private void DrawFooter(ITemplateInternal target) - { - if (GUILayout.Button("Clear", GUILayout.Height(24f))) - { - Init(); - serializedObject.FindProperty(target.ComponentsPropertyName).ClearArray(); - serializedObject.ApplyModifiedProperties(); + case EcsGUI.AddClearComponentButton.AddComponent: + Init(); + _genericMenu.ShowAsContext(); + break; + case EcsGUI.AddClearComponentButton.Clear: + Init(); + serializedObject.FindProperty(target.ComponentsPropertyName).ClearArray(); + serializedObject.ApplyModifiedProperties(); + break; } } + private void DrawComponentData(SerializedProperty componentRefProp, int index) { IComponentTemplate template = componentRefProp.managedReferenceValue as IComponentTemplate; - if (template == null) - { - DrawDamagedComponent(componentRefProp, index); - return; - } - - if (componentRefProp.managedReferenceValue == null) + if (template == null || componentRefProp.managedReferenceValue == null) { DrawDamagedComponent(componentRefProp, index); return; diff --git a/src/Internal/Editor/EcsGUI.cs b/src/Internal/Editor/EcsGUI.cs index 41d866b..aa4ebb9 100644 --- a/src/Internal/Editor/EcsGUI.cs +++ b/src/Internal/Editor/EcsGUI.cs @@ -4,6 +4,7 @@ using System; using System.Reflection; using UnityEditor; using UnityEngine; +using static UnityEngine.GraphicsBuffer; namespace DCFApixels.DragonECS.Unity.Editors { @@ -15,6 +16,25 @@ namespace DCFApixels.DragonECS.Unity.Editors private static readonly Rect RemoveButtonRect = new Rect(0f, 0f, 17f, 19f); private static readonly Rect TooltipIconRect = new Rect(0f, 0f, 21f, 15f); + + private static bool IsShowHidden + { + get { return DebugMonitorPrefs.instance.IsShowHidden; } + set { DebugMonitorPrefs.instance.IsShowHidden = value; } + } + private static bool IsShowRuntimeComponents + { + get { return DebugMonitorPrefs.instance.IsShowRuntimeComponents; } + set { DebugMonitorPrefs.instance.IsShowRuntimeComponents = value; } + } + + public enum AddClearComponentButton : byte + { + None = 0, + AddComponent, + Clear, + } + //private static GUILayoutOption[] _defaultParams; //private static bool _isInit = false; //private static void Init() @@ -27,17 +47,29 @@ namespace DCFApixels.DragonECS.Unity.Editors // _isInit = true; //} + public static AddClearComponentButton AddClearComponentButtons(Rect position) + { + //Rect rect = GUILayoutUtility.GetRect(EditorGUIUtility.currentViewWidth, 36f); + position = RectUtility.AddPadding(position, 20f, 20f, 12f, 2f); + var (left, right) = RectUtility.HorizontalSliceLerp(position, 0.75f); + + if (GUI.Button(left, "Add Component")) + { + return AddClearComponentButton.AddComponent; + } + if (GUI.Button(right, "Clear")) + { + return AddClearComponentButton.Clear; + } + return AddClearComponentButton.None; + } + public static class Layout { - private static bool IsShowHidden + + public static AddClearComponentButton AddClearComponentButtons() { - get { return DebugMonitorPrefs.instance.IsShowHidden; } - set { DebugMonitorPrefs.instance.IsShowHidden = value; } - } - private static bool IsShowRuntimeComponents - { - get { return DebugMonitorPrefs.instance.IsShowRuntimeComponents; } - set { DebugMonitorPrefs.instance.IsShowRuntimeComponents = value; } + return EcsGUI.AddClearComponentButtons(GUILayoutUtility.GetRect(EditorGUIUtility.currentViewWidth, 36f)); } public static void DrawRuntimeComponents(entlong entity, bool isWithFoldout = true) { @@ -59,8 +91,21 @@ namespace DCFApixels.DragonECS.Unity.Editors } if (isWithFoldout == false || IsShowRuntimeComponents) { + switch (EcsGUI.Layout.AddClearComponentButtons()) + { + case AddClearComponentButton.AddComponent: + GenericMenu genericMenu = RuntimeComponentsUtility.GetAddComponentGenericMenu(world); + RuntimeComponentsUtility.CurrentEntityID = entityID; + genericMenu.ShowAsContext(); + break; + case AddClearComponentButton.Clear: + break; + } + + GUILayout.Box("", UnityEditorUtility.GetStyle(GUI.color, 0.16f), GUILayout.ExpandWidth(true)); IsShowHidden = EditorGUI.Toggle(GUILayoutUtility.GetLastRect(), "Show Hidden", IsShowHidden); + foreach (var componentTypeID in componentTypeIDs) { var pool = world.GetPoolInstance(componentTypeID); @@ -70,13 +115,6 @@ namespace DCFApixels.DragonECS.Unity.Editors } } GUILayout.EndVertical(); - - if (GUILayout.Button("Add Component", GUILayout.Height(24f))) - { - GenericMenu genericMenu = RuntimeComponentsUtility.GetAddComponentGenericMenu(world); - RuntimeComponentsUtility.CurrentEntityID = entityID; - genericMenu.ShowAsContext(); - } } private static readonly BindingFlags fieldFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; private static void DrawRuntimeComponent(int entityID, IEcsPool pool) @@ -123,9 +161,17 @@ namespace DCFApixels.DragonECS.Unity.Editors } private static bool DrawRuntimeData(Type fieldType, GUIContent label, ExpandMatrix expandMatrix, object data, out object outData) - { - Type type = data.GetType(); + { + outData = data; + Type type = data == null ? typeof(void) : data.GetType(); + bool isUnityObject = typeof(UnityEngine.Object).IsAssignableFrom(fieldType); + + if (isUnityObject == false && data == null) + { + EditorGUILayout.TextField(label, "Null"); + return false; + } ref bool isExpanded = ref expandMatrix.Down(); bool changed = false; outData = data; From 18d9fc29bd5ea4e373a6f6475e283d5be6f8adbb Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Sat, 9 Mar 2024 09:42:04 +0800 Subject: [PATCH 33/50] update --- src/Connectors/AutoEntityCreator.cs | 5 +- src/Connectors/EcsEntityConnect.cs | 2 +- .../Editor/EcsEntityConnectEditor.cs | 60 ++--- .../Editor/EntityTemplateEditor.cs | 12 +- src/Internal/Editor/EcsGUI.cs | 236 ++++++++++++++++-- src/Internal/Editor/UnityEditorUtility.cs | 12 + 6 files changed, 260 insertions(+), 67 deletions(-) diff --git a/src/Connectors/AutoEntityCreator.cs b/src/Connectors/AutoEntityCreator.cs index 8953844..e2b31a7 100644 --- a/src/Connectors/AutoEntityCreator.cs +++ b/src/Connectors/AutoEntityCreator.cs @@ -30,6 +30,7 @@ namespace DCFApixels.DragonECS } #endregion + #region Methods private void AutoResolveWorldProviderDependensy() { _world = EcsDefaultWorldSingletonProvider.Instance; @@ -54,13 +55,14 @@ namespace DCFApixels.DragonECS } _created = true; } - private void InitConnect(EcsEntityConnect connect, EcsWorld world) { connect.ConnectWith(world.NewEntityLong()); connect.ApplyTemplates(); } + #endregion + #region Editor #if UNITY_EDITOR internal void Autoset_Editor() { @@ -68,5 +70,6 @@ namespace DCFApixels.DragonECS AutoResolveWorldProviderDependensy(); } #endif + #endregion } } \ No newline at end of file diff --git a/src/Connectors/EcsEntityConnect.cs b/src/Connectors/EcsEntityConnect.cs index f12313f..7ab7271 100644 --- a/src/Connectors/EcsEntityConnect.cs +++ b/src/Connectors/EcsEntityConnect.cs @@ -60,7 +60,7 @@ namespace DCFApixels.DragonECS if (_entity.TryGetID(out int oldEntityID) && _world != null) { var a = _world.GetAspect(); - a.unityGameObjects.Del(oldEntityID); + a.unityGameObjects.TryDel(oldEntityID); } _world = null; diff --git a/src/Connectors/Editor/EcsEntityConnectEditor.cs b/src/Connectors/Editor/EcsEntityConnectEditor.cs index 491f731..cfe896b 100644 --- a/src/Connectors/Editor/EcsEntityConnectEditor.cs +++ b/src/Connectors/Editor/EcsEntityConnectEditor.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.Linq; using UnityEditor; using UnityEngine; -using static PlasticGui.LaunchDiffParameters; namespace DCFApixels.DragonECS.Unity.Editors { @@ -43,56 +42,29 @@ namespace DCFApixels.DragonECS.Unity.Editors private void DrawEntityInfo(EcsEntityConnect[] targets) { - //TODO Отрефакторить + bool isConnected = Target.Entity.TryUnpack(out int id, out short gen, out EcsWorld world); + EcsGUI.EntityStatus status = IsMultipleTargets ? EcsGUI.EntityStatus.Undefined : isConnected ? EcsGUI.EntityStatus.Alive : EcsGUI.EntityStatus.NotAlive; + float width = EditorGUIUtility.currentViewWidth; float height = EditorGUIUtility.singleLineHeight; - Rect entityRect = GUILayoutUtility.GetRect(width, height + 3f); - var (entityInfoRect, statusRect) = RectUtility.VerticalSliceBottom(entityRect, 3f); + Rect rect = GUILayoutUtility.GetRect(width, height + 3f); + var (left, delEntityButtonRect) = RectUtility.HorizontalSliceRight(rect, height + 3); + var (entityRect, unlinkButtonRect) = RectUtility.HorizontalSliceRight(left, height + 3); - Color w = Color.gray; - w.a = 0.6f; - Color b = Color.black; - b.a = 0.55f; - EditorGUI.DrawRect(entityInfoRect, w); - - var (idRect, genWorldRect) = RectUtility.HorizontalSliceLerp(entityInfoRect, 0.5f); - var (genRect, worldRect) = RectUtility.HorizontalSliceLerp(genWorldRect, 0.5f); - - idRect = RectUtility.AddPadding(idRect, 2, 1, 0, 0); - genRect = RectUtility.AddPadding(genRect, 1, 1, 0, 0); - worldRect = RectUtility.AddPadding(worldRect, 1, 2, 0, 0); - EditorGUI.DrawRect(idRect, b); - EditorGUI.DrawRect(genRect, b); - EditorGUI.DrawRect(worldRect, b); - - bool isConnected = Target.Entity.TryUnpack(out int id, out short gen, out short world); - - GUIStyle style = new GUIStyle(EditorStyles.numberField); - style.alignment = TextAnchor.MiddleCenter; - style.font = EditorStyles.boldFont; - if (IsMultipleTargets == false && isConnected) + using (new EditorGUI.DisabledScope(status != EcsGUI.EntityStatus.Alive)) { - Color statusColor = EcsGUI.GreenColor; - statusColor.a = 0.6f; - EditorGUI.DrawRect(statusRect, statusColor); - - EditorGUI.IntField(idRect, id, style); - EditorGUI.IntField(genRect, gen, style); - EditorGUI.IntField(worldRect, world, style); - } - else - { - Color statusColor = IsMultipleTargets ? new Color32(200, 200, 200, 255) : EcsGUI.RedColor; - statusColor.a = 0.6f; - EditorGUI.DrawRect(statusRect, statusColor); - - using (new EditorGUI.DisabledScope(true)) + if (EcsGUI.UnlinkButton(unlinkButtonRect)) { - GUI.Label(idRect, "Entity ID", style); - GUI.Label(genRect, "Generation", style); - GUI.Label(worldRect, "World ID", style); + Target.ConnectWith(entlong.NULL); + } + if (EcsGUI.DelEntityButton(delEntityButtonRect)) + { + world.DelEntity(id); + Target.ConnectWith(entlong.NULL); } } + + EcsGUI.DrawEntity(entityRect, status, id, gen, world.id); } private void DrawTemplates() diff --git a/src/EntityTemplate/Editor/EntityTemplateEditor.cs b/src/EntityTemplate/Editor/EntityTemplateEditor.cs index 6787868..2bba492 100644 --- a/src/EntityTemplate/Editor/EntityTemplateEditor.cs +++ b/src/EntityTemplate/Editor/EntityTemplateEditor.cs @@ -9,8 +9,8 @@ namespace DCFApixels.DragonECS.Unity.Editors { public abstract class EntityTemplateEditorBase : Editor { - private static readonly Rect RemoveButtonRect = new Rect(0f, 0f, 17f, 19f); - private static readonly Rect TooltipIconRect = new Rect(0f, 0f, 21f, 15f); + private static readonly Rect RemoveButtonRect = new Rect(0f, 0f, 19f, 19f); + private static readonly Rect TooltipIconRect = new Rect(0f, 0f, 19f, 19f); private GUIStyle _removeButtonStyle; private GenericMenu _genericMenu; @@ -141,6 +141,7 @@ namespace DCFApixels.DragonECS.Unity.Editors return; } + Type componentType; SerializedProperty componentProperty = componentRefProp; ComponentTemplateBase customInitializer = componentProperty.managedReferenceValue as ComponentTemplateBase; @@ -177,7 +178,8 @@ namespace DCFApixels.DragonECS.Unity.Editors removeButtonRect.yMax += RemoveButtonRect.height; removeButtonRect.xMin = removeButtonRect.xMax - RemoveButtonRect.width; removeButtonRect.center += Vector2.up * padding * 2f; - if (GUI.Button(removeButtonRect, "x")) + + if (EcsGUI.CloseButton(removeButtonRect)) { isRemoveComponent = true; } @@ -199,12 +201,12 @@ namespace DCFApixels.DragonECS.Unity.Editors Rect tooltipIconRect = TooltipIconRect; tooltipIconRect.center = removeButtonRect.center; tooltipIconRect.center -= Vector2.right * tooltipIconRect.width; - GUIContent descriptionLabel = UnityEditorUtility.GetLabel(EcsUnityConsts.INFO_MARK, description); - GUI.Label(tooltipIconRect, descriptionLabel, EditorStyles.boldLabel); + EcsGUI.DescriptionIcon(tooltipIconRect, description); } #endregion GUILayout.EndVertical(); + if (EditorGUI.EndChangeCheck()) { componentProperty.serializedObject.ApplyModifiedProperties(); diff --git a/src/Internal/Editor/EcsGUI.cs b/src/Internal/Editor/EcsGUI.cs index aa4ebb9..fbdfcc4 100644 --- a/src/Internal/Editor/EcsGUI.cs +++ b/src/Internal/Editor/EcsGUI.cs @@ -4,18 +4,31 @@ using System; using System.Reflection; using UnityEditor; using UnityEngine; -using static UnityEngine.GraphicsBuffer; namespace DCFApixels.DragonECS.Unity.Editors { internal static class EcsGUI { + public struct ColorScope : IDisposable + { + private readonly Color _oldColor; + public ColorScope(Color color) + { + _oldColor = GUI.color; + GUI.color = color; + } + public void Dispose() + { + GUI.color = _oldColor; + } + } + internal readonly static Color GrayColor = new Color32(100, 100, 100, 255); internal readonly static Color GreenColor = new Color32(75, 255, 0, 255); internal readonly static Color RedColor = new Color32(255, 0, 75, 255); - private static readonly Rect RemoveButtonRect = new Rect(0f, 0f, 17f, 19f); - private static readonly Rect TooltipIconRect = new Rect(0f, 0f, 21f, 15f); + private static readonly Rect RemoveButtonRect = new Rect(0f, 0f, 19f, 19f); + private static readonly Rect TooltipIconRect = new Rect(0f, 0f, 19f, 19f); private static bool IsShowHidden { @@ -34,6 +47,13 @@ namespace DCFApixels.DragonECS.Unity.Editors AddComponent, Clear, } + [Flags] + public enum EntityStatus + { + NotAlive = 0, + Alive = 1 << 0, + Undefined = 1 << 1, + } //private static GUILayoutOption[] _defaultParams; //private static bool _isInit = false; @@ -47,6 +67,178 @@ namespace DCFApixels.DragonECS.Unity.Editors // _isInit = true; //} + + internal static bool HitTest(Rect rect, Event evt) + { + return HitTest(rect, evt.mousePosition); + } + internal static bool HitTest(Rect rect, Vector2 point) + { + int offset = 0; + return HitTest(rect, point, offset); + } + internal static bool HitTest(Rect rect, Vector2 point, int offset) + { + return point.x >= rect.xMin - (float)offset && point.x < rect.xMax + (float)offset && point.y >= rect.yMin - (float)offset && point.y < rect.yMax + (float)offset; + } + + //public static bool IconButton(Rect position, Texture normal, Texture hover, GUIStyle normalStyle = null, GUIStyle hoverStyle = null) + //{ + // Color dc = GUI.color; + // GUI.color = Color.clear; //Хак чтобы сделать реакцию от курсора мыши без лага + // bool result = GUI.Button(position, "", EditorStyles.miniButtonMid); + // GUI.color = dc; + // + // var current = Event.current; + // { + // if (HitTest(position, current)) + // { + // if (hoverStyle != null && Event.current.type == EventType.Repaint) + // { + // hoverStyle.Draw(position, true, false, false, false); + // } + // GUI.DrawTexture(position, hover); + // } + // else + // { + // if (normalStyle != null && Event.current.type == EventType.Repaint) + // { + // normalStyle.Draw(position, false, false, false, false); + // } + // GUI.DrawTexture(position, normal); + // } + // } + // + // return result; + //} + public static (bool, bool) IconButton(Rect position) + { + Color dc = GUI.color; + GUI.color = Color.clear; //Хак чтобы сделать реакцию от курсора мыши без лага + bool result = GUI.Button(position, "", EditorStyles.miniButtonMid); + GUI.color = dc; + + var current = Event.current; + return (GUI.enabled && HitTest(position, current), result); + } + public static bool SingleIconButton(Rect position, Texture icon) + { + var (hover, click) = IconButton(position); + Color color = GUI.color; + float enableMultiplier = GUI.enabled ? 1f : 0.72f; + + if (hover) + { + if (Event.current.type == EventType.Repaint) + { + GUI.color = Color.white * 2.2f * enableMultiplier; + EditorStyles.helpBox.Draw(position, hover, false, false, false); + } + + Rect rect = RectUtility.AddPadding(position, -1f); + GUI.color = Color.white * enableMultiplier; + GUI.DrawTexture(rect, icon); + } + else + { + if (Event.current.type == EventType.Repaint) + { + GUI.color = Color.white * 1.7f * enableMultiplier; + EditorStyles.helpBox.Draw(position, hover, false, false, false); + } + GUI.color = Color.white * enableMultiplier; + GUI.DrawTexture(position, icon); + } + GUI.color = color; + return click; + } + public static void DescriptionIcon(Rect position, string description) + { + using (new ColorScope(new Color(1f, 1f, 1f, 0.8f))) + { + GUIContent descriptionLabel = UnityEditorUtility.GetLabel(EditorGUIUtility.IconContent("d__Help@2x").image, description); + GUI.Label(position, descriptionLabel, EditorStyles.boldLabel); + } + } + public static bool CloseButton(Rect position) + { + using (new ColorScope(new Color(1f, 1f, 1f, 0.8f))) + { + var (hover, click) = IconButton(position); + if (hover) + { + Rect rect = RectUtility.AddPadding(position, -4f); + GUI.DrawTexture(rect, EditorGUIUtility.IconContent("P4_DeletedLocal@2x").image); + } + else + { + GUI.DrawTexture(position, EditorGUIUtility.IconContent("d_winbtn_win_close@2x").image); + } + return click; + } + } + public static bool UnlinkButton(Rect position) + { + return SingleIconButton(position, EditorGUIUtility.IconContent("d_Unlinked@2x").image); + } + public static bool DelEntityButton(Rect position) + { + return SingleIconButton(position, EditorGUIUtility.IconContent("d_winbtn_win_close@2x").image); + } + public static void DrawEntity(Rect position, EntityStatus status, int id, short gen, short world) + { + var (entityInfoRect, statusRect) = RectUtility.VerticalSliceBottom(position, 3f); + + Color w = Color.gray; + w.a = 0.6f; + Color b = Color.black; + b.a = 0.55f; + EditorGUI.DrawRect(entityInfoRect, w); + + var (idRect, genWorldRect) = RectUtility.HorizontalSliceLerp(entityInfoRect, 0.4f); + var (genRect, worldRect) = RectUtility.HorizontalSliceLerp(genWorldRect, 0.5f); + + idRect = RectUtility.AddPadding(idRect, 2, 1, 0, 0); + genRect = RectUtility.AddPadding(genRect, 1, 1, 0, 0); + worldRect = RectUtility.AddPadding(worldRect, 1, 2, 0, 0); + EditorGUI.DrawRect(idRect, b); + EditorGUI.DrawRect(genRect, b); + EditorGUI.DrawRect(worldRect, b); + + + GUIStyle style = new GUIStyle(EditorStyles.numberField); + style.alignment = TextAnchor.MiddleCenter; + style.font = EditorStyles.boldFont; + if (status == EntityStatus.Alive) + { + Color statusColor = EcsGUI.GreenColor; + statusColor.a = 0.6f; + EditorGUI.DrawRect(statusRect, statusColor); + + EditorGUI.IntField(idRect, id, style); + EditorGUI.IntField(genRect, gen, style); + EditorGUI.IntField(worldRect, world, style); + } + else + { + Color statusColor = status == EntityStatus.Undefined ? new Color32(200, 200, 200, 255) : EcsGUI.RedColor; + statusColor.a = 0.6f; + EditorGUI.DrawRect(statusRect, statusColor); + + using (new EditorGUI.DisabledScope(true)) + { + GUI.Label(idRect, "Entity ID", style); + GUI.Label(genRect, "Generation", style); + GUI.Label(worldRect, "World ID", style); + } + } + } + + public static bool AddComponentButtons(Rect position) + { + position = RectUtility.AddPadding(position, 20f, 20f, 12f, 2f); + return GUI.Button(position, "Add Component"); + } public static AddClearComponentButton AddClearComponentButtons(Rect position) { //Rect rect = GUILayoutUtility.GetRect(EditorGUIUtility.currentViewWidth, 36f); @@ -66,7 +258,16 @@ namespace DCFApixels.DragonECS.Unity.Editors public static class Layout { - + public static void DrawEntity(EntityStatus status, int id, short gen, short world) + { + float width = EditorGUIUtility.currentViewWidth; + float height = EditorGUIUtility.singleLineHeight; + EcsGUI.DrawEntity(GUILayoutUtility.GetRect(width, height + 3f), status, id, gen, world); + } + public static bool AddComponentButtons() + { + return EcsGUI.AddComponentButtons(GUILayoutUtility.GetRect(EditorGUIUtility.currentViewWidth, 36f)); + } public static AddClearComponentButton AddClearComponentButtons() { return EcsGUI.AddClearComponentButtons(GUILayoutUtility.GetRect(EditorGUIUtility.currentViewWidth, 36f)); @@ -91,18 +292,13 @@ namespace DCFApixels.DragonECS.Unity.Editors } if (isWithFoldout == false || IsShowRuntimeComponents) { - switch (EcsGUI.Layout.AddClearComponentButtons()) + if (EcsGUI.Layout.AddComponentButtons()) { - case AddClearComponentButton.AddComponent: - GenericMenu genericMenu = RuntimeComponentsUtility.GetAddComponentGenericMenu(world); - RuntimeComponentsUtility.CurrentEntityID = entityID; - genericMenu.ShowAsContext(); - break; - case AddClearComponentButton.Clear: - break; + GenericMenu genericMenu = RuntimeComponentsUtility.GetAddComponentGenericMenu(world); + RuntimeComponentsUtility.CurrentEntityID = entityID; + genericMenu.ShowAsContext(); } - GUILayout.Box("", UnityEditorUtility.GetStyle(GUI.color, 0.16f), GUILayout.ExpandWidth(true)); IsShowHidden = EditorGUI.Toggle(GUILayoutUtility.GetLastRect(), "Show Hidden", IsShowHidden); @@ -136,7 +332,7 @@ namespace DCFApixels.DragonECS.Unity.Editors removeButtonRect.yMax += RemoveButtonRect.height; removeButtonRect.xMin = removeButtonRect.xMax - RemoveButtonRect.width; removeButtonRect.center += Vector2.up * padding * 2f; - if (GUI.Button(removeButtonRect, "x")) + if (EcsGUI.CloseButton(removeButtonRect)) { isRemoveComponent = true; } @@ -156,15 +352,23 @@ namespace DCFApixels.DragonECS.Unity.Editors } } + if (string.IsNullOrEmpty(meta.Description) == false) + { + Rect tooltipIconRect = TooltipIconRect; + tooltipIconRect.center = removeButtonRect.center; + tooltipIconRect.center -= Vector2.right * tooltipIconRect.width; + EcsGUI.DescriptionIcon(tooltipIconRect, meta.Description); + } + GUILayout.EndVertical(); } } private static bool DrawRuntimeData(Type fieldType, GUIContent label, ExpandMatrix expandMatrix, object data, out object outData) - { + { outData = data; Type type = data == null ? typeof(void) : data.GetType(); - + bool isUnityObject = typeof(UnityEngine.Object).IsAssignableFrom(fieldType); if (isUnityObject == false && data == null) diff --git a/src/Internal/Editor/UnityEditorUtility.cs b/src/Internal/Editor/UnityEditorUtility.cs index 5a4a43b..2be801c 100644 --- a/src/Internal/Editor/UnityEditorUtility.cs +++ b/src/Internal/Editor/UnityEditorUtility.cs @@ -75,6 +75,18 @@ namespace DCFApixels.DragonECS.Unity.Editors _singletonContent = new GUIContent(); } _singletonContent.text = name; + _singletonContent.image = null; + _singletonContent.tooltip = tooltip; + return _singletonContent; + } + public static GUIContent GetLabel(Texture image, string tooltip = null) + { + if (_singletonContent == null) + { + _singletonContent = new GUIContent(); + } + _singletonContent.text = string.Empty; + _singletonContent.image = image; _singletonContent.tooltip = tooltip; return _singletonContent; } From d6190b455b45792f04d8230d8f02e61b119d8bda Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Sat, 9 Mar 2024 09:56:45 +0800 Subject: [PATCH 34/50] update --- src/Connectors/AutoEntityCreator.cs | 1 + src/Connectors/EcsEntityConnect.cs | 1 + src/Connectors/Editor/AutoEntityCreatorEditor.cs | 14 +++++++++++++- src/EntityTemplate/Templates/MonoEntityTemplate.cs | 1 + 4 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/Connectors/AutoEntityCreator.cs b/src/Connectors/AutoEntityCreator.cs index e2b31a7..f109ad7 100644 --- a/src/Connectors/AutoEntityCreator.cs +++ b/src/Connectors/AutoEntityCreator.cs @@ -2,6 +2,7 @@ using UnityEngine; namespace DCFApixels.DragonECS { + [DisallowMultipleComponent] public class AutoEntityCreator : MonoBehaviour { [SerializeField] diff --git a/src/Connectors/EcsEntityConnect.cs b/src/Connectors/EcsEntityConnect.cs index 7ab7271..f266ad9 100644 --- a/src/Connectors/EcsEntityConnect.cs +++ b/src/Connectors/EcsEntityConnect.cs @@ -5,6 +5,7 @@ using UnityEngine; namespace DCFApixels.DragonECS { + [DisallowMultipleComponent] public class EcsEntityConnect : MonoBehaviour { private sealed class Aspect : EcsAspect diff --git a/src/Connectors/Editor/AutoEntityCreatorEditor.cs b/src/Connectors/Editor/AutoEntityCreatorEditor.cs index 07155c8..7c77873 100644 --- a/src/Connectors/Editor/AutoEntityCreatorEditor.cs +++ b/src/Connectors/Editor/AutoEntityCreatorEditor.cs @@ -10,7 +10,19 @@ namespace DCFApixels.DragonECS.Unity.Editors { public override void OnInspectorGUI() { - base.OnInspectorGUI(); + EditorGUI.BeginChangeCheck(); + var iterator = serializedObject.GetIterator(); + iterator.NextVisible(true); + while (iterator.NextVisible(false)) + { + EditorGUILayout.PropertyField(iterator, true); + } + if (EditorGUI.EndChangeCheck()) + { + serializedObject.ApplyModifiedProperties(); + } + + if (GUILayout.Button("Autoset")) { foreach (var tr in targets) diff --git a/src/EntityTemplate/Templates/MonoEntityTemplate.cs b/src/EntityTemplate/Templates/MonoEntityTemplate.cs index 3e7d248..5bb3d5f 100644 --- a/src/EntityTemplate/Templates/MonoEntityTemplate.cs +++ b/src/EntityTemplate/Templates/MonoEntityTemplate.cs @@ -3,6 +3,7 @@ using UnityEngine; namespace DCFApixels.DragonECS { + [DisallowMultipleComponent] public class MonoEntityTemplate : MonoBehaviour, ITemplateInternal { [SerializeReference] From b78285169752433181cc67c1e2f9d50f648ae153 Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Sat, 9 Mar 2024 22:36:35 +0800 Subject: [PATCH 35/50] update --- src/Connectors/AutoEntityCreator.cs | 21 +++- src/Connectors/EcsEntityConnect.cs | 53 ++++++++++- .../Editor/AutoEntityCreatorEditor.cs | 30 +++++- .../Editor/EcsEntityConnectEditor.cs | 95 ++++++++----------- src/Internal/Editor/EcsGUI.cs | 92 ++++++++++-------- src/Internal/Utils/RectUtility.cs | 13 ++- 6 files changed, 199 insertions(+), 105 deletions(-) diff --git a/src/Connectors/AutoEntityCreator.cs b/src/Connectors/AutoEntityCreator.cs index f109ad7..86db544 100644 --- a/src/Connectors/AutoEntityCreator.cs +++ b/src/Connectors/AutoEntityCreator.cs @@ -65,10 +65,27 @@ namespace DCFApixels.DragonECS #region Editor #if UNITY_EDITOR + [ContextMenu("Autoset")] internal void Autoset_Editor() { - _connect = GetComponentInChildren(); - AutoResolveWorldProviderDependensy(); + foreach (var connect in GetComponentsInChildren()) + { + if (connect.GetComponentInParent() == this) + { + _connect = connect; + AutoResolveWorldProviderDependensy(); + break; + } + } + } + [ContextMenu("Autoset Cascade")] + internal void AutosetCascade_Editor() + { + foreach (var target in GetComponentsInChildren()) + { + target.Autoset_Editor(); + } + } #endif #endregion diff --git a/src/Connectors/EcsEntityConnect.cs b/src/Connectors/EcsEntityConnect.cs index f266ad9..073c5f4 100644 --- a/src/Connectors/EcsEntityConnect.cs +++ b/src/Connectors/EcsEntityConnect.cs @@ -1,7 +1,9 @@ using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; +using UnityEditor; using UnityEngine; +using static UnityEngine.GraphicsBuffer; namespace DCFApixels.DragonECS { @@ -105,10 +107,57 @@ namespace DCFApixels.DragonECS #endregion #region Editor - internal void SetTemplates_Editor(MonoEntityTemplate[] tempaltes) +#if UNITY_EDITOR + [ContextMenu("Autoset")] + internal void Autoset_Editor() { - _monoTemplates = tempaltes; + Autoset(this); } + [ContextMenu("Autoset Cascade")] + internal void AutosetCascade_Editor() + { + foreach (var item in GetComponentsInChildren()) + { + Autoset(item); + } + } + [ContextMenu("Unlink Entity")] + internal void UnlinkEntity_Editor() + { + ConnectWith(entlong.NULL); + } + [ContextMenu("Delete Entity")] + internal void DeleteEntity_Editor() + { + if (_entity.TryUnpack(out int id, out EcsWorld world)) + { + world.DelEntity(id); + } + UnlinkEntity_Editor(); + } + + private static void Autoset(EcsEntityConnect target) + { + var result = target.MonoTemplates.Where(o => o != null).Union(GetTemplatesFor(target.transform)); + + target._monoTemplates = result.ToArray(); + EditorUtility.SetDirty(target); + } + private static IEnumerable GetTemplatesFor(Transform parent) + { + IEnumerable result = parent.GetComponents(); + for (int i = 0; i < parent.childCount; i++) + { + var child = parent.GetChild(i); + if (child.TryGetComponent(out _)) + { + return Enumerable.Empty(); + } + result = result.Concat(GetTemplatesFor(child)); + } + return result; + } +#endif #endregion } } \ No newline at end of file diff --git a/src/Connectors/Editor/AutoEntityCreatorEditor.cs b/src/Connectors/Editor/AutoEntityCreatorEditor.cs index 7c77873..91d27d8 100644 --- a/src/Connectors/Editor/AutoEntityCreatorEditor.cs +++ b/src/Connectors/Editor/AutoEntityCreatorEditor.cs @@ -1,4 +1,5 @@ #if UNITY_EDITOR +using DCFApixels.DragonECS.Unity.Internal; using UnityEditor; using UnityEngine; @@ -8,6 +9,8 @@ namespace DCFApixels.DragonECS.Unity.Editors [CanEditMultipleObjects] public class AutoEntityCreatorEditor : Editor { + private AutoEntityCreator Target => (AutoEntityCreator)target; + public override void OnInspectorGUI() { EditorGUI.BeginChangeCheck(); @@ -21,15 +24,32 @@ namespace DCFApixels.DragonECS.Unity.Editors { serializedObject.ApplyModifiedProperties(); } + DrawControlButtons(); + } - if (GUILayout.Button("Autoset")) + private void DrawControlButtons() + { + float height = EcsGUI.EntityBarHeight; + Rect rect = GUILayoutUtility.GetRect(EditorGUIUtility.currentViewWidth, height); + EditorGUI.DrawRect(rect, new Color(0f, 0f, 0f, 0.1f)); + rect = RectUtility.AddPadding(rect, 2f, 0f); + var (left, autosetCascadeRect) = RectUtility.HorizontalSliceRight(rect, height); + var (_, autosetRect) = RectUtility.HorizontalSliceRight(left, height); + + if (EcsGUI.AutosetCascadeButton(autosetCascadeRect)) { - foreach (var tr in targets) + foreach (AutoEntityCreator target in targets) { - AutoEntityCreator creator = (AutoEntityCreator)tr; - creator.Autoset_Editor(); - EditorUtility.SetDirty(creator); + target.AutosetCascade_Editor(); + } + } + + if (EcsGUI.AutosetButton(autosetRect)) + { + foreach (AutoEntityCreator target in targets) + { + target.Autoset_Editor(); } } } diff --git a/src/Connectors/Editor/EcsEntityConnectEditor.cs b/src/Connectors/Editor/EcsEntityConnectEditor.cs index cfe896b..e103e54 100644 --- a/src/Connectors/Editor/EcsEntityConnectEditor.cs +++ b/src/Connectors/Editor/EcsEntityConnectEditor.cs @@ -1,7 +1,6 @@ #if UNITY_EDITOR +using Codice.CM.Client.Differences; using DCFApixels.DragonECS.Unity.Internal; -using System.Collections.Generic; -using System.Linq; using UnityEditor; using UnityEngine; @@ -36,7 +35,7 @@ namespace DCFApixels.DragonECS.Unity.Editors DrawTemplates(); - DrawButtons(); + DrawControlButtons(targets); DrawComponents(targets); } @@ -44,27 +43,7 @@ namespace DCFApixels.DragonECS.Unity.Editors { bool isConnected = Target.Entity.TryUnpack(out int id, out short gen, out EcsWorld world); EcsGUI.EntityStatus status = IsMultipleTargets ? EcsGUI.EntityStatus.Undefined : isConnected ? EcsGUI.EntityStatus.Alive : EcsGUI.EntityStatus.NotAlive; - - float width = EditorGUIUtility.currentViewWidth; - float height = EditorGUIUtility.singleLineHeight; - Rect rect = GUILayoutUtility.GetRect(width, height + 3f); - var (left, delEntityButtonRect) = RectUtility.HorizontalSliceRight(rect, height + 3); - var (entityRect, unlinkButtonRect) = RectUtility.HorizontalSliceRight(left, height + 3); - - using (new EditorGUI.DisabledScope(status != EcsGUI.EntityStatus.Alive)) - { - if (EcsGUI.UnlinkButton(unlinkButtonRect)) - { - Target.ConnectWith(entlong.NULL); - } - if (EcsGUI.DelEntityButton(delEntityButtonRect)) - { - world.DelEntity(id); - Target.ConnectWith(entlong.NULL); - } - } - - EcsGUI.DrawEntity(entityRect, status, id, gen, world.id); + EcsGUI.Layout.EntityBar(status, id, gen, world.id); } private void DrawTemplates() @@ -82,43 +61,47 @@ namespace DCFApixels.DragonECS.Unity.Editors } } - private void Autoset(EcsEntityConnect target) + private void DrawControlButtons(EcsEntityConnect[] targets) { - var result = target.MonoTemplates.Where(o => o != null).Union(GetTemplatesFor(target.transform)); - - target.SetTemplates_Editor(result.ToArray()); - EditorUtility.SetDirty(target); - } - private IEnumerable GetTemplatesFor(Transform parent) - { - IEnumerable result = parent.GetComponents(); - for (int i = 0; i < parent.childCount; i++) + float height = EcsGUI.EntityBarHeight; + Rect rect = GUILayoutUtility.GetRect(EditorGUIUtility.currentViewWidth, height); + EditorGUI.DrawRect(rect, new Color(0f, 0f, 0f, 0.1f)); + rect = RectUtility.AddPadding(rect, 2f, 0f); + var (_, buttonRect) = RectUtility.HorizontalSliceRight(rect, height); + if (EcsGUI.AutosetCascadeButton(buttonRect)) { - var child = parent.GetChild(i); - if (child.TryGetComponent(out _)) + foreach (var target in targets) { - return Enumerable.Empty(); - } - result = result.Concat(GetTemplatesFor(child)); - } - return result; - } - - private void DrawButtons() - { - GUILayout.BeginHorizontal(); - if (GUILayout.Button("Autoset")) - { - Autoset(Target); - } - if (GUILayout.Button("Autoset Cascade")) - { - foreach (var item in Target.GetComponentsInChildren()) - { - Autoset(item); + target.AutosetCascade_Editor(); + } + } + buttonRect = RectUtility.Move(buttonRect , - height, 0); + if (EcsGUI.AutosetButton(buttonRect)) + { + foreach (var target in targets) + { + target.Autoset_Editor(); + } + } + using (new EditorGUI.DisabledScope(!Application.isPlaying)) + { + buttonRect = RectUtility.Move(buttonRect, -height, 0); + if (EcsGUI.DelEntityButton(buttonRect)) + { + foreach (var target in targets) + { + target.DeleteEntity_Editor(); + } + } + buttonRect = RectUtility.Move(buttonRect, -height, 0); + if (EcsGUI.UnlinkButton(buttonRect)) + { + foreach (var target in targets) + { + target.UnlinkEntity_Editor(); + } } } - GUILayout.EndHorizontal(); } private void DrawComponents(EcsEntityConnect[] targets) diff --git a/src/Internal/Editor/EcsGUI.cs b/src/Internal/Editor/EcsGUI.cs index fbdfcc4..e2c268a 100644 --- a/src/Internal/Editor/EcsGUI.cs +++ b/src/Internal/Editor/EcsGUI.cs @@ -30,6 +30,8 @@ namespace DCFApixels.DragonECS.Unity.Editors private static readonly Rect RemoveButtonRect = new Rect(0f, 0f, 19f, 19f); private static readonly Rect TooltipIconRect = new Rect(0f, 0f, 19f, 19f); + public static float EntityBarHeight => EditorGUIUtility.singleLineHeight + 3f; + private static bool IsShowHidden { get { return DebugMonitorPrefs.instance.IsShowHidden; } @@ -111,7 +113,7 @@ namespace DCFApixels.DragonECS.Unity.Editors // // return result; //} - public static (bool, bool) IconButton(Rect position) + public static (bool, bool) IconButtonGeneric(Rect position) { Color dc = GUI.color; GUI.color = Color.clear; //Хак чтобы сделать реакцию от курсора мыши без лага @@ -121,42 +123,46 @@ namespace DCFApixels.DragonECS.Unity.Editors var current = Event.current; return (GUI.enabled && HitTest(position, current), result); } - public static bool SingleIconButton(Rect position, Texture icon) + public static bool IconButton(Rect position, Texture icon, float iconPadding, string description) { - var (hover, click) = IconButton(position); - Color color = GUI.color; - float enableMultiplier = GUI.enabled ? 1f : 0.72f; + //var (hover, click) = IconButton(position); + //Color color = GUI.color; + //float enableMultiplier = GUI.enabled ? 1f : 0.72f; + // + //if (hover) + //{ + // if (Event.current.type == EventType.Repaint) + // { + // GUI.color = Color.white * 2.2f * enableMultiplier; + // EditorStyles.helpBox.Draw(position, hover, false, false, false); + // } + // + // Rect rect = RectUtility.AddPadding(position, -1f); + // GUI.color = Color.white * enableMultiplier; + // GUI.DrawTexture(rect, icon); + //} + //else + //{ + // if (Event.current.type == EventType.Repaint) + // { + // GUI.color = Color.white * 1.7f * enableMultiplier; + // EditorStyles.helpBox.Draw(position, hover, false, false, false); + // } + // GUI.color = Color.white * enableMultiplier; + // GUI.DrawTexture(position, icon); + //} + //GUI.color = color; + //return click; - if (hover) - { - if (Event.current.type == EventType.Repaint) - { - GUI.color = Color.white * 2.2f * enableMultiplier; - EditorStyles.helpBox.Draw(position, hover, false, false, false); - } - - Rect rect = RectUtility.AddPadding(position, -1f); - GUI.color = Color.white * enableMultiplier; - GUI.DrawTexture(rect, icon); - } - else - { - if (Event.current.type == EventType.Repaint) - { - GUI.color = Color.white * 1.7f * enableMultiplier; - EditorStyles.helpBox.Draw(position, hover, false, false, false); - } - GUI.color = Color.white * enableMultiplier; - GUI.DrawTexture(position, icon); - } - GUI.color = color; - return click; + bool result = GUI.Button(position, UnityEditorUtility.GetLabel(string.Empty)); + GUI.Label(RectUtility.AddPadding(position, iconPadding), UnityEditorUtility.GetLabel(icon, description)); + return result; } public static void DescriptionIcon(Rect position, string description) { using (new ColorScope(new Color(1f, 1f, 1f, 0.8f))) { - GUIContent descriptionLabel = UnityEditorUtility.GetLabel(EditorGUIUtility.IconContent("d__Help@2x").image, description); + GUIContent descriptionLabel = UnityEditorUtility.GetLabel(EditorGUIUtility.IconContent("d__Help").image, description); GUI.Label(position, descriptionLabel, EditorStyles.boldLabel); } } @@ -164,7 +170,7 @@ namespace DCFApixels.DragonECS.Unity.Editors { using (new ColorScope(new Color(1f, 1f, 1f, 0.8f))) { - var (hover, click) = IconButton(position); + var (hover, click) = IconButtonGeneric(position); if (hover) { Rect rect = RectUtility.AddPadding(position, -4f); @@ -172,20 +178,30 @@ namespace DCFApixels.DragonECS.Unity.Editors } else { - GUI.DrawTexture(position, EditorGUIUtility.IconContent("d_winbtn_win_close@2x").image); + GUI.DrawTexture(position, EditorGUIUtility.IconContent("d_winbtn_win_close").image); } return click; } } + public static bool AutosetCascadeButton(Rect position) + { + return IconButton(position, EditorGUIUtility.IconContent("d_winbtn_win_max@2x").image, 1f, "Autoset Cascade"); + } + public static bool AutosetButton(Rect position) + { + return IconButton(position, EditorGUIUtility.IconContent("d_winbtn_win_restore@2x").image, 1f, "Autoset"); + } public static bool UnlinkButton(Rect position) { - return SingleIconButton(position, EditorGUIUtility.IconContent("d_Unlinked@2x").image); + bool result = GUI.Button(position, UnityEditorUtility.GetLabel(string.Empty)); + GUI.Label(RectUtility.Move(position, 0, -1f), UnityEditorUtility.GetLabel(EditorGUIUtility.IconContent("d_Unlinked").image, "Unlink Entity")); + return result; } public static bool DelEntityButton(Rect position) { - return SingleIconButton(position, EditorGUIUtility.IconContent("d_winbtn_win_close@2x").image); + return IconButton(position, EditorGUIUtility.IconContent("d_winbtn_win_close").image, 0f, "Delete Entity"); } - public static void DrawEntity(Rect position, EntityStatus status, int id, short gen, short world) + public static void EntityBar(Rect position, EntityStatus status, int id, short gen, short world) { var (entityInfoRect, statusRect) = RectUtility.VerticalSliceBottom(position, 3f); @@ -258,11 +274,11 @@ namespace DCFApixels.DragonECS.Unity.Editors public static class Layout { - public static void DrawEntity(EntityStatus status, int id, short gen, short world) + public static void EntityBar(EntityStatus status, int id, short gen, short world) { float width = EditorGUIUtility.currentViewWidth; - float height = EditorGUIUtility.singleLineHeight; - EcsGUI.DrawEntity(GUILayoutUtility.GetRect(width, height + 3f), status, id, gen, world); + float height = EntityBarHeight; + EcsGUI.EntityBar(GUILayoutUtility.GetRect(width, height), status, id, gen, world); } public static bool AddComponentButtons() { diff --git a/src/Internal/Utils/RectUtility.cs b/src/Internal/Utils/RectUtility.cs index 53fe4dd..e341fbf 100644 --- a/src/Internal/Utils/RectUtility.cs +++ b/src/Internal/Utils/RectUtility.cs @@ -50,9 +50,9 @@ namespace DCFApixels.DragonECS.Unity.Internal { return AddPadding(rect, verticalHorizontal, verticalHorizontal, verticalHorizontal, verticalHorizontal); } - public static Rect AddPadding(Rect rect, float vertical, float horizontal) + public static Rect AddPadding(Rect rect, float horizontal, float vertical) { - return AddPadding(rect, vertical, vertical, horizontal, horizontal); + return AddPadding(rect, horizontal, horizontal, vertical, vertical); } public static Rect AddPadding(Rect rect, float left, float right, float top, float bottom) { @@ -62,5 +62,14 @@ namespace DCFApixels.DragonECS.Unity.Internal rect.yMax -= bottom; return rect; } + public static Rect Move(Rect rect, Vector2 addVector) + { + rect.center += addVector; + return rect; + } + public static Rect Move(Rect rect, float addX, float addY) + { + return Move(rect, new Vector2(addX, addY)); + } } } From ea192221348fd6b7d7a4a4ffcf3cac2c590bef1e Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Sat, 9 Mar 2024 23:09:14 +0800 Subject: [PATCH 36/50] update --- src/Connectors/EcsEntityConnect.cs | 1 - .../Editor/AutoEntityCreatorEditor.cs | 2 +- .../Editor/EcsEntityConnectEditor.cs | 5 ++-- .../Editor/EcsWorldProviderBaseEditor.cs | 2 +- .../SOWrappers/UnityObjEditorWrapper.cs | 29 ------------------- .../SOWrappers/UnityObjEditorWrapper.cs.meta | 11 ------- 6 files changed, 4 insertions(+), 46 deletions(-) delete mode 100644 src/Internal/Editor/SOWrappers/UnityObjEditorWrapper.cs delete mode 100644 src/Internal/Editor/SOWrappers/UnityObjEditorWrapper.cs.meta diff --git a/src/Connectors/EcsEntityConnect.cs b/src/Connectors/EcsEntityConnect.cs index 073c5f4..895b867 100644 --- a/src/Connectors/EcsEntityConnect.cs +++ b/src/Connectors/EcsEntityConnect.cs @@ -3,7 +3,6 @@ using System.Linq; using System.Runtime.CompilerServices; using UnityEditor; using UnityEngine; -using static UnityEngine.GraphicsBuffer; namespace DCFApixels.DragonECS { diff --git a/src/Connectors/Editor/AutoEntityCreatorEditor.cs b/src/Connectors/Editor/AutoEntityCreatorEditor.cs index 91d27d8..402618d 100644 --- a/src/Connectors/Editor/AutoEntityCreatorEditor.cs +++ b/src/Connectors/Editor/AutoEntityCreatorEditor.cs @@ -7,7 +7,7 @@ namespace DCFApixels.DragonECS.Unity.Editors { [CustomEditor(typeof(AutoEntityCreator))] [CanEditMultipleObjects] - public class AutoEntityCreatorEditor : Editor + internal class AutoEntityCreatorEditor : Editor { private AutoEntityCreator Target => (AutoEntityCreator)target; diff --git a/src/Connectors/Editor/EcsEntityConnectEditor.cs b/src/Connectors/Editor/EcsEntityConnectEditor.cs index e103e54..ae099a9 100644 --- a/src/Connectors/Editor/EcsEntityConnectEditor.cs +++ b/src/Connectors/Editor/EcsEntityConnectEditor.cs @@ -1,5 +1,4 @@ #if UNITY_EDITOR -using Codice.CM.Client.Differences; using DCFApixels.DragonECS.Unity.Internal; using UnityEditor; using UnityEngine; @@ -8,7 +7,7 @@ namespace DCFApixels.DragonECS.Unity.Editors { [CustomEditor(typeof(EcsEntityConnect))] [CanEditMultipleObjects] - public class EcsEntityConnectEditor : Editor + internal class EcsEntityConnectEditor : Editor { private bool _isInit = false; private EcsEntityConnect Target => (EcsEntityConnect)target; @@ -75,7 +74,7 @@ namespace DCFApixels.DragonECS.Unity.Editors target.AutosetCascade_Editor(); } } - buttonRect = RectUtility.Move(buttonRect , - height, 0); + buttonRect = RectUtility.Move(buttonRect, -height, 0); if (EcsGUI.AutosetButton(buttonRect)) { foreach (var target in targets) diff --git a/src/Connectors/Editor/EcsWorldProviderBaseEditor.cs b/src/Connectors/Editor/EcsWorldProviderBaseEditor.cs index aba9bfe..4e53ce5 100644 --- a/src/Connectors/Editor/EcsWorldProviderBaseEditor.cs +++ b/src/Connectors/Editor/EcsWorldProviderBaseEditor.cs @@ -6,7 +6,7 @@ namespace DCFApixels.DragonECS.Unity.Editors { [CustomEditor(typeof(EcsWorldProviderBase), true)] [CanEditMultipleObjects] - public class EcsWorldProviderBaseEditor : Editor + internal class EcsWorldProviderBaseEditor : Editor { private EcsWorldProviderBase Target => (EcsWorldProviderBase)target; diff --git a/src/Internal/Editor/SOWrappers/UnityObjEditorWrapper.cs b/src/Internal/Editor/SOWrappers/UnityObjEditorWrapper.cs deleted file mode 100644 index fdb96d6..0000000 --- a/src/Internal/Editor/SOWrappers/UnityObjEditorWrapper.cs +++ /dev/null @@ -1,29 +0,0 @@ -#if UNITY_EDITOR -using System; -using System.Runtime.CompilerServices; -using UnityEngine; - -namespace DCFApixels.DragonECS.Unity.Editors -{ - [Serializable] - internal class UnityObjEditorWrapper : WrapperBase - { - [SerializeField] - public UnityEngine.Object data; - - public override object Data - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get { return data; } - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static UnityObjEditorWrapper Take(UnityEngine.Object data) - { - var result = Take(); - result.data = data; - result.SO.Update(); - return result; - } - } -} -#endif diff --git a/src/Internal/Editor/SOWrappers/UnityObjEditorWrapper.cs.meta b/src/Internal/Editor/SOWrappers/UnityObjEditorWrapper.cs.meta deleted file mode 100644 index 8960b1f..0000000 --- a/src/Internal/Editor/SOWrappers/UnityObjEditorWrapper.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 7060bf63683c82a4a8a6cf54255c4139 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: From 7f2d1cee737acb78e96bd3f83eb6611934df01bf Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Sat, 9 Mar 2024 23:28:43 +0800 Subject: [PATCH 37/50] fix --- src/Internal/Editor/EcsGUI.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Internal/Editor/EcsGUI.cs b/src/Internal/Editor/EcsGUI.cs index e2c268a..a6a4a0c 100644 --- a/src/Internal/Editor/EcsGUI.cs +++ b/src/Internal/Editor/EcsGUI.cs @@ -185,11 +185,11 @@ namespace DCFApixels.DragonECS.Unity.Editors } public static bool AutosetCascadeButton(Rect position) { - return IconButton(position, EditorGUIUtility.IconContent("d_winbtn_win_max@2x").image, 1f, "Autoset Cascade"); + return IconButton(position, EditorGUIUtility.IconContent("d_winbtn_win_restore@2x").image, 0f, "Autoset Cascade"); } public static bool AutosetButton(Rect position) { - return IconButton(position, EditorGUIUtility.IconContent("d_winbtn_win_restore@2x").image, 1f, "Autoset"); + return IconButton(position, EditorGUIUtility.IconContent("d_winbtn_win_max@2x").image, 1f, "Autoset"); } public static bool UnlinkButton(Rect position) { From 69e2c926e8f1a8822f45843b11f94c560e04ebb3 Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Sun, 10 Mar 2024 04:56:29 +0800 Subject: [PATCH 38/50] update runtime monitors --- src/Connectors/EcsWorldProvider.cs | 5 + .../Editor/EcsWorldProviderBaseEditor.cs | 3 + src/Debug/DebugModule.cs | 20 +++- src/Debug/Monitors/Editor.meta | 8 ++ .../Monitors/Editor/EntityMonitorEditor.cs | 20 ++++ .../Editor/EntityMonitorEditor.cs.meta | 11 ++ .../Monitors/Editor/WorldMonitorEditor.cs | 18 +++ .../Editor/WorldMonitorEditor.cs.meta | 11 ++ src/Debug/Monitors/EntityMonitor.cs | 26 ++--- src/Debug/Monitors/PipelineMonitor.cs | 41 ++++++- src/Debug/Monitors/WorldMonitor.cs | 107 +++++++++++++++++- src/Internal/Editor/EcsGUI.cs | 29 +++++ src/Internal/Editor/UnityEditorUtility.cs | 37 ++++++ 13 files changed, 304 insertions(+), 32 deletions(-) create mode 100644 src/Debug/Monitors/Editor.meta create mode 100644 src/Debug/Monitors/Editor/EntityMonitorEditor.cs create mode 100644 src/Debug/Monitors/Editor/EntityMonitorEditor.cs.meta create mode 100644 src/Debug/Monitors/Editor/WorldMonitorEditor.cs create mode 100644 src/Debug/Monitors/Editor/WorldMonitorEditor.cs.meta diff --git a/src/Connectors/EcsWorldProvider.cs b/src/Connectors/EcsWorldProvider.cs index 1f044fa..21145d2 100644 --- a/src/Connectors/EcsWorldProvider.cs +++ b/src/Connectors/EcsWorldProvider.cs @@ -12,6 +12,7 @@ namespace DCFApixels.DragonECS public abstract bool IsEmpty { get; } public abstract void SetRaw(EcsWorld world); public abstract EcsWorld GetRaw(); + public abstract EcsWorld GetCurrentWorldRaw(); } [Serializable] public abstract class EcsWorldProvider : EcsWorldProviderBase where TWorld : EcsWorld @@ -78,6 +79,10 @@ namespace DCFApixels.DragonECS { return Get(); } + public sealed override EcsWorld GetCurrentWorldRaw() + { + return _world; + } public TWorld Get() { if (_world == null || _world.IsDestroyed) diff --git a/src/Connectors/Editor/EcsWorldProviderBaseEditor.cs b/src/Connectors/Editor/EcsWorldProviderBaseEditor.cs index 4e53ce5..93cee9f 100644 --- a/src/Connectors/Editor/EcsWorldProviderBaseEditor.cs +++ b/src/Connectors/Editor/EcsWorldProviderBaseEditor.cs @@ -23,6 +23,9 @@ namespace DCFApixels.DragonECS.Unity.Editors EcsWorld world = Target.GetRaw(); GUILayout.Box($"{world.GetMeta().Name} ( {world.id} )", style, GUILayout.ExpandWidth(true)); } + EcsGUI.Layout.DrawWorldBaseInfo(Target.GetCurrentWorldRaw()); + + base.OnInspectorGUI(); GUILayout.Space(10); diff --git a/src/Debug/DebugModule.cs b/src/Debug/DebugModule.cs index 9be3304..c0bdec7 100644 --- a/src/Debug/DebugModule.cs +++ b/src/Debug/DebugModule.cs @@ -1,23 +1,33 @@ -namespace DCFApixels.DragonECS +using DCFApixels.DragonECS.Unity.Internal; + +namespace DCFApixels.DragonECS { public sealed class DebugModule : IEcsModule { public const string DEBUG_LAYER = nameof(DEBUG_LAYER); public EcsWorld[] _worlds; - public DebugModule(params EcsWorld[] worlds) { _worlds = worlds; } - void IEcsModule.Import(EcsPipeline.Builder b) { + UnityDebugService.Activate(); b.Layers.Insert(EcsConsts.POST_END_LAYER, DEBUG_LAYER); - //b.Add(new PipelineDebugSystem(), DEBUG_LAYER); + b.Add(new PipelineMonitorSystem(), DEBUG_LAYER); foreach (var world in _worlds) { - //b.Add(new WorldDebugSystem(world), DEBUG_LAYER); + b.Add(new WorldMonitorSystem(world), DEBUG_LAYER); } } } + + public static class DebugModuleExt + { + public static EcsPipeline.Builder AddUnityDebug(this EcsPipeline.Builder self, params EcsWorld[] worlds) + { + self.AddModule(new DebugModule(worlds)); + return self; + } + } } diff --git a/src/Debug/Monitors/Editor.meta b/src/Debug/Monitors/Editor.meta new file mode 100644 index 0000000..bcd0c58 --- /dev/null +++ b/src/Debug/Monitors/Editor.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b1105324b07e39d449acceb24bdd7eb3 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/Debug/Monitors/Editor/EntityMonitorEditor.cs b/src/Debug/Monitors/Editor/EntityMonitorEditor.cs new file mode 100644 index 0000000..9bbbeba --- /dev/null +++ b/src/Debug/Monitors/Editor/EntityMonitorEditor.cs @@ -0,0 +1,20 @@ +#if UNITY_EDITOR +using DCFApixels.DragonECS.Unity.Internal; +using UnityEditor; + +namespace DCFApixels.DragonECS.Unity.Editors +{ + [CustomEditor(typeof(EntityMonitor))] + internal class EntityMonitorEditor : Editor + { + private EntityMonitor Target => (EntityMonitor)target; + + public override void OnInspectorGUI() + { + bool isAlive = Target.Entity.TryUnpack(out int id, out short gen, out EcsWorld world); + EcsGUI.Layout.EntityBar(isAlive ? EcsGUI.EntityStatus.Alive : EcsGUI.EntityStatus.NotAlive, id, gen, world.id); + EcsGUI.Layout.DrawRuntimeComponents(Target.Entity, false); + } + } +} +#endif \ No newline at end of file diff --git a/src/Debug/Monitors/Editor/EntityMonitorEditor.cs.meta b/src/Debug/Monitors/Editor/EntityMonitorEditor.cs.meta new file mode 100644 index 0000000..89a9d88 --- /dev/null +++ b/src/Debug/Monitors/Editor/EntityMonitorEditor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c5457dbe0f53566419d37e0ee9d9c13f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/Debug/Monitors/Editor/WorldMonitorEditor.cs b/src/Debug/Monitors/Editor/WorldMonitorEditor.cs new file mode 100644 index 0000000..7470fec --- /dev/null +++ b/src/Debug/Monitors/Editor/WorldMonitorEditor.cs @@ -0,0 +1,18 @@ +#if UNITY_EDITOR +using DCFApixels.DragonECS.Unity.Internal; +using UnityEditor; + +namespace DCFApixels.DragonECS.Unity.Editors +{ + [CustomEditor(typeof(WorldMonitor))] + internal class WorldMonitorEditor : Editor + { + private WorldMonitor Target => (WorldMonitor)target; + + public override void OnInspectorGUI() + { + EcsGUI.Layout.DrawWorldBaseInfo(Target.World); + } + } +} +#endif \ No newline at end of file diff --git a/src/Debug/Monitors/Editor/WorldMonitorEditor.cs.meta b/src/Debug/Monitors/Editor/WorldMonitorEditor.cs.meta new file mode 100644 index 0000000..84872b2 --- /dev/null +++ b/src/Debug/Monitors/Editor/WorldMonitorEditor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7aadf8c836c97694186e4b3aeb01fcce +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/Debug/Monitors/EntityMonitor.cs b/src/Debug/Monitors/EntityMonitor.cs index 905a720..40ac57a 100644 --- a/src/Debug/Monitors/EntityMonitor.cs +++ b/src/Debug/Monitors/EntityMonitor.cs @@ -1,31 +1,19 @@ using UnityEngine; -namespace DCFApixels.DragonECS +namespace DCFApixels.DragonECS.Unity.Internal { - [MetaTags(MetaTags.HIDDEN), MetaColor(MetaColor.Gray)] - public class EntityMonitor : MonoBehaviour, IEcsProcess + [MetaTags(MetaTags.HIDDEN)] + [MetaColor(MetaColor.Gray)] + public class EntityMonitor : MonoBehaviour { private entlong _entity; - private int _entityID; - private short _gen; - private EcsWorld _world; - - public EcsWorld World + public entlong Entity { - get { return _world; } + get { return _entity; } } - public int EntityID - { - get { return _entityID; } - } - - public EntityMonitor(entlong entity) + public void Set(entlong entity) { _entity = entity; - if (_entity.TryUnpack(out _entityID, out _gen, out _world)) - { - - } } } } diff --git a/src/Debug/Monitors/PipelineMonitor.cs b/src/Debug/Monitors/PipelineMonitor.cs index 66e102d..c2f1c5d 100644 --- a/src/Debug/Monitors/PipelineMonitor.cs +++ b/src/Debug/Monitors/PipelineMonitor.cs @@ -1,9 +1,42 @@ -using UnityEngine; +using DCFApixels.DragonECS.Unity.Editors; +using UnityEngine; -namespace DCFApixels.DragonECS +namespace DCFApixels.DragonECS.Unity.Internal { - [MetaTags(MetaTags.HIDDEN), MetaColor(MetaColor.Gray)] - public class PipelineMonitor : MonoBehaviour, IEcsProcess + [MetaTags(MetaTags.HIDDEN)] + [MetaColor(MetaColor.Gray)] + public class PipelineMonitor : MonoBehaviour { + private EcsPipeline _pipeline; + public EcsPipeline Pipeline + { + get { return _pipeline; } + } + public void Set(EcsPipeline pipeline) + { + _pipeline = pipeline; + } + } + + [MetaTags(MetaTags.HIDDEN)] + [MetaColor(MetaColor.Gray)] + public class PipelineMonitorSystem : IEcsInit, IEcsPipelineMember, IEcsDestroy + { + private PipelineMonitor _monitor; + public EcsPipeline Pipeline { get; set; } + + public void Init() + { + TypeMeta meta = typeof(EcsPipeline).ToMeta(); + _monitor = new GameObject($"{UnityEditorUtility.TransformToUpperName(meta.Name)}").AddComponent(); + UnityEngine.Object.DontDestroyOnLoad(_monitor); + _monitor.Set(Pipeline); + _monitor.gameObject.SetActive(false); + } + + public void Destroy() + { + UnityEngine.Object.Destroy(_monitor); + } } } diff --git a/src/Debug/Monitors/WorldMonitor.cs b/src/Debug/Monitors/WorldMonitor.cs index 1db0c00..5236296 100644 --- a/src/Debug/Monitors/WorldMonitor.cs +++ b/src/Debug/Monitors/WorldMonitor.cs @@ -1,9 +1,108 @@ -using UnityEngine; +using DCFApixels.DragonECS.Unity.Editors; +using System; +using UnityEngine; -namespace DCFApixels.DragonECS +namespace DCFApixels.DragonECS.Unity.Internal { - [MetaTags(MetaTags.HIDDEN), MetaColor(MetaColor.Gray)] - public class WorldMonitor : MonoBehaviour, IEcsProcess + [MetaTags(MetaTags.HIDDEN)] + [MetaColor(MetaColor.Gray)] + public class WorldMonitor : MonoBehaviour { + private EcsWorld _world; + public EcsWorld World + { + get { return _world; } + } + public void Set(EcsWorld world) + { + _world = world; + } + } + + [MetaTags(MetaTags.HIDDEN)] + [MetaColor(MetaColor.Gray)] + public class WorldMonitorSystem : IEcsInit, IEcsWorldEventListener, IEcsEntityEventListener + { + private EcsWorld _world; + private WorldMonitor _monitor; + private Transform _entityMonitorsPoolRoot; + private EntityMonitor[] _entityMonitors; + public EcsWorld World + { + get { return _world; } + } + public WorldMonitorSystem(EcsWorld world) + { + _world = world; + _entityMonitors = new EntityMonitor[_world.Capacity]; + + _world.AddListener(entityEventListener: this); + _world.AddListener(worldEventListener: this); + } + public void Init() + { + TypeMeta meta = _world.GetMeta(); + _monitor = new GameObject($"{UnityEditorUtility.TransformToUpperName(meta.Name)} ( {_world.id} )").AddComponent(); + UnityEngine.Object.DontDestroyOnLoad(_monitor); + _monitor.Set(_world); + _monitor.gameObject.SetActive(false); + + _entityMonitorsPoolRoot = new GameObject("__POOL").transform; + _entityMonitorsPoolRoot.SetParent(_monitor.transform); + + foreach (var e in _world.Entities) + { + InitNewEntity(e, false); + } + } + + void IEcsWorldEventListener.OnWorldResize(int newSize) + { + Array.Resize(ref _entityMonitors, newSize); + } + void IEcsWorldEventListener.OnReleaseDelEntityBuffer(ReadOnlySpan buffer) { } + void IEcsWorldEventListener.OnWorldDestroy() + { + UnityEngine.Object.Destroy(_monitor); + UnityEngine.Object.Destroy(_entityMonitorsPoolRoot); + _monitor = null; + _entityMonitorsPoolRoot = null; + } + + void IEcsEntityEventListener.OnNewEntity(int entityID) + { + InitNewEntity(entityID, true); + } + + private void InitNewEntity(int entityID, bool check) + { + if(_monitor == null) { return; } + ref var _entityMonitorRef = ref _entityMonitors[entityID]; + if (_entityMonitorRef == null) + { + _entityMonitorRef = new GameObject($"ENTITY ( {entityID} )").AddComponent(); + } + if (check && _entityMonitorRef.Entity.IsAlive) + { + throw new Exception(); + } + _entityMonitorRef.Set(_world.GetEntityLong(entityID)); + _entityMonitorRef.transform.SetParent(_monitor.transform); + } + + void IEcsEntityEventListener.OnDelEntity(int entityID) + { + if(_monitor == null) { return; } + ref var _entityMonitorRef = ref _entityMonitors[entityID]; + if (_entityMonitorRef != null) + { + if (_entityMonitorRef.Entity.IsAlive) + { + throw new Exception(); + } + _entityMonitorRef.transform.SetParent(_entityMonitorsPoolRoot.transform); + _entityMonitorRef.Set(_world.GetEntityLong(entityID)); + } + } } } diff --git a/src/Internal/Editor/EcsGUI.cs b/src/Internal/Editor/EcsGUI.cs index a6a4a0c..9c1b9d1 100644 --- a/src/Internal/Editor/EcsGUI.cs +++ b/src/Internal/Editor/EcsGUI.cs @@ -1,4 +1,5 @@ #if UNITY_EDITOR +using Codice.Client.Common.GameUI; using DCFApixels.DragonECS.Unity.Internal; using System; using System.Reflection; @@ -23,6 +24,20 @@ namespace DCFApixels.DragonECS.Unity.Editors } } + public struct ContentColorScope : IDisposable + { + private readonly Color _oldColor; + public ContentColorScope(Color color) + { + _oldColor = GUI.contentColor; + GUI.contentColor = color; + } + public void Dispose() + { + GUI.contentColor = _oldColor; + } + } + internal readonly static Color GrayColor = new Color32(100, 100, 100, 255); internal readonly static Color GreenColor = new Color32(75, 255, 0, 255); internal readonly static Color RedColor = new Color32(255, 0, 75, 255); @@ -274,6 +289,20 @@ namespace DCFApixels.DragonECS.Unity.Editors public static class Layout { + public static void DrawWorldBaseInfo(EcsWorld world) + { + bool isNull = world == null || world.id == 0; + int entitesCount = isNull ? 0 : world.Count; + int capacity = isNull ? 0 : world.Capacity; + int leakedEntitesCount = isNull ? 0 : world.CountLeakedEntitesDebug(); + EditorGUILayout.IntField("Entities", entitesCount, EditorStyles.boldLabel); + EditorGUILayout.IntField("Capacity", capacity, EditorStyles.boldLabel); + Color color = leakedEntitesCount > 0 ? Color.yellow : GUI.contentColor; + using (new ContentColorScope(color)) + { + EditorGUILayout.IntField("Leaked Entites", leakedEntitesCount, EditorStyles.boldLabel); + } + } public static void EntityBar(EntityStatus status, int id, short gen, short world) { float width = EditorGUIUtility.currentViewWidth; diff --git a/src/Internal/Editor/UnityEditorUtility.cs b/src/Internal/Editor/UnityEditorUtility.cs index 2be801c..9a9f2f9 100644 --- a/src/Internal/Editor/UnityEditorUtility.cs +++ b/src/Internal/Editor/UnityEditorUtility.cs @@ -20,6 +20,43 @@ namespace DCFApixels.DragonECS.Unity.Editors private static GUIContent _singletonContent = null; #region TransformFieldName + public static string TransformToUpperName(string name) + { + if (name.Length <= 0) + { + return name; + } + StringBuilder b = new StringBuilder(); + bool nextWorld = true; + bool prewIsUpper = false; + + + for (int i = 0; i < name.Length; i++) + { + char c = name[i]; + if (char.IsLetter(c) == false) + { + nextWorld = true; + prewIsUpper = false; + continue; + } + + bool isUpper = char.IsUpper(c); + if (isUpper) + { + if (nextWorld == false && prewIsUpper == false) + { + b.Append('_'); + } + } + b.Append(char.ToUpper(c)); + nextWorld = false; + prewIsUpper = isUpper; + } + + return b.ToString(); + } + public static string TransformFieldName(string name) { if (name.Length <= 0) From 7b1cad6e2b864691d85da48e94b424fe21f884ef Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Sun, 10 Mar 2024 06:19:20 +0800 Subject: [PATCH 39/50] add pipeline monitor --- .../Monitors/Editor/PipelineMonitorEditor.cs | 152 ++++++++++++++ .../Editor/PipelineMonitorEditor.cs.meta | 11 ++ .../Editor/PipelineProcessesMonitorEditor.cs | 185 ++++++++++++++++++ .../PipelineProcessesMonitorEditor.cs.meta | 11 ++ src/Debug/Monitors/EntityMonitor.cs | 2 +- src/Debug/Monitors/PipelineMonitor.cs | 10 +- src/Debug/Monitors/PipelineProcessMonitor.cs | 19 ++ .../Monitors/PipelineProcessMonitor.cs.meta | 11 ++ src/Debug/Monitors/WorldMonitor.cs | 8 +- src/Internal/Editor/EcsGUI.cs | 1 - 10 files changed, 402 insertions(+), 8 deletions(-) create mode 100644 src/Debug/Monitors/Editor/PipelineMonitorEditor.cs create mode 100644 src/Debug/Monitors/Editor/PipelineMonitorEditor.cs.meta create mode 100644 src/Debug/Monitors/Editor/PipelineProcessesMonitorEditor.cs create mode 100644 src/Debug/Monitors/Editor/PipelineProcessesMonitorEditor.cs.meta create mode 100644 src/Debug/Monitors/PipelineProcessMonitor.cs create mode 100644 src/Debug/Monitors/PipelineProcessMonitor.cs.meta diff --git a/src/Debug/Monitors/Editor/PipelineMonitorEditor.cs b/src/Debug/Monitors/Editor/PipelineMonitorEditor.cs new file mode 100644 index 0000000..ccc2bcc --- /dev/null +++ b/src/Debug/Monitors/Editor/PipelineMonitorEditor.cs @@ -0,0 +1,152 @@ +#if UNITY_EDITOR +using DCFApixels.DragonECS.RunnersCore; +using DCFApixels.DragonECS.Unity.Internal; +using System; +using System.Linq; +using UnityEditor; +using UnityEngine; + +namespace DCFApixels.DragonECS.Unity.Editors +{ + [CustomEditor(typeof(PipelineMonitor))] + internal class PipelineMonitorEditor : Editor + { + private MetaColorAttribute _fakeDebugColorAttribute = new MetaColorAttribute(190, 190, 190); + private Type _debugColorAttributeType = typeof(MetaColorAttribute); + private GUIStyle _headerStyle; + private GUIStyle _interfacesStyle; + private Color _interfaceColor = new Color(0.96f, 1f, 0.16f); + + private GUIStyle systemsListStyle; + + private PipelineMonitor Target => (PipelineMonitor)target; + private bool IsShowInterfaces + { + get { return DebugMonitorPrefs.instance.IsShowInterfaces; } + set { DebugMonitorPrefs.instance.IsShowInterfaces = value; } + } + private bool IsShowHidden + { + get { return DebugMonitorPrefs.instance.IsShowHidden; } + set { DebugMonitorPrefs.instance.IsShowHidden = value; } + } + + public override void OnInspectorGUI() + { + systemsListStyle = new GUIStyle(EditorStyles.miniLabel); + systemsListStyle.wordWrap = true; + + if (Target.Pipeline == null || Target.Pipeline.IsDestoryed) + { + return; + } + if (_headerStyle == null) + { + _headerStyle = new GUIStyle(EditorStyles.boldLabel); + _interfacesStyle = new GUIStyle(EditorStyles.miniLabel); + _interfacesStyle.hover.textColor = _interfaceColor; + _interfacesStyle.focused.textColor = _interfaceColor; + _interfacesStyle.active.textColor = _interfaceColor; + _interfacesStyle.normal.textColor = _interfaceColor; + _interfacesStyle.wordWrap = true; + _headerStyle.fontSize = 28; + } + + GUILayout.Label("[Systems]", _headerStyle); + + IsShowInterfaces = EditorGUILayout.Toggle("Show Interfaces", IsShowInterfaces); + IsShowHidden = EditorGUILayout.Toggle("Show Hidden", IsShowHidden); + + GUILayout.BeginVertical(); + foreach (var item in Target.Pipeline.AllSystems) + { + DrawSystem(item); + } + GUILayout.EndVertical(); + + + GUILayout.Label("[Runners]", _headerStyle); + + GUILayout.BeginVertical(UnityEditorUtility.GetStyle(Color.black, 0.2f)); + foreach (var item in Target.Pipeline.AllRunners) + { + if (item.Key.IsInterface == false) + { + DrawRunner(item.Value); + } + } + GUILayout.EndVertical(); + } + + private void DrawSystem(IEcsProcess system) + { + if (system is SystemsLayerMarkerSystem markerSystem) + { + GUILayout.EndVertical(); + GUILayout.BeginVertical(UnityEditorUtility.GetStyle(Color.black, 0.2f)); + + GUILayout.BeginHorizontal(); + GUILayout.Label("<"); + GUILayout.Label($"{markerSystem.name}", EditorStyles.boldLabel); + GUILayout.Label(">", GUILayout.ExpandWidth(false)); + GUILayout.EndHorizontal(); + return; + } + + Type type = system.GetType(); + TypeMeta meta = type.ToMeta(); + + if (CheckIsHidden(meta)) + { + return; + } + + string name = meta.Name; + Color color = meta.Color.ToUnityColor(); + + GUILayout.BeginVertical(UnityEditorUtility.GetStyle(color, 0.2f)); + if (IsShowInterfaces) + { + GUILayout.Label(string.Join(", ", type.GetInterfaces().Select(o => o.Name)), _interfacesStyle); + } + GUILayout.Label(name, EditorStyles.boldLabel); + GUILayout.EndVertical(); + } + + private void DrawRunner(IEcsRunner runner) + { + Type type = runner.GetType(); + TypeMeta meta = type.ToMeta(); + + if (CheckIsHidden(meta)) + { + return; + } + + //Color color = (GetAttribute(type) ?? _fakeDebugColorAttribute).GetUnityColor(); + Color color = meta.Color.ToUnityColor(); + + GUILayout.BeginVertical(UnityEditorUtility.GetStyle(color, 0.2f)); + GUILayout.Label(meta.Name, EditorStyles.boldLabel); + GUILayout.Label(string.Join(", ", runner.ProcessRaw.Cast().Select(o => o.GetType().Name)), systemsListStyle); + GUILayout.EndVertical(); + } + + private TAttribute GetAttribute(Type target) where TAttribute : Attribute + { + var result = target.GetCustomAttributes(_debugColorAttributeType, false); + if (result.Length > 0) + return (TAttribute)result[0]; + return null; + } + + private bool CheckIsHidden(TypeMeta meta) + { + if (IsShowHidden) + return false; + + return meta.IsHidden; + } + } +} +#endif \ No newline at end of file diff --git a/src/Debug/Monitors/Editor/PipelineMonitorEditor.cs.meta b/src/Debug/Monitors/Editor/PipelineMonitorEditor.cs.meta new file mode 100644 index 0000000..99bc7f1 --- /dev/null +++ b/src/Debug/Monitors/Editor/PipelineMonitorEditor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 406298e83eb7a0b41b525c7e810c0c6f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/Debug/Monitors/Editor/PipelineProcessesMonitorEditor.cs b/src/Debug/Monitors/Editor/PipelineProcessesMonitorEditor.cs new file mode 100644 index 0000000..a7606aa --- /dev/null +++ b/src/Debug/Monitors/Editor/PipelineProcessesMonitorEditor.cs @@ -0,0 +1,185 @@ +#if UNITY_EDITOR +using DCFApixels.DragonECS.Unity.Internal; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using UnityEditor; +using UnityEngine; + +namespace DCFApixels.DragonECS.Unity.Editors +{ + [CustomEditor(typeof(PipelineProcessMonitor))] + internal class PipelineProcessesMonitorEditor : Editor + { + private bool _isInit = false; + private List _processesList = new List(); + private Dictionary _processeIndexes = new Dictionary(); + private Type systemInterfaceType = typeof(IEcsProcess); + private IEcsProcess[] _systems; + + private PipelineProcessMonitor Target => (PipelineProcessMonitor)target; + private bool IsShowInterfaces + { + get { return DebugMonitorPrefs.instance.IsShowInterfaces; } + set { DebugMonitorPrefs.instance.IsShowInterfaces = value; } + } + private bool IsShowHidden + { + get { return DebugMonitorPrefs.instance.IsShowHidden; } + set { DebugMonitorPrefs.instance.IsShowHidden = value; } + } + + private void Init() + { + if (_isInit) + { + return; + } + + _processesList.Clear(); + _processeIndexes.Clear(); + if (IsShowHidden) + { + _systems = Target.Pipeline.AllSystems.Where(o => o is SystemsLayerMarkerSystem == false).ToArray(); + } + else + { + _systems = Target.Pipeline.AllSystems.Where(o => o.GetMeta().IsHidden == false).ToArray(); + } + + int i = 0; + foreach (var system in _systems) + { + foreach (var interfaceType in system.GetType().GetInterfaces()) + { + TypeMeta meta = interfaceType.ToMeta(); + if (systemInterfaceType.IsAssignableFrom(interfaceType) && systemInterfaceType != interfaceType && (IsShowHidden || meta.IsHidden == false)) + { + ProcessData data; + if (!_processeIndexes.TryGetValue(interfaceType, out int index)) + { + index = _processesList.Count; + _processeIndexes.Add(interfaceType, index); + + data = new ProcessData(); + _processesList.Add(data); + + data.name = meta.Name; + data.interfaceType = interfaceType; + data.systemsBitMask = new BitMask(_systems.Length); + } + data = _processesList[index]; + data.systemsBitMask[i] = true; + } + } + i++; + } + + _isInit = true; + } + private Vector2 _position; + private Vector2 _cellsize = new Vector2(EditorGUIUtility.singleLineHeight, EditorGUIUtility.singleLineHeight); + private Vector2 _nameCellSize = new Vector2(200f, 200f); + + public override void OnInspectorGUI() + { + EditorGUI.BeginChangeCheck(); + IsShowHidden = EditorGUILayout.Toggle("Show Hidden", IsShowHidden); + if (EditorGUI.EndChangeCheck()) + { + _isInit = false; + } + + Init(); + + Rect rect; + Rect lineRect; + GUILayout.Label("", GUILayout.ExpandWidth(true), GUILayout.Height(400f)); + rect = GUILayoutUtility.GetLastRect(); + + rect.height = 400f; + + + Rect rectView = new Rect(0f, 0f, _nameCellSize.x + _cellsize.x * _processesList.Count, _nameCellSize.y + _cellsize.y * _systems.Length); + _position = GUI.BeginScrollView(rect, _position, rectView, true, true); + + List systeNames = new List(); + + var blackStyle = UnityEditorUtility.GetStyle(Color.black, 0.04f); + var whiteStyle = UnityEditorUtility.GetStyle(Color.white, 0.04f); + GUIContent label = new GUIContent(); + + + Vector2 pivod = _nameCellSize; + rect = new Rect(); + rect.y = _nameCellSize.y; + rect.width = _nameCellSize.x; + rect.height = _cellsize.x; + rect.y -= _cellsize.y; + for (int i = 0; i < _processesList.Count; i++) + { + lineRect = rect; + lineRect.y = 0f; + lineRect.x = _nameCellSize.x + _cellsize.x * i; + lineRect.width = _cellsize.x; + lineRect.height = rectView.height; + GUI.Label(lineRect, "", i % 2 == 1 ? whiteStyle : blackStyle); + + GUIUtility.RotateAroundPivot(90, pivod); + label.text = _processesList[i].name; + label.tooltip = "." + _processesList[i].name; + GUI.Label(rect, label, EditorStyles.miniBoldLabel); + GUIUtility.RotateAroundPivot(-90, pivod); + + pivod.x += _cellsize.x; + rect.x += _cellsize.x; + } + + rect = new Rect(); + rect.y = _nameCellSize.y; + rect.width = _nameCellSize.x; + rect.height = _cellsize.x; + for (int i = 0; i < _systems.Length; i++) + { + TypeMeta meta = _systems[i].GetMeta(); + string name = meta.Name; + systeNames.Add(name); + + lineRect = rect; + lineRect.width = rectView.width; + GUI.Label(lineRect, "", i % 2 == 1 ? whiteStyle : blackStyle); + + label.text = name; + label.tooltip = i + " " + name; + GUI.Label(rect, label, EditorStyles.miniBoldLabel); + rect.y += _cellsize.y; + } + + for (int x = 0; x < _processesList.Count; x++) + { + var process = _processesList[x]; + for (int y = 0; y < _systems.Length; y++) + { + string systemName = systeNames[x]; + rect = new Rect(x * _cellsize.x + _nameCellSize.x, y * _cellsize.y + _nameCellSize.y, _cellsize.x, _cellsize.y); + bool flag = process.systemsBitMask[y]; + string labeltext = flag ? "^" : " "; + label.text = labeltext; + label.tooltip = $"{process.name}-{systemName}"; + GUI.Label(rect, label); + } + } + + GUI.EndScrollView(); + } + + private class ProcessData + { + public Type interfaceType; + public string name; + public BitMask systemsBitMask; + } + } +} +#endif \ No newline at end of file diff --git a/src/Debug/Monitors/Editor/PipelineProcessesMonitorEditor.cs.meta b/src/Debug/Monitors/Editor/PipelineProcessesMonitorEditor.cs.meta new file mode 100644 index 0000000..8451072 --- /dev/null +++ b/src/Debug/Monitors/Editor/PipelineProcessesMonitorEditor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d3cd5a052acb5c4469a9802390bb532a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/Debug/Monitors/EntityMonitor.cs b/src/Debug/Monitors/EntityMonitor.cs index 40ac57a..c3f5cbc 100644 --- a/src/Debug/Monitors/EntityMonitor.cs +++ b/src/Debug/Monitors/EntityMonitor.cs @@ -4,7 +4,7 @@ namespace DCFApixels.DragonECS.Unity.Internal { [MetaTags(MetaTags.HIDDEN)] [MetaColor(MetaColor.Gray)] - public class EntityMonitor : MonoBehaviour + internal class EntityMonitor : MonoBehaviour { private entlong _entity; public entlong Entity diff --git a/src/Debug/Monitors/PipelineMonitor.cs b/src/Debug/Monitors/PipelineMonitor.cs index c2f1c5d..b5b1774 100644 --- a/src/Debug/Monitors/PipelineMonitor.cs +++ b/src/Debug/Monitors/PipelineMonitor.cs @@ -5,7 +5,7 @@ namespace DCFApixels.DragonECS.Unity.Internal { [MetaTags(MetaTags.HIDDEN)] [MetaColor(MetaColor.Gray)] - public class PipelineMonitor : MonoBehaviour + internal class PipelineMonitor : MonoBehaviour { private EcsPipeline _pipeline; public EcsPipeline Pipeline @@ -20,9 +20,10 @@ namespace DCFApixels.DragonECS.Unity.Internal [MetaTags(MetaTags.HIDDEN)] [MetaColor(MetaColor.Gray)] - public class PipelineMonitorSystem : IEcsInit, IEcsPipelineMember, IEcsDestroy + internal class PipelineMonitorSystem : IEcsInit, IEcsPipelineMember, IEcsDestroy { private PipelineMonitor _monitor; + private PipelineProcessMonitor _processesMonitor; public EcsPipeline Pipeline { get; set; } public void Init() @@ -32,6 +33,11 @@ namespace DCFApixels.DragonECS.Unity.Internal UnityEngine.Object.DontDestroyOnLoad(_monitor); _monitor.Set(Pipeline); _monitor.gameObject.SetActive(false); + + _processesMonitor = new GameObject($"PROCESS_MATRIX").AddComponent(); + _processesMonitor.transform.SetParent(_monitor.transform); + _processesMonitor.Set(Pipeline); + _processesMonitor.gameObject.SetActive(false); } public void Destroy() diff --git a/src/Debug/Monitors/PipelineProcessMonitor.cs b/src/Debug/Monitors/PipelineProcessMonitor.cs new file mode 100644 index 0000000..3401463 --- /dev/null +++ b/src/Debug/Monitors/PipelineProcessMonitor.cs @@ -0,0 +1,19 @@ +using UnityEngine; + +namespace DCFApixels.DragonECS.Unity.Editors +{ + [MetaTags(MetaTags.HIDDEN)] + [MetaColor(MetaColor.Gray)] + internal class PipelineProcessMonitor : MonoBehaviour + { + private EcsPipeline _pipeline; + public EcsPipeline Pipeline + { + get { return _pipeline; } + } + public void Set(EcsPipeline pipeline) + { + _pipeline = pipeline; + } + } +} diff --git a/src/Debug/Monitors/PipelineProcessMonitor.cs.meta b/src/Debug/Monitors/PipelineProcessMonitor.cs.meta new file mode 100644 index 0000000..628f9be --- /dev/null +++ b/src/Debug/Monitors/PipelineProcessMonitor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2e20707e619a5b742aeb26e3eff3a9c4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/Debug/Monitors/WorldMonitor.cs b/src/Debug/Monitors/WorldMonitor.cs index 5236296..0c5eca2 100644 --- a/src/Debug/Monitors/WorldMonitor.cs +++ b/src/Debug/Monitors/WorldMonitor.cs @@ -6,7 +6,7 @@ namespace DCFApixels.DragonECS.Unity.Internal { [MetaTags(MetaTags.HIDDEN)] [MetaColor(MetaColor.Gray)] - public class WorldMonitor : MonoBehaviour + internal class WorldMonitor : MonoBehaviour { private EcsWorld _world; public EcsWorld World @@ -21,7 +21,7 @@ namespace DCFApixels.DragonECS.Unity.Internal [MetaTags(MetaTags.HIDDEN)] [MetaColor(MetaColor.Gray)] - public class WorldMonitorSystem : IEcsInit, IEcsWorldEventListener, IEcsEntityEventListener + internal class WorldMonitorSystem : IEcsInit, IEcsWorldEventListener, IEcsEntityEventListener { private EcsWorld _world; private WorldMonitor _monitor; @@ -76,7 +76,7 @@ namespace DCFApixels.DragonECS.Unity.Internal private void InitNewEntity(int entityID, bool check) { - if(_monitor == null) { return; } + if (_monitor == null) { return; } ref var _entityMonitorRef = ref _entityMonitors[entityID]; if (_entityMonitorRef == null) { @@ -92,7 +92,7 @@ namespace DCFApixels.DragonECS.Unity.Internal void IEcsEntityEventListener.OnDelEntity(int entityID) { - if(_monitor == null) { return; } + if (_monitor == null) { return; } ref var _entityMonitorRef = ref _entityMonitors[entityID]; if (_entityMonitorRef != null) { diff --git a/src/Internal/Editor/EcsGUI.cs b/src/Internal/Editor/EcsGUI.cs index 9c1b9d1..fbe62af 100644 --- a/src/Internal/Editor/EcsGUI.cs +++ b/src/Internal/Editor/EcsGUI.cs @@ -1,5 +1,4 @@ #if UNITY_EDITOR -using Codice.Client.Common.GameUI; using DCFApixels.DragonECS.Unity.Internal; using System; using System.Reflection; From 3f75ec5f981d295c366a61ee5312fa17fa404a87 Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Sun, 10 Mar 2024 08:10:58 +0800 Subject: [PATCH 40/50] update style --- .../Monitors/Editor/PipelineMonitorEditor.cs | 13 -- .../Editor/PipelineProcessesMonitorEditor.cs | 137 ++++++++++-------- src/Internal/Editor/UnityEditorUtility.cs | 8 + src/Internal/Utils/ColorUtility.cs | 2 +- 4 files changed, 84 insertions(+), 76 deletions(-) diff --git a/src/Debug/Monitors/Editor/PipelineMonitorEditor.cs b/src/Debug/Monitors/Editor/PipelineMonitorEditor.cs index ccc2bcc..41819f6 100644 --- a/src/Debug/Monitors/Editor/PipelineMonitorEditor.cs +++ b/src/Debug/Monitors/Editor/PipelineMonitorEditor.cs @@ -77,7 +77,6 @@ namespace DCFApixels.DragonECS.Unity.Editors } GUILayout.EndVertical(); } - private void DrawSystem(IEcsProcess system) { if (system is SystemsLayerMarkerSystem markerSystem) @@ -112,7 +111,6 @@ namespace DCFApixels.DragonECS.Unity.Editors GUILayout.Label(name, EditorStyles.boldLabel); GUILayout.EndVertical(); } - private void DrawRunner(IEcsRunner runner) { Type type = runner.GetType(); @@ -122,8 +120,6 @@ namespace DCFApixels.DragonECS.Unity.Editors { return; } - - //Color color = (GetAttribute(type) ?? _fakeDebugColorAttribute).GetUnityColor(); Color color = meta.Color.ToUnityColor(); GUILayout.BeginVertical(UnityEditorUtility.GetStyle(color, 0.2f)); @@ -131,15 +127,6 @@ namespace DCFApixels.DragonECS.Unity.Editors GUILayout.Label(string.Join(", ", runner.ProcessRaw.Cast().Select(o => o.GetType().Name)), systemsListStyle); GUILayout.EndVertical(); } - - private TAttribute GetAttribute(Type target) where TAttribute : Attribute - { - var result = target.GetCustomAttributes(_debugColorAttributeType, false); - if (result.Length > 0) - return (TAttribute)result[0]; - return null; - } - private bool CheckIsHidden(TypeMeta meta) { if (IsShowHidden) diff --git a/src/Debug/Monitors/Editor/PipelineProcessesMonitorEditor.cs b/src/Debug/Monitors/Editor/PipelineProcessesMonitorEditor.cs index a7606aa..7c7e34a 100644 --- a/src/Debug/Monitors/Editor/PipelineProcessesMonitorEditor.cs +++ b/src/Debug/Monitors/Editor/PipelineProcessesMonitorEditor.cs @@ -12,11 +12,12 @@ namespace DCFApixels.DragonECS.Unity.Editors [CustomEditor(typeof(PipelineProcessMonitor))] internal class PipelineProcessesMonitorEditor : Editor { + private static Type SYSTEM_INTERFACE_TYPE = typeof(IEcsProcess); + private bool _isInit = false; - private List _processesList = new List(); + private List _processList = new List(); private Dictionary _processeIndexes = new Dictionary(); - private Type systemInterfaceType = typeof(IEcsProcess); - private IEcsProcess[] _systems; + private SystemData[] _systemsList; private PipelineProcessMonitor Target => (PipelineProcessMonitor)target; private bool IsShowInterfaces @@ -37,45 +38,39 @@ namespace DCFApixels.DragonECS.Unity.Editors return; } - _processesList.Clear(); + _processList.Clear(); _processeIndexes.Clear(); + IEnumerable fileretSystems = Target.Pipeline.AllSystems; if (IsShowHidden) - { - _systems = Target.Pipeline.AllSystems.Where(o => o is SystemsLayerMarkerSystem == false).ToArray(); - } + { fileretSystems = fileretSystems.Where(o => o is SystemsLayerMarkerSystem == false); } else - { - _systems = Target.Pipeline.AllSystems.Where(o => o.GetMeta().IsHidden == false).ToArray(); - } + { fileretSystems = fileretSystems.Where(o => o.GetMeta().IsHidden == false); } + _systemsList = fileretSystems.Select(o => new SystemData(o.GetMeta(), o)).ToArray(); - int i = 0; - foreach (var system in _systems) + for (int i = 0; i < _systemsList.Length; i++) { - foreach (var interfaceType in system.GetType().GetInterfaces()) + var system = _systemsList[i]; + foreach (var interfaceType in system.meta.Type.GetInterfaces()) { TypeMeta meta = interfaceType.ToMeta(); - if (systemInterfaceType.IsAssignableFrom(interfaceType) && systemInterfaceType != interfaceType && (IsShowHidden || meta.IsHidden == false)) + if (SYSTEM_INTERFACE_TYPE.IsAssignableFrom(interfaceType) && SYSTEM_INTERFACE_TYPE != interfaceType && (IsShowHidden || meta.IsHidden == false)) { ProcessData data; - if (!_processeIndexes.TryGetValue(interfaceType, out int index)) + if (_processeIndexes.TryGetValue(interfaceType, out int index) == false) { - index = _processesList.Count; + index = _processList.Count; _processeIndexes.Add(interfaceType, index); data = new ProcessData(); - _processesList.Add(data); - - data.name = meta.Name; - data.interfaceType = interfaceType; - data.systemsBitMask = new BitMask(_systems.Length); + data.interfaceMeta = meta; + data.systemsBitMask = new BitMask(_systemsList.Length); + _processList.Add(data); } - data = _processesList[index]; + data = _processList[index]; data.systemsBitMask[i] = true; } } - i++; } - _isInit = true; } private Vector2 _position; @@ -90,94 +85,112 @@ namespace DCFApixels.DragonECS.Unity.Editors { _isInit = false; } - Init(); - Rect rect; - Rect lineRect; GUILayout.Label("", GUILayout.ExpandWidth(true), GUILayout.Height(400f)); - rect = GUILayoutUtility.GetLastRect(); + Rect rect = GUILayoutUtility.GetLastRect(); rect.height = 400f; - Rect rectView = new Rect(0f, 0f, _nameCellSize.x + _cellsize.x * _processesList.Count, _nameCellSize.y + _cellsize.y * _systems.Length); + Rect rectView = new Rect(0f, 0f, _nameCellSize.x + _cellsize.x * _processList.Count, _nameCellSize.y + _cellsize.y * _systemsList.Length); + EditorGUI.DrawRect(rect, new Color(0, 0, 0, 0.6f)); _position = GUI.BeginScrollView(rect, _position, rectView, true, true); - - List systeNames = new List(); - - var blackStyle = UnityEditorUtility.GetStyle(Color.black, 0.04f); - var whiteStyle = UnityEditorUtility.GetStyle(Color.white, 0.04f); - GUIContent label = new GUIContent(); - + //var blackStyle = UnityEditorUtility.GetStyle(Color.black, 0.04f); + //var whiteStyle = UnityEditorUtility.GetStyle(Color.white, 0.04f); Vector2 pivod = _nameCellSize; - rect = new Rect(); + rect = default; rect.y = _nameCellSize.y; rect.width = _nameCellSize.x; rect.height = _cellsize.x; rect.y -= _cellsize.y; - for (int i = 0; i < _processesList.Count; i++) + //processes line + for (int i = 0; i < _processList.Count; i++) { - lineRect = rect; + TypeMeta meta = _processList[i].interfaceMeta; + Rect lineRect = rect; lineRect.y = 0f; lineRect.x = _nameCellSize.x + _cellsize.x * i; lineRect.width = _cellsize.x; lineRect.height = rectView.height; - GUI.Label(lineRect, "", i % 2 == 1 ? whiteStyle : blackStyle); + lineRect = RectUtility.AddPadding(lineRect, 1, 0); + //GUI.Label(lineRect, "", i % 2 == 1 ? whiteStyle : blackStyle); + Color color = meta.Color.ToUnityColor(); + color = NormalizeGridColor(i, color); + EditorGUI.DrawRect(lineRect, color); GUIUtility.RotateAroundPivot(90, pivod); - label.text = _processesList[i].name; - label.tooltip = "." + _processesList[i].name; - GUI.Label(rect, label, EditorStyles.miniBoldLabel); + GUI.Label(rect, UnityEditorUtility.GetLabel(meta.Name), EditorStyles.miniBoldLabel); GUIUtility.RotateAroundPivot(-90, pivod); pivod.x += _cellsize.x; rect.x += _cellsize.x; } - rect = new Rect(); + rect = default; rect.y = _nameCellSize.y; rect.width = _nameCellSize.x; rect.height = _cellsize.x; - for (int i = 0; i < _systems.Length; i++) + //systems line + for (int i = 0; i < _systemsList.Length; i++) { - TypeMeta meta = _systems[i].GetMeta(); + TypeMeta meta = _systemsList[i].meta; string name = meta.Name; - systeNames.Add(name); - lineRect = rect; + Rect lineRect = rect; lineRect.width = rectView.width; - GUI.Label(lineRect, "", i % 2 == 1 ? whiteStyle : blackStyle); + lineRect = RectUtility.AddPadding(lineRect, 0, 1); + //GUI.Label(lineRect, "", i % 2 == 1 ? whiteStyle : blackStyle); + Color color = meta.Color.ToUnityColor(); + color = NormalizeGridColor(i, color); + EditorGUI.DrawRect(lineRect, color); - label.text = name; - label.tooltip = i + " " + name; - GUI.Label(rect, label, EditorStyles.miniBoldLabel); + GUI.Label(rect, UnityEditorUtility.GetLabel(name, i + " " + name), EditorStyles.miniBoldLabel); rect.y += _cellsize.y; } - for (int x = 0; x < _processesList.Count; x++) + //matrix + for (int x = 0; x < _processList.Count; x++) { - var process = _processesList[x]; - for (int y = 0; y < _systems.Length; y++) + var process = _processList[x]; + for (int y = 0; y < _systemsList.Length; y++) { - string systemName = systeNames[x]; rect = new Rect(x * _cellsize.x + _nameCellSize.x, y * _cellsize.y + _nameCellSize.y, _cellsize.x, _cellsize.y); bool flag = process.systemsBitMask[y]; string labeltext = flag ? "^" : " "; - label.text = labeltext; - label.tooltip = $"{process.name}-{systemName}"; - GUI.Label(rect, label); + GUI.Label(rect, UnityEditorUtility.GetLabel(labeltext, $"{process.interfaceMeta.Name}-{_systemsList[x].meta.Name}")); } } - GUI.EndScrollView(); } + private static Color NormalizeGridColor(int index, Color color) + { + if (index % 2 == 1) + { + color = color / 1.4f; + color.a = 0.3f; + } + else + { + color.a = 0.5f; + } + return color; + } + private class SystemData + { + public TypeMeta meta; + public IEcsProcess system; + public SystemData(TypeMeta meta, IEcsProcess system) + { + this.meta = meta; + this.system = system; + } + } private class ProcessData { - public Type interfaceType; - public string name; + public TypeMeta interfaceMeta; public BitMask systemsBitMask; } } diff --git a/src/Internal/Editor/UnityEditorUtility.cs b/src/Internal/Editor/UnityEditorUtility.cs index 9a9f2f9..eb0eeb5 100644 --- a/src/Internal/Editor/UnityEditorUtility.cs +++ b/src/Internal/Editor/UnityEditorUtility.cs @@ -105,6 +105,14 @@ namespace DCFApixels.DragonECS.Unity.Editors #endregion #region Label + public static GUIContent GetLabelTemp() + { + if (_singletonContent == null) + { + _singletonContent = new GUIContent(); + } + return _singletonContent; + } public static GUIContent GetLabel(string name, string tooltip = null) { if (_singletonContent == null) diff --git a/src/Internal/Utils/ColorUtility.cs b/src/Internal/Utils/ColorUtility.cs index ca9f91d..fe2b945 100644 --- a/src/Internal/Utils/ColorUtility.cs +++ b/src/Internal/Utils/ColorUtility.cs @@ -14,7 +14,7 @@ namespace DCFApixels.DragonECS.Unity.Internal r = r + (gray - r) * (1 - t); g = g + (gray - g) * (1 - t); b = b + (gray - b) * (1 - t); - return new Color(r, g, b); + return new Color(r, g, b, self.a); } } } \ No newline at end of file From 1d2fa0ad722045e12036b09343a343b038e3ce69 Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Sun, 10 Mar 2024 09:18:40 +0800 Subject: [PATCH 41/50] update --- .../Editor/PipelineProcessesMonitorEditor.cs | 47 +++++++++++++++---- src/Internal/Editor/EcsGUI.cs | 5 +- 2 files changed, 42 insertions(+), 10 deletions(-) diff --git a/src/Debug/Monitors/Editor/PipelineProcessesMonitorEditor.cs b/src/Debug/Monitors/Editor/PipelineProcessesMonitorEditor.cs index 7c7e34a..ae4ff83 100644 --- a/src/Debug/Monitors/Editor/PipelineProcessesMonitorEditor.cs +++ b/src/Debug/Monitors/Editor/PipelineProcessesMonitorEditor.cs @@ -2,6 +2,7 @@ using DCFApixels.DragonECS.Unity.Internal; using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Reflection; using UnityEditor; @@ -62,7 +63,7 @@ namespace DCFApixels.DragonECS.Unity.Editors _processeIndexes.Add(interfaceType, index); data = new ProcessData(); - data.interfaceMeta = meta; + data.meta = meta; data.systemsBitMask = new BitMask(_systemsList.Length); _processList.Add(data); } @@ -77,6 +78,8 @@ namespace DCFApixels.DragonECS.Unity.Editors private Vector2 _cellsize = new Vector2(EditorGUIUtility.singleLineHeight, EditorGUIUtility.singleLineHeight); private Vector2 _nameCellSize = new Vector2(200f, 200f); + //private Vector2Int _selectedPoint = new Vector2Int(-1, -1); + private (TypeMeta system, TypeMeta process) _selectedPointMeta = default; public override void OnInspectorGUI() { EditorGUI.BeginChangeCheck(); @@ -95,9 +98,9 @@ namespace DCFApixels.DragonECS.Unity.Editors Rect rectView = new Rect(0f, 0f, _nameCellSize.x + _cellsize.x * _processList.Count, _nameCellSize.y + _cellsize.y * _systemsList.Length); EditorGUI.DrawRect(rect, new Color(0, 0, 0, 0.6f)); + GUI.Button(rect, "", EditorStyles.helpBox); + _position = GUI.BeginScrollView(rect, _position, rectView, true, true); - //var blackStyle = UnityEditorUtility.GetStyle(Color.black, 0.04f); - //var whiteStyle = UnityEditorUtility.GetStyle(Color.white, 0.04f); Vector2 pivod = _nameCellSize; rect = default; @@ -108,18 +111,24 @@ namespace DCFApixels.DragonECS.Unity.Editors //processes line for (int i = 0; i < _processList.Count; i++) { - TypeMeta meta = _processList[i].interfaceMeta; + TypeMeta meta = _processList[i].meta; Rect lineRect = rect; lineRect.y = 0f; lineRect.x = _nameCellSize.x + _cellsize.x * i; lineRect.width = _cellsize.x; lineRect.height = rectView.height; lineRect = RectUtility.AddPadding(lineRect, 1, 0); - //GUI.Label(lineRect, "", i % 2 == 1 ? whiteStyle : blackStyle); + Color color = meta.Color.ToUnityColor(); color = NormalizeGridColor(i, color); EditorGUI.DrawRect(lineRect, color); + if (EcsGUI.HitTest(lineRect)) + { + GUI.Button(lineRect, "", EditorStyles.selectionRect); + //_selectedPoint.x = i; + _selectedPointMeta.process = meta; + } GUIUtility.RotateAroundPivot(90, pivod); GUI.Label(rect, UnityEditorUtility.GetLabel(meta.Name), EditorStyles.miniBoldLabel); GUIUtility.RotateAroundPivot(-90, pivod); @@ -141,15 +150,23 @@ namespace DCFApixels.DragonECS.Unity.Editors Rect lineRect = rect; lineRect.width = rectView.width; lineRect = RectUtility.AddPadding(lineRect, 0, 1); - //GUI.Label(lineRect, "", i % 2 == 1 ? whiteStyle : blackStyle); + Color color = meta.Color.ToUnityColor(); color = NormalizeGridColor(i, color); EditorGUI.DrawRect(lineRect, color); + if (EcsGUI.HitTest(lineRect)) + { + GUI.Button(lineRect, "", EditorStyles.selectionRect); + //_selectedPoint.y = i; + _selectedPointMeta.system = meta; + } GUI.Label(rect, UnityEditorUtility.GetLabel(name, i + " " + name), EditorStyles.miniBoldLabel); rect.y += _cellsize.y; } + Texture checkIcon = EditorGUIUtility.IconContent("DotFill").image; + //matrix for (int x = 0; x < _processList.Count; x++) { @@ -158,11 +175,23 @@ namespace DCFApixels.DragonECS.Unity.Editors { rect = new Rect(x * _cellsize.x + _nameCellSize.x, y * _cellsize.y + _nameCellSize.y, _cellsize.x, _cellsize.y); bool flag = process.systemsBitMask[y]; - string labeltext = flag ? "^" : " "; - GUI.Label(rect, UnityEditorUtility.GetLabel(labeltext, $"{process.interfaceMeta.Name}-{_systemsList[x].meta.Name}")); + + //string tooltip = $"{process.meta.Name}-{_systemsList[x].meta.Name}"; + //GUIContent label = flag ? UnityEditorUtility.GetLabel(checkIcon, tooltip) : UnityEditorUtility.GetLabel("", tooltip); + //GUI.Label(rect, label); + if (flag) + { + GUI.Label(rect, UnityEditorUtility.GetLabel(checkIcon)); + } } } GUI.EndScrollView(); + + Rect r = GUILayoutUtility.GetRect(EditorGUIUtility.currentViewWidth, EditorGUIUtility.singleLineHeight); + if(_selectedPointMeta.process != null && _selectedPointMeta.system != null) + { + GUI.Label(r, $"{_selectedPointMeta.process.Name}-{_selectedPointMeta.system.Name}"); + } } private static Color NormalizeGridColor(int index, Color color) @@ -190,7 +219,7 @@ namespace DCFApixels.DragonECS.Unity.Editors } private class ProcessData { - public TypeMeta interfaceMeta; + public TypeMeta meta; public BitMask systemsBitMask; } } diff --git a/src/Internal/Editor/EcsGUI.cs b/src/Internal/Editor/EcsGUI.cs index fbe62af..6428dc0 100644 --- a/src/Internal/Editor/EcsGUI.cs +++ b/src/Internal/Editor/EcsGUI.cs @@ -83,7 +83,10 @@ namespace DCFApixels.DragonECS.Unity.Editors // _isInit = true; //} - + internal static bool HitTest(Rect rect) + { + return HitTest(rect, Event.current.mousePosition); + } internal static bool HitTest(Rect rect, Event evt) { return HitTest(rect, evt.mousePosition); From c8a199d412c46370543c69943bc40191516f55cf Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Sun, 10 Mar 2024 09:29:21 +0800 Subject: [PATCH 42/50] rename --- .../{DebugMonitorPrefs.cs => SettingsPrefs.cs} | 6 +++--- ...MonitorPrefs.cs.meta => SettingsPrefs.cs.meta} | 0 .../Monitors/Editor/PipelineMonitorEditor.cs | 8 ++++---- .../Editor/PipelineProcessesMonitorEditor.cs | 15 ++++----------- src/Internal/Editor/EcsGUI.cs | 8 ++++---- 5 files changed, 15 insertions(+), 22 deletions(-) rename src/Debug/Editor/{DebugMonitorPrefs.cs => SettingsPrefs.cs} (82%) rename src/Debug/Editor/{DebugMonitorPrefs.cs.meta => SettingsPrefs.cs.meta} (100%) diff --git a/src/Debug/Editor/DebugMonitorPrefs.cs b/src/Debug/Editor/SettingsPrefs.cs similarity index 82% rename from src/Debug/Editor/DebugMonitorPrefs.cs rename to src/Debug/Editor/SettingsPrefs.cs index 2923965..fdedf29 100644 --- a/src/Debug/Editor/DebugMonitorPrefs.cs +++ b/src/Debug/Editor/SettingsPrefs.cs @@ -4,8 +4,8 @@ using UnityEngine; namespace DCFApixels.DragonECS.Unity.Editors { - [FilePath(EcsConsts.FRAMEWORK_NAME + "/" + nameof(DebugMonitorPrefs) + ".prefs", FilePathAttribute.Location.ProjectFolder)] - public class DebugMonitorPrefs : ScriptableSingleton + [FilePath(EcsConsts.FRAMEWORK_NAME + "/" + nameof(SettingsPrefs) + ".prefs", FilePathAttribute.Location.ProjectFolder)] + public class SettingsPrefs : ScriptableSingleton { [SerializeField] private bool _isShowInterfaces = false; @@ -30,7 +30,7 @@ namespace DCFApixels.DragonECS.Unity.Editors } } [SerializeField] - private bool _isShowRuntimeComponents = true; + private bool _isShowRuntimeComponents = false; public bool IsShowRuntimeComponents { get => _isShowRuntimeComponents; diff --git a/src/Debug/Editor/DebugMonitorPrefs.cs.meta b/src/Debug/Editor/SettingsPrefs.cs.meta similarity index 100% rename from src/Debug/Editor/DebugMonitorPrefs.cs.meta rename to src/Debug/Editor/SettingsPrefs.cs.meta diff --git a/src/Debug/Monitors/Editor/PipelineMonitorEditor.cs b/src/Debug/Monitors/Editor/PipelineMonitorEditor.cs index 41819f6..9936e29 100644 --- a/src/Debug/Monitors/Editor/PipelineMonitorEditor.cs +++ b/src/Debug/Monitors/Editor/PipelineMonitorEditor.cs @@ -22,13 +22,13 @@ namespace DCFApixels.DragonECS.Unity.Editors private PipelineMonitor Target => (PipelineMonitor)target; private bool IsShowInterfaces { - get { return DebugMonitorPrefs.instance.IsShowInterfaces; } - set { DebugMonitorPrefs.instance.IsShowInterfaces = value; } + get { return SettingsPrefs.instance.IsShowInterfaces; } + set { SettingsPrefs.instance.IsShowInterfaces = value; } } private bool IsShowHidden { - get { return DebugMonitorPrefs.instance.IsShowHidden; } - set { DebugMonitorPrefs.instance.IsShowHidden = value; } + get { return SettingsPrefs.instance.IsShowHidden; } + set { SettingsPrefs.instance.IsShowHidden = value; } } public override void OnInspectorGUI() diff --git a/src/Debug/Monitors/Editor/PipelineProcessesMonitorEditor.cs b/src/Debug/Monitors/Editor/PipelineProcessesMonitorEditor.cs index ae4ff83..7dffd56 100644 --- a/src/Debug/Monitors/Editor/PipelineProcessesMonitorEditor.cs +++ b/src/Debug/Monitors/Editor/PipelineProcessesMonitorEditor.cs @@ -23,13 +23,13 @@ namespace DCFApixels.DragonECS.Unity.Editors private PipelineProcessMonitor Target => (PipelineProcessMonitor)target; private bool IsShowInterfaces { - get { return DebugMonitorPrefs.instance.IsShowInterfaces; } - set { DebugMonitorPrefs.instance.IsShowInterfaces = value; } + get { return SettingsPrefs.instance.IsShowInterfaces; } + set { SettingsPrefs.instance.IsShowInterfaces = value; } } private bool IsShowHidden { - get { return DebugMonitorPrefs.instance.IsShowHidden; } - set { DebugMonitorPrefs.instance.IsShowHidden = value; } + get { return SettingsPrefs.instance.IsShowHidden; } + set { SettingsPrefs.instance.IsShowHidden = value; } } private void Init() @@ -78,7 +78,6 @@ namespace DCFApixels.DragonECS.Unity.Editors private Vector2 _cellsize = new Vector2(EditorGUIUtility.singleLineHeight, EditorGUIUtility.singleLineHeight); private Vector2 _nameCellSize = new Vector2(200f, 200f); - //private Vector2Int _selectedPoint = new Vector2Int(-1, -1); private (TypeMeta system, TypeMeta process) _selectedPointMeta = default; public override void OnInspectorGUI() { @@ -126,7 +125,6 @@ namespace DCFApixels.DragonECS.Unity.Editors if (EcsGUI.HitTest(lineRect)) { GUI.Button(lineRect, "", EditorStyles.selectionRect); - //_selectedPoint.x = i; _selectedPointMeta.process = meta; } GUIUtility.RotateAroundPivot(90, pivod); @@ -158,7 +156,6 @@ namespace DCFApixels.DragonECS.Unity.Editors if (EcsGUI.HitTest(lineRect)) { GUI.Button(lineRect, "", EditorStyles.selectionRect); - //_selectedPoint.y = i; _selectedPointMeta.system = meta; } GUI.Label(rect, UnityEditorUtility.GetLabel(name, i + " " + name), EditorStyles.miniBoldLabel); @@ -175,10 +172,6 @@ namespace DCFApixels.DragonECS.Unity.Editors { rect = new Rect(x * _cellsize.x + _nameCellSize.x, y * _cellsize.y + _nameCellSize.y, _cellsize.x, _cellsize.y); bool flag = process.systemsBitMask[y]; - - //string tooltip = $"{process.meta.Name}-{_systemsList[x].meta.Name}"; - //GUIContent label = flag ? UnityEditorUtility.GetLabel(checkIcon, tooltip) : UnityEditorUtility.GetLabel("", tooltip); - //GUI.Label(rect, label); if (flag) { GUI.Label(rect, UnityEditorUtility.GetLabel(checkIcon)); diff --git a/src/Internal/Editor/EcsGUI.cs b/src/Internal/Editor/EcsGUI.cs index 6428dc0..5d13281 100644 --- a/src/Internal/Editor/EcsGUI.cs +++ b/src/Internal/Editor/EcsGUI.cs @@ -48,13 +48,13 @@ namespace DCFApixels.DragonECS.Unity.Editors private static bool IsShowHidden { - get { return DebugMonitorPrefs.instance.IsShowHidden; } - set { DebugMonitorPrefs.instance.IsShowHidden = value; } + get { return SettingsPrefs.instance.IsShowHidden; } + set { SettingsPrefs.instance.IsShowHidden = value; } } private static bool IsShowRuntimeComponents { - get { return DebugMonitorPrefs.instance.IsShowRuntimeComponents; } - set { DebugMonitorPrefs.instance.IsShowRuntimeComponents = value; } + get { return SettingsPrefs.instance.IsShowRuntimeComponents; } + set { SettingsPrefs.instance.IsShowRuntimeComponents = value; } } public enum AddClearComponentButton : byte From c865955e8bab5259b0a0c0fb092e83f2db8e321c Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Sun, 10 Mar 2024 09:50:20 +0800 Subject: [PATCH 43/50] update connect --- ...ameObject.cs => UnityGameObjectConnect.cs} | 16 ++++------ ...cs.meta => UnityGameObjectConnect.cs.meta} | 0 src/Connectors/AutoEntityCreator.cs | 3 +- src/Connectors/EcsEntityConnect.cs | 32 ++++++++----------- 4 files changed, 22 insertions(+), 29 deletions(-) rename src/Buildin/{UnityGameObject.cs => UnityGameObjectConnect.cs} (87%) rename src/Buildin/{UnityGameObject.cs.meta => UnityGameObjectConnect.cs.meta} (100%) diff --git a/src/Buildin/UnityGameObject.cs b/src/Buildin/UnityGameObjectConnect.cs similarity index 87% rename from src/Buildin/UnityGameObject.cs rename to src/Buildin/UnityGameObjectConnect.cs index be8159c..8b96b2a 100644 --- a/src/Buildin/UnityGameObject.cs +++ b/src/Buildin/UnityGameObjectConnect.cs @@ -7,21 +7,19 @@ using UnityEditor; namespace DCFApixels.DragonECS { [MetaColor(MetaColor.Cyan)] - public readonly struct UnityGameObject : IEcsComponent + public readonly struct UnityGameObjectConnect : IEcsComponent { - public readonly GameObject gameObject; + public readonly EcsEntityConnect connect; public readonly Transform transform; - public string Name { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => gameObject.name; + get => connect.name; } - - public UnityGameObject(GameObject gameObject) + public UnityGameObjectConnect(EcsEntityConnect connect) { - this.gameObject = gameObject; - transform = gameObject.transform; + this.connect = connect; + transform = connect.transform; } } @@ -64,7 +62,7 @@ namespace DCFApixels.DragonECS { entlong result = self.NewEntityLong(); GameObject newGameObject = new GameObject(name); - newGameObject.AddComponent().ConnectWith(result); + newGameObject.AddComponent().ConnectWith(result, false); #if UNITY_EDITOR if (icon != GameObjectIcon.NONE) { diff --git a/src/Buildin/UnityGameObject.cs.meta b/src/Buildin/UnityGameObjectConnect.cs.meta similarity index 100% rename from src/Buildin/UnityGameObject.cs.meta rename to src/Buildin/UnityGameObjectConnect.cs.meta diff --git a/src/Connectors/AutoEntityCreator.cs b/src/Connectors/AutoEntityCreator.cs index 86db544..90d3945 100644 --- a/src/Connectors/AutoEntityCreator.cs +++ b/src/Connectors/AutoEntityCreator.cs @@ -58,8 +58,7 @@ namespace DCFApixels.DragonECS } private void InitConnect(EcsEntityConnect connect, EcsWorld world) { - connect.ConnectWith(world.NewEntityLong()); - connect.ApplyTemplates(); + connect.ConnectWith(world.NewEntityLong(), true); } #endregion diff --git a/src/Connectors/EcsEntityConnect.cs b/src/Connectors/EcsEntityConnect.cs index 895b867..cc48f06 100644 --- a/src/Connectors/EcsEntityConnect.cs +++ b/src/Connectors/EcsEntityConnect.cs @@ -11,10 +11,10 @@ namespace DCFApixels.DragonECS { private sealed class Aspect : EcsAspect { - public EcsPool unityGameObjects; + public EcsPool unityGameObjects; protected override void Init(Builder b) { - unityGameObjects = b.Include(); + unityGameObjects = b.Include(); } } @@ -35,12 +35,12 @@ namespace DCFApixels.DragonECS public EcsWorld World { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => _world; + get { return _world; } } public bool IsConected { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => _entity.IsAlive; + get { return _entity.IsAlive; } } public IEnumerable ScriptableTemplates { @@ -57,7 +57,7 @@ namespace DCFApixels.DragonECS #endregion #region Connect - public void ConnectWith(entlong entity, bool applyTemplates = false) + public void ConnectWith(entlong entity, bool applyTemplates) { if (_entity.TryGetID(out int oldEntityID) && _world != null) { @@ -66,18 +66,18 @@ namespace DCFApixels.DragonECS } _world = null; - if (entity.TryGetID(out int newEntityID)) + if (entity.TryUnpack(out int newEntityID, out EcsWorld world)) { _entity = entity; - _world = _entity.World; + _world = world; var a = _world.GetAspect(); - if (!a.unityGameObjects.Has(newEntityID)) + if (a.unityGameObjects.Has(newEntityID) == false) { - a.unityGameObjects.Add(newEntityID) = new UnityGameObject(gameObject); + a.unityGameObjects.Add(newEntityID) = new UnityGameObjectConnect(this); } if (applyTemplates) { - ApplyTemplates(); + ApplyTemplatesFor(world.id, newEntityID); } } else @@ -88,19 +88,15 @@ namespace DCFApixels.DragonECS #endregion #region ApplyTemplates - public void ApplyTemplates() - { - ApplyTemplatesFor(_entity.ID); - } - public void ApplyTemplatesFor(int entityID) + public void ApplyTemplatesFor(short worldID, int entityID) { foreach (var template in _scriptableTemplates) { - template.Apply(_world.id, entityID); + template.Apply(worldID, entityID); } foreach (var template in _monoTemplates) { - template.Apply(_world.id, entityID); + template.Apply(worldID, entityID); } } #endregion @@ -123,7 +119,7 @@ namespace DCFApixels.DragonECS [ContextMenu("Unlink Entity")] internal void UnlinkEntity_Editor() { - ConnectWith(entlong.NULL); + ConnectWith(entlong.NULL, false); } [ContextMenu("Delete Entity")] internal void DeleteEntity_Editor() From 3f1c38a51024bd6e37846ed35d2f17125e38bf03 Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Sun, 10 Mar 2024 10:20:44 +0800 Subject: [PATCH 44/50] update conncetors --- src/Connectors/EcsEntityConnect.cs | 55 ++++++++++++++++--- .../Editor/EcsEntityConnectEditor.cs | 2 +- .../UnityGameObjectConnect.cs | 14 ++++- .../UnityGameObjectConnect.cs.meta | 0 .../Editor/PipelineProcessesMonitorEditor.cs | 4 +- 5 files changed, 60 insertions(+), 15 deletions(-) rename src/{Buildin => Connectors}/UnityGameObjectConnect.cs (84%) rename src/{Buildin => Connectors}/UnityGameObjectConnect.cs.meta (100%) diff --git a/src/Connectors/EcsEntityConnect.cs b/src/Connectors/EcsEntityConnect.cs index cc48f06..d05b886 100644 --- a/src/Connectors/EcsEntityConnect.cs +++ b/src/Connectors/EcsEntityConnect.cs @@ -6,6 +6,33 @@ using UnityEngine; namespace DCFApixels.DragonECS { + public static class EcsConnect + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Connect(GameObject go, entlong entity, bool applyTemplates) + { + Connect(entity, go, applyTemplates); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Connect(entlong entity, GameObject go, bool applyTemplates) + { + if (go.TryGetComponent(out EcsEntityConnect connect) == false) + { + connect = go.AddComponent(); + } + connect.ConnectWith(entity, applyTemplates); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Connect(EcsEntityConnect connect, entlong entity, bool applyTemplates) + { + Connect(entity, connect, applyTemplates); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Connect(entlong entity, EcsEntityConnect connect, bool applyTemplates) + { + connect.ConnectWith(entity, applyTemplates); + } + } [DisallowMultipleComponent] public class EcsEntityConnect : MonoBehaviour { @@ -37,7 +64,7 @@ namespace DCFApixels.DragonECS [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return _world; } } - public bool IsConected + public bool IsConnected { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return _entity.IsAlive; } @@ -59,22 +86,23 @@ namespace DCFApixels.DragonECS #region Connect public void ConnectWith(entlong entity, bool applyTemplates) { - if (_entity.TryGetID(out int oldEntityID) && _world != null) - { - var a = _world.GetAspect(); - a.unityGameObjects.TryDel(oldEntityID); - } - _world = null; + Disconnect(); if (entity.TryUnpack(out int newEntityID, out EcsWorld world)) { _entity = entity; _world = world; var a = _world.GetAspect(); - if (a.unityGameObjects.Has(newEntityID) == false) + if (a.unityGameObjects.Has(newEntityID)) { - a.unityGameObjects.Add(newEntityID) = new UnityGameObjectConnect(this); + ref readonly var uconnect = ref a.unityGameObjects.Read(newEntityID); + if (uconnect.IsConnected) + { + uconnect.connect.Disconnect(); + } } + + a.unityGameObjects.TryAddOrGet(newEntityID) = new UnityGameObjectConnect(this); if (applyTemplates) { ApplyTemplatesFor(world.id, newEntityID); @@ -85,6 +113,15 @@ namespace DCFApixels.DragonECS _entity = entlong.NULL; } } + public void Disconnect() + { + if (_entity.TryGetID(out int oldEntityID) && _world != null) + { + var a = _world.GetAspect(); + a.unityGameObjects.TryDel(oldEntityID); + } + _world = null; + } #endregion #region ApplyTemplates diff --git a/src/Connectors/Editor/EcsEntityConnectEditor.cs b/src/Connectors/Editor/EcsEntityConnectEditor.cs index ae099a9..453144e 100644 --- a/src/Connectors/Editor/EcsEntityConnectEditor.cs +++ b/src/Connectors/Editor/EcsEntityConnectEditor.cs @@ -109,7 +109,7 @@ namespace DCFApixels.DragonECS.Unity.Editors { for (int i = 0; i < targets.Length; i++) { - if (targets[i].IsConected == true) + if (targets[i].IsConnected == true) { EditorGUILayout.HelpBox("Multiple component editing is not available.", MessageType.Warning); return; diff --git a/src/Buildin/UnityGameObjectConnect.cs b/src/Connectors/UnityGameObjectConnect.cs similarity index 84% rename from src/Buildin/UnityGameObjectConnect.cs rename to src/Connectors/UnityGameObjectConnect.cs index 8b96b2a..be3fdeb 100644 --- a/src/Buildin/UnityGameObjectConnect.cs +++ b/src/Connectors/UnityGameObjectConnect.cs @@ -14,9 +14,19 @@ namespace DCFApixels.DragonECS public string Name { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => connect.name; + get { return connect.name; } } - public UnityGameObjectConnect(EcsEntityConnect connect) + public bool IsUnidirectional + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get { return connect == null; } + } + public bool IsConnected + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get { return transform != null; } + } + internal UnityGameObjectConnect(EcsEntityConnect connect) { this.connect = connect; transform = connect.transform; diff --git a/src/Buildin/UnityGameObjectConnect.cs.meta b/src/Connectors/UnityGameObjectConnect.cs.meta similarity index 100% rename from src/Buildin/UnityGameObjectConnect.cs.meta rename to src/Connectors/UnityGameObjectConnect.cs.meta diff --git a/src/Debug/Monitors/Editor/PipelineProcessesMonitorEditor.cs b/src/Debug/Monitors/Editor/PipelineProcessesMonitorEditor.cs index 7dffd56..b5b9e0a 100644 --- a/src/Debug/Monitors/Editor/PipelineProcessesMonitorEditor.cs +++ b/src/Debug/Monitors/Editor/PipelineProcessesMonitorEditor.cs @@ -2,9 +2,7 @@ using DCFApixels.DragonECS.Unity.Internal; using System; using System.Collections.Generic; -using System.Diagnostics; using System.Linq; -using System.Reflection; using UnityEditor; using UnityEngine; @@ -181,7 +179,7 @@ namespace DCFApixels.DragonECS.Unity.Editors GUI.EndScrollView(); Rect r = GUILayoutUtility.GetRect(EditorGUIUtility.currentViewWidth, EditorGUIUtility.singleLineHeight); - if(_selectedPointMeta.process != null && _selectedPointMeta.system != null) + if (_selectedPointMeta.process != null && _selectedPointMeta.system != null) { GUI.Label(r, $"{_selectedPointMeta.process.Name}-{_selectedPointMeta.system.Name}"); } From 1d8b693ccac37deaf6397208e2e2990e077f1d47 Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Sun, 10 Mar 2024 10:24:58 +0800 Subject: [PATCH 45/50] update connectors --- src/Connectors/EcsEntityConnect.cs | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/Connectors/EcsEntityConnect.cs b/src/Connectors/EcsEntityConnect.cs index d05b886..b7d2a02 100644 --- a/src/Connectors/EcsEntityConnect.cs +++ b/src/Connectors/EcsEntityConnect.cs @@ -9,12 +9,27 @@ namespace DCFApixels.DragonECS public static class EcsConnect { [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Connect(GameObject go, entlong entity, bool applyTemplates) + public static void Connect(this Component cmp, entlong entity, bool applyTemplates) + { + Connect(entity, cmp, applyTemplates); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Connect(this entlong entity, Component cmp, bool applyTemplates) + { + if (cmp.TryGetComponent(out EcsEntityConnect connect) == false) + { + connect = cmp.gameObject.AddComponent(); + } + connect.ConnectWith(entity, applyTemplates); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Connect(this GameObject go, entlong entity, bool applyTemplates) { Connect(entity, go, applyTemplates); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Connect(entlong entity, GameObject go, bool applyTemplates) + public static void Connect(this entlong entity, GameObject go, bool applyTemplates) { if (go.TryGetComponent(out EcsEntityConnect connect) == false) { @@ -22,17 +37,19 @@ namespace DCFApixels.DragonECS } connect.ConnectWith(entity, applyTemplates); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Connect(EcsEntityConnect connect, entlong entity, bool applyTemplates) + public static void Connect(this EcsEntityConnect connect, entlong entity, bool applyTemplates) { Connect(entity, connect, applyTemplates); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Connect(entlong entity, EcsEntityConnect connect, bool applyTemplates) + public static void Connect(this entlong entity, EcsEntityConnect connect, bool applyTemplates) { connect.ConnectWith(entity, applyTemplates); } } + [DisallowMultipleComponent] public class EcsEntityConnect : MonoBehaviour { From d0d3d5bd78139fe31247638e3fbc7e99fddc39b9 Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Sun, 10 Mar 2024 10:29:58 +0800 Subject: [PATCH 46/50] Update EcsEntityConnect.cs --- src/Connectors/EcsEntityConnect.cs | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/src/Connectors/EcsEntityConnect.cs b/src/Connectors/EcsEntityConnect.cs index b7d2a02..9d78132 100644 --- a/src/Connectors/EcsEntityConnect.cs +++ b/src/Connectors/EcsEntityConnect.cs @@ -53,15 +53,6 @@ namespace DCFApixels.DragonECS [DisallowMultipleComponent] public class EcsEntityConnect : MonoBehaviour { - private sealed class Aspect : EcsAspect - { - public EcsPool unityGameObjects; - protected override void Init(Builder b) - { - unityGameObjects = b.Include(); - } - } - private entlong _entity; private EcsWorld _world; @@ -109,17 +100,17 @@ namespace DCFApixels.DragonECS { _entity = entity; _world = world; - var a = _world.GetAspect(); - if (a.unityGameObjects.Has(newEntityID)) + var unityGameObjects = _world.GetPool(); + if (unityGameObjects.Has(newEntityID)) { - ref readonly var uconnect = ref a.unityGameObjects.Read(newEntityID); + ref readonly var uconnect = ref unityGameObjects.Read(newEntityID); if (uconnect.IsConnected) { uconnect.connect.Disconnect(); } } - a.unityGameObjects.TryAddOrGet(newEntityID) = new UnityGameObjectConnect(this); + unityGameObjects.TryAddOrGet(newEntityID) = new UnityGameObjectConnect(this); if (applyTemplates) { ApplyTemplatesFor(world.id, newEntityID); @@ -134,8 +125,8 @@ namespace DCFApixels.DragonECS { if (_entity.TryGetID(out int oldEntityID) && _world != null) { - var a = _world.GetAspect(); - a.unityGameObjects.TryDel(oldEntityID); + var unityGameObjects = _world.GetPool(); + unityGameObjects.TryDel(oldEntityID); } _world = null; } From ba93aa4871d76d3812f56cfcc7ce0f0ffeb7452e Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Sun, 10 Mar 2024 10:35:02 +0800 Subject: [PATCH 47/50] Update EcsEntityConnect.cs --- src/Connectors/EcsEntityConnect.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Connectors/EcsEntityConnect.cs b/src/Connectors/EcsEntityConnect.cs index 9d78132..3fab46f 100644 --- a/src/Connectors/EcsEntityConnect.cs +++ b/src/Connectors/EcsEntityConnect.cs @@ -129,6 +129,7 @@ namespace DCFApixels.DragonECS unityGameObjects.TryDel(oldEntityID); } _world = null; + _entity = entlong.NULL; } #endregion From 7b31c7d0ba757a173966e88afd8497335383cb71 Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Sun, 10 Mar 2024 19:23:05 +0800 Subject: [PATCH 48/50] update --- src/Connectors/EcsEntityConnect.cs | 7 +++++++ src/Connectors/UnityGameObjectConnect.cs | 22 +++++++++++++++------- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/Connectors/EcsEntityConnect.cs b/src/Connectors/EcsEntityConnect.cs index 3fab46f..0f08c57 100644 --- a/src/Connectors/EcsEntityConnect.cs +++ b/src/Connectors/EcsEntityConnect.cs @@ -147,6 +147,13 @@ namespace DCFApixels.DragonECS } #endregion + #region UnityEvents + private void OnDestroy() + { + Disconnect(); + } + #endregion + #region Editor #if UNITY_EDITOR [ContextMenu("Autoset")] diff --git a/src/Connectors/UnityGameObjectConnect.cs b/src/Connectors/UnityGameObjectConnect.cs index be3fdeb..e92b602 100644 --- a/src/Connectors/UnityGameObjectConnect.cs +++ b/src/Connectors/UnityGameObjectConnect.cs @@ -7,7 +7,7 @@ using UnityEditor; namespace DCFApixels.DragonECS { [MetaColor(MetaColor.Cyan)] - public readonly struct UnityGameObjectConnect : IEcsComponent + public readonly struct UnityGameObjectConnect : IEcsComponent, IEcsComponentLifecycle { public readonly EcsEntityConnect connect; public readonly Transform transform; @@ -16,21 +16,29 @@ namespace DCFApixels.DragonECS [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return connect.name; } } - public bool IsUnidirectional - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get { return connect == null; } - } public bool IsConnected { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get { return transform != null; } + get { return connect != null; } } internal UnityGameObjectConnect(EcsEntityConnect connect) { this.connect = connect; transform = connect.transform; } + + void IEcsComponentLifecycle.Enable(ref UnityGameObjectConnect component) + { + component = default; + } + void IEcsComponentLifecycle.Disable(ref UnityGameObjectConnect component) + { + if (component.connect != null) + { + component.connect.Disconnect(); + } + component = default; + } } public enum GameObjectIcon : byte From 7b94683522a31e27165416d6a595f1997269dc11 Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Sun, 10 Mar 2024 22:27:17 +0800 Subject: [PATCH 49/50] update connectors --- src/Connectors/EcsEntityConnect.cs | 26 +++++++++-------- ...eObjectConnect.cs => GameObjectConnect.cs} | 28 ++++++++----------- ...nect.cs.meta => GameObjectConnect.cs.meta} | 0 3 files changed, 26 insertions(+), 28 deletions(-) rename src/Connectors/{UnityGameObjectConnect.cs => GameObjectConnect.cs} (71%) rename src/Connectors/{UnityGameObjectConnect.cs.meta => GameObjectConnect.cs.meta} (100%) diff --git a/src/Connectors/EcsEntityConnect.cs b/src/Connectors/EcsEntityConnect.cs index 0f08c57..1e6f997 100644 --- a/src/Connectors/EcsEntityConnect.cs +++ b/src/Connectors/EcsEntityConnect.cs @@ -61,6 +61,8 @@ namespace DCFApixels.DragonECS [SerializeField] private MonoEntityTemplate[] _monoTemplates; + private bool _isConnected = false; + #region Properties public entlong Entity { @@ -98,34 +100,36 @@ namespace DCFApixels.DragonECS if (entity.TryUnpack(out int newEntityID, out EcsWorld world)) { + _isConnected = true; _entity = entity; _world = world; - var unityGameObjects = _world.GetPool(); - if (unityGameObjects.Has(newEntityID)) + var goConnects = world.GetPool(); + if (goConnects.Has(newEntityID)) { - ref readonly var uconnect = ref unityGameObjects.Read(newEntityID); - if (uconnect.IsConnected) + ref readonly var goConnect = ref goConnects.Read(newEntityID); + if (goConnect.IsConnected) { - uconnect.connect.Disconnect(); + goConnect.Connect.Disconnect(); } } - unityGameObjects.TryAddOrGet(newEntityID) = new UnityGameObjectConnect(this); + goConnects.TryAddOrGet(newEntityID) = new GameObjectConnect(this); if (applyTemplates) { ApplyTemplatesFor(world.id, newEntityID); } } - else - { - _entity = entlong.NULL; - } } public void Disconnect() { + if(_isConnected == false) + { + return; + } + _isConnected = false; if (_entity.TryGetID(out int oldEntityID) && _world != null) { - var unityGameObjects = _world.GetPool(); + var unityGameObjects = _world.GetPool(); unityGameObjects.TryDel(oldEntityID); } _world = null; diff --git a/src/Connectors/UnityGameObjectConnect.cs b/src/Connectors/GameObjectConnect.cs similarity index 71% rename from src/Connectors/UnityGameObjectConnect.cs rename to src/Connectors/GameObjectConnect.cs index e92b602..71c21ec 100644 --- a/src/Connectors/UnityGameObjectConnect.cs +++ b/src/Connectors/GameObjectConnect.cs @@ -7,35 +7,29 @@ using UnityEditor; namespace DCFApixels.DragonECS { [MetaColor(MetaColor.Cyan)] - public readonly struct UnityGameObjectConnect : IEcsComponent, IEcsComponentLifecycle + public readonly struct GameObjectConnect : IEcsComponent, IEcsComponentLifecycle { - public readonly EcsEntityConnect connect; - public readonly Transform transform; - public string Name - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get { return connect.name; } - } + public readonly EcsEntityConnect Connect; public bool IsConnected { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get { return connect != null; } + get { return Connect != null; } } - internal UnityGameObjectConnect(EcsEntityConnect connect) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal GameObjectConnect(EcsEntityConnect connect) { - this.connect = connect; - transform = connect.transform; + Connect = connect; } - void IEcsComponentLifecycle.Enable(ref UnityGameObjectConnect component) + void IEcsComponentLifecycle.Enable(ref GameObjectConnect component) { component = default; } - void IEcsComponentLifecycle.Disable(ref UnityGameObjectConnect component) + void IEcsComponentLifecycle.Disable(ref GameObjectConnect component) { - if (component.connect != null) + if (component.Connect != null) { - component.connect.Disconnect(); + component.Connect.Disconnect(); } component = default; } @@ -69,7 +63,7 @@ namespace DCFApixels.DragonECS Diamond_Red, Diamond_Purple } - public static class GameObjectIconConsts + internal static class GameObjectIconConsts { public const int RAW_LABEL_ICON_LAST = (int)GameObjectIcon.Label_Purple; } diff --git a/src/Connectors/UnityGameObjectConnect.cs.meta b/src/Connectors/GameObjectConnect.cs.meta similarity index 100% rename from src/Connectors/UnityGameObjectConnect.cs.meta rename to src/Connectors/GameObjectConnect.cs.meta From 955f4bc60af989c11f2cde35e7f07a9fef6afbba Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Sun, 10 Mar 2024 22:29:17 +0800 Subject: [PATCH 50/50] Update package.json --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4b134a8..6a84a35 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ }, "displayName": "DragonECS-Unity", "description": "Integration with Unity for DragonECS", - "unity": "2020.3", + "unity": "2021.2", "version": "0.3.0", "repository": { "type": "git",