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