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)) {