com.artromskiy.deltaecs.unity 0.0.53 → 0.0.56

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.0.56
4
+
5
+ - Published with the matching DeltaECS NuGet packages.
6
+
7
+ ## 0.0.54
8
+
9
+ - Published with the matching DeltaECS NuGet packages.
10
+
3
11
  ## 0.0.53
4
12
 
5
13
  - Published with the matching DeltaECS NuGet packages.
@@ -1,66 +1,16 @@
1
1
  using System;
2
2
  using System.Collections.Generic;
3
+
3
4
  using Delta.ECS;
5
+
4
6
  using UnityEditor;
5
7
  using UnityEditor.UIElements;
8
+
6
9
  using UnityEngine;
7
10
  using UnityEngine.UIElements;
8
11
 
9
12
  namespace Delta.ECS.Unity.Editor
10
13
  {
11
- internal static class BoundEntityRootEditorSelector
12
- {
13
- private static bool _creatingDefaultGameObjectEditor;
14
-
15
- [RootEditor(supportsAddComponent: true)]
16
- private static Type SelectRootEditor(UnityEngine.Object[] objects)
17
- {
18
- if (_creatingDefaultGameObjectEditor)
19
- {
20
- return null;
21
- }
22
-
23
- if (objects == null || objects.Length != 1
24
- || objects[0] is not GameObject gameObject
25
- || gameObject == null)
26
- {
27
- return null;
28
- }
29
-
30
- if (SceneWorld.TryFindLiveWorld(gameObject, out _, out _))
31
- {
32
- return typeof(BoundEntityRootEditor);
33
- }
34
-
35
- if (EditorApplication.isPlayingOrWillChangePlaymode)
36
- {
37
- return null;
38
- }
39
-
40
- SceneAuthoring authoring = SceneAuthoring.FindForScene(gameObject.scene);
41
- return authoring != null && authoring.TryGetStableId(gameObject, out _)
42
- ? typeof(BoundEntityRootEditor)
43
- : null;
44
- }
45
-
46
- internal static UnityEditor.Editor CreateDefaultGameObjectEditor(GameObject gameObject)
47
- {
48
- if (gameObject == null)
49
- {
50
- return null;
51
- }
52
-
53
- _creatingDefaultGameObjectEditor = true;
54
- try
55
- {
56
- return UnityEditor.Editor.CreateEditor(gameObject);
57
- }
58
- finally
59
- {
60
- _creatingDefaultGameObjectEditor = false;
61
- }
62
- }
63
- }
64
14
 
65
15
  internal sealed class BoundEntityRootEditor : UnityEditor.Editor
66
16
  {
@@ -73,54 +23,6 @@ namespace Delta.ECS.Unity.Editor
73
23
  private SceneEntityInspectorView _view;
74
24
  private VisualElement _componentInspectorRoot;
75
25
 
76
- private void OnEnable()
77
- {
78
- if (target is GameObject gameObject && gameObject != null)
79
- {
80
- _gameObjectEditor = BoundEntityRootEditorSelector.CreateDefaultGameObjectEditor(gameObject);
81
- }
82
-
83
- _view = new SceneEntityInspectorView(ResolveTarget, embedded: true);
84
- EditorApplication.hierarchyChanged += RefreshComponentInspectors;
85
- Undo.undoRedoPerformed += RefreshComponentInspectors;
86
- }
87
-
88
- private void OnDisable()
89
- {
90
- _view?.Dispose();
91
- _view = null;
92
- if (_gameObjectEditor != null)
93
- {
94
- DestroyImmediate(_gameObjectEditor);
95
- _gameObjectEditor = null;
96
- }
97
-
98
- EditorApplication.hierarchyChanged -= RefreshComponentInspectors;
99
- Undo.undoRedoPerformed -= RefreshComponentInspectors;
100
- _componentInspectorRoot = null;
101
- DisposeComponentEditors();
102
- }
103
-
104
- protected override void OnHeaderGUI()
105
- {
106
- // The root editor's generic object header is replaced by the native
107
- // GameObjectInspector header embedded at the top of CreateInspectorGUI.
108
- }
109
-
110
- private void DisposeComponentEditors()
111
- {
112
- foreach (UnityEditor.Editor componentEditor in _componentEditors)
113
- {
114
- if (componentEditor != null)
115
- {
116
- DestroyImmediate(componentEditor);
117
- }
118
- }
119
-
120
- _componentEditors.Clear();
121
- _componentTargets.Clear();
122
- }
123
-
124
26
  public override bool UseDefaultMargins() => false;
125
27
 
126
28
  public override bool RequiresConstantRepaint()
@@ -186,6 +88,57 @@ namespace Delta.ECS.Unity.Editor
186
88
  return root;
187
89
  }
188
90
 
91
+ protected override void OnHeaderGUI()
92
+ {
93
+ // The root editor's generic object header is replaced by the native
94
+ // GameObjectInspector header embedded at the top of CreateInspectorGUI.
95
+ }
96
+
97
+ private static bool ShouldDrawComponent(Component component) => component != null
98
+ && (component.hideFlags & HideFlags.HideInInspector) == 0;
99
+
100
+ private void OnEnable()
101
+ {
102
+ if (target is GameObject gameObject && gameObject != null)
103
+ {
104
+ _gameObjectEditor = BoundEntityRootEditorSelector.CreateDefaultGameObjectEditor(gameObject);
105
+ }
106
+
107
+ _view = new SceneEntityInspectorView(ResolveTarget, embedded: true);
108
+ EditorApplication.hierarchyChanged += RefreshComponentInspectors;
109
+ Undo.undoRedoPerformed += RefreshComponentInspectors;
110
+ }
111
+
112
+ private void OnDisable()
113
+ {
114
+ _view?.Dispose();
115
+ _view = null;
116
+ if (_gameObjectEditor != null)
117
+ {
118
+ DestroyImmediate(_gameObjectEditor);
119
+ _gameObjectEditor = null;
120
+ }
121
+
122
+ EditorApplication.hierarchyChanged -= RefreshComponentInspectors;
123
+ Undo.undoRedoPerformed -= RefreshComponentInspectors;
124
+ _componentInspectorRoot = null;
125
+ DisposeComponentEditors();
126
+ }
127
+
128
+ private void DisposeComponentEditors()
129
+ {
130
+ foreach (UnityEditor.Editor componentEditor in _componentEditors)
131
+ {
132
+ if (componentEditor != null)
133
+ {
134
+ DestroyImmediate(componentEditor);
135
+ }
136
+ }
137
+
138
+ _componentEditors.Clear();
139
+ _componentTargets.Clear();
140
+ }
141
+
189
142
  private void DrawGameObjectHeader(UnityEditor.Editor gameObjectEditor)
190
143
  {
191
144
  if (gameObjectEditor == null
@@ -274,9 +227,6 @@ namespace Delta.ECS.Unity.Editor
274
227
  }
275
228
  }
276
229
 
277
- private static bool ShouldDrawComponent(Component component) => component != null
278
- && (component.hideFlags & HideFlags.HideInInspector) == 0;
279
-
280
230
  private EntityInspectorTarget ResolveTarget()
281
231
  {
282
232
  if (target is not GameObject gameObject || gameObject == null)
@@ -302,4 +252,57 @@ namespace Delta.ECS.Unity.Editor
302
252
  return default;
303
253
  }
304
254
  }
255
+ internal static class BoundEntityRootEditorSelector
256
+ {
257
+ private static bool _creatingDefaultGameObjectEditor;
258
+
259
+ internal static UnityEditor.Editor CreateDefaultGameObjectEditor(GameObject gameObject)
260
+ {
261
+ if (gameObject == null)
262
+ {
263
+ return null;
264
+ }
265
+
266
+ _creatingDefaultGameObjectEditor = true;
267
+ try
268
+ {
269
+ return UnityEditor.Editor.CreateEditor(gameObject);
270
+ }
271
+ finally
272
+ {
273
+ _creatingDefaultGameObjectEditor = false;
274
+ }
275
+ }
276
+
277
+ [RootEditor(supportsAddComponent: true)]
278
+ private static Type SelectRootEditor(UnityEngine.Object[] objects)
279
+ {
280
+ if (_creatingDefaultGameObjectEditor)
281
+ {
282
+ return null;
283
+ }
284
+
285
+ if (objects == null || objects.Length != 1
286
+ || objects[0] is not GameObject gameObject
287
+ || gameObject == null)
288
+ {
289
+ return null;
290
+ }
291
+
292
+ if (SceneWorld.TryFindLiveWorld(gameObject, out _, out _))
293
+ {
294
+ return typeof(BoundEntityRootEditor);
295
+ }
296
+
297
+ if (EditorApplication.isPlayingOrWillChangePlaymode)
298
+ {
299
+ return null;
300
+ }
301
+
302
+ SceneAuthoring authoring = SceneAuthoring.FindForScene(gameObject.scene);
303
+ return authoring != null && authoring.TryGetStableId(gameObject, out _)
304
+ ? typeof(BoundEntityRootEditor)
305
+ : null;
306
+ }
307
+ }
305
308
  }
@@ -2,8 +2,11 @@ using System;
2
2
  using System.Collections.Generic;
3
3
  using System.Linq;
4
4
  using System.Reflection;
5
+
5
6
  using Delta.ECS.Integration;
7
+
6
8
  using UnityEditor.IMGUI.Controls;
9
+
7
10
  using UnityEngine;
8
11
 
9
12
  namespace Delta.ECS.Unity.Editor
@@ -1,5 +1,6 @@
1
- using UnityEditor.UIElements;
2
1
  using UnityEditor.IMGUI.Controls;
2
+ using UnityEditor.UIElements;
3
+
3
4
  using UnityEngine;
4
5
  using UnityEngine.UIElements;
5
6
 
@@ -1,30 +1,21 @@
1
1
  using System;
2
2
  using System.Collections.Generic;
3
+
3
4
  using Delta;
4
5
  using Delta.ECS;
5
6
  using Delta.ECS.Integration;
6
7
  using Delta.ECS.Unity;
8
+
7
9
  using Unity.Properties;
10
+
8
11
  using UnityEditor;
9
12
  using UnityEditor.UIElements;
13
+
10
14
  using UnityEngine;
11
15
  using UnityEngine.UIElements;
12
16
 
13
17
  namespace Delta.ECS.Unity.Editor
14
18
  {
15
- internal readonly struct ComponentPropertyBinding
16
- {
17
- internal readonly string[] Path;
18
- internal readonly Type ValueType;
19
- internal readonly VisualElement Control;
20
-
21
- internal ComponentPropertyBinding(string[] path, Type valueType, VisualElement control)
22
- {
23
- Path = path;
24
- ValueType = valueType;
25
- Control = control;
26
- }
27
- }
28
19
 
29
20
  internal static class ComponentPropertyBagFields
30
21
  {
@@ -50,86 +41,6 @@ namespace Delta.ECS.Unity.Editor
50
41
  return bindings.ToArray();
51
42
  }
52
43
 
53
- private sealed class PropertyFieldVisitor : IPropertyBagVisitor, IPropertyVisitor
54
- {
55
- private readonly VisualElement _parent;
56
- private readonly bool _canWrite;
57
- private readonly string[] _path;
58
- private readonly int _depth;
59
- private readonly List<ComponentPropertyBinding> _bindings;
60
- private readonly Action<string[], object> _onChanged;
61
- private readonly Func<string, Entity, Action<object>, VisualElement> _createEntityField;
62
-
63
- internal PropertyFieldVisitor(VisualElement parent, bool canWrite, string[] path, int depth,
64
- List<ComponentPropertyBinding> bindings, Action<string[], object> onChanged,
65
- Func<string, Entity, Action<object>, VisualElement> createEntityField)
66
- {
67
- _parent = parent;
68
- _canWrite = canWrite;
69
- _path = path;
70
- _depth = depth;
71
- _bindings = bindings;
72
- _onChanged = onChanged;
73
- _createEntityField = createEntityField;
74
- }
75
-
76
- public void Visit<TContainer>(IPropertyBag<TContainer> properties, ref TContainer container)
77
- {
78
- foreach (var property in properties.GetProperties(ref container))
79
- {
80
- ((IPropertyAccept<TContainer>)property).Accept(this, ref container);
81
- }
82
- }
83
-
84
- public void Visit<TContainer, TValue>(Property<TContainer, TValue> property, ref TContainer container)
85
- {
86
- TValue value = property.GetValue(ref container);
87
- Type valueType = typeof(TValue);
88
- string[] path = Append(_path, property.Name);
89
- string label = GetLabel(property.Name);
90
- bool canWrite = _canWrite && !property.IsReadOnly;
91
-
92
- VisualElement control = CreateFieldControl(label, valueType, value,
93
- next => _onChanged(path, next), canWrite, _createEntityField);
94
- if (control != null)
95
- {
96
- _parent.Add(control);
97
- _bindings.Add(new ComponentPropertyBinding(path, valueType, control));
98
- return;
99
- }
100
-
101
- if (value != null && _depth < 24)
102
- {
103
- object nestedValue = value;
104
- IPropertyBag nestedBag = PropertyBag.GetPropertyBag(nestedValue.GetType());
105
- if (nestedBag != null)
106
- {
107
- var foldout = new Foldout { text = label, value = true };
108
- foldout.AddToClassList("ecs-property-foldout");
109
- _parent.Add(foldout);
110
- int previousCount = _bindings.Count;
111
- bool canWriteNested = canWrite && valueType.IsValueType;
112
- var nestedVisitor = new PropertyFieldVisitor(foldout, canWriteNested, path,
113
- _depth + 1, _bindings, _onChanged, _createEntityField);
114
- nestedBag.Accept(nestedVisitor, ref nestedValue);
115
- if (_bindings.Count == previousCount)
116
- {
117
- var empty = new Label("No exposed properties.");
118
- empty.AddToClassList("ecs-empty-component");
119
- foldout.Add(empty);
120
- }
121
-
122
- return;
123
- }
124
- }
125
-
126
- string detail = value == null ? "Null" : $"Unsupported: {valueType.Name}";
127
- var unsupported = new Label($"{label} · {detail}");
128
- unsupported.AddToClassList("ecs-unsupported-field");
129
- _parent.Add(unsupported);
130
- }
131
- }
132
-
133
44
  private static VisualElement CreateFieldControl(string label, Type type, object value,
134
45
  Action<object> onChanged, bool canWrite,
135
46
  Func<string, Entity, Action<object>, VisualElement> createEntityField)
@@ -276,5 +187,98 @@ namespace Delta.ECS.Unity.Editor
276
187
  ? $"Element {index}"
277
188
  : ObjectNames.NicifyVariableName(name);
278
189
  }
190
+
191
+ private sealed class PropertyFieldVisitor : IPropertyBagVisitor, IPropertyVisitor
192
+ {
193
+ private readonly VisualElement _parent;
194
+ private readonly bool _canWrite;
195
+ private readonly string[] _path;
196
+ private readonly int _depth;
197
+ private readonly List<ComponentPropertyBinding> _bindings;
198
+ private readonly Action<string[], object> _onChanged;
199
+ private readonly Func<string, Entity, Action<object>, VisualElement> _createEntityField;
200
+
201
+ internal PropertyFieldVisitor(VisualElement parent, bool canWrite, string[] path, int depth,
202
+ List<ComponentPropertyBinding> bindings, Action<string[], object> onChanged,
203
+ Func<string, Entity, Action<object>, VisualElement> createEntityField)
204
+ {
205
+ _parent = parent;
206
+ _canWrite = canWrite;
207
+ _path = path;
208
+ _depth = depth;
209
+ _bindings = bindings;
210
+ _onChanged = onChanged;
211
+ _createEntityField = createEntityField;
212
+ }
213
+
214
+ public void Visit<TContainer>(IPropertyBag<TContainer> properties, ref TContainer container)
215
+ {
216
+ foreach (var property in properties.GetProperties(ref container))
217
+ {
218
+ ((IPropertyAccept<TContainer>)property).Accept(this, ref container);
219
+ }
220
+ }
221
+
222
+ public void Visit<TContainer, TValue>(Property<TContainer, TValue> property, ref TContainer container)
223
+ {
224
+ TValue value = property.GetValue(ref container);
225
+ Type valueType = typeof(TValue);
226
+ string[] path = Append(_path, property.Name);
227
+ string label = GetLabel(property.Name);
228
+ bool canWrite = _canWrite && !property.IsReadOnly;
229
+
230
+ VisualElement control = CreateFieldControl(label, valueType, value,
231
+ next => _onChanged(path, next), canWrite, _createEntityField);
232
+ if (control != null)
233
+ {
234
+ _parent.Add(control);
235
+ _bindings.Add(new ComponentPropertyBinding(path, valueType, control));
236
+ return;
237
+ }
238
+
239
+ if (value != null && _depth < 24)
240
+ {
241
+ object nestedValue = value;
242
+ IPropertyBag nestedBag = PropertyBag.GetPropertyBag(nestedValue.GetType());
243
+ if (nestedBag != null)
244
+ {
245
+ var foldout = new Foldout { text = label, value = true };
246
+ foldout.AddToClassList("ecs-property-foldout");
247
+ _parent.Add(foldout);
248
+ int previousCount = _bindings.Count;
249
+ bool canWriteNested = canWrite && valueType.IsValueType;
250
+ var nestedVisitor = new PropertyFieldVisitor(foldout, canWriteNested, path,
251
+ _depth + 1, _bindings, _onChanged, _createEntityField);
252
+ nestedBag.Accept(nestedVisitor, ref nestedValue);
253
+ if (_bindings.Count == previousCount)
254
+ {
255
+ var empty = new Label("No exposed properties.");
256
+ empty.AddToClassList("ecs-empty-component");
257
+ foldout.Add(empty);
258
+ }
259
+
260
+ return;
261
+ }
262
+ }
263
+
264
+ string detail = value == null ? "Null" : $"Unsupported: {valueType.Name}";
265
+ var unsupported = new Label($"{label} · {detail}");
266
+ unsupported.AddToClassList("ecs-unsupported-field");
267
+ _parent.Add(unsupported);
268
+ }
269
+ }
270
+ }
271
+ internal readonly struct ComponentPropertyBinding
272
+ {
273
+ internal readonly string[] Path;
274
+ internal readonly Type ValueType;
275
+ internal readonly VisualElement Control;
276
+
277
+ internal ComponentPropertyBinding(string[] path, Type valueType, VisualElement control)
278
+ {
279
+ Path = path;
280
+ ValueType = valueType;
281
+ Control = control;
282
+ }
279
283
  }
280
284
  }
@@ -1,5 +1,6 @@
1
1
  using UnityEditor;
2
2
  using UnityEditor.SceneManagement;
3
+
3
4
  using UnityEngine;
4
5
  using UnityEngine.SceneManagement;
5
6
 
@@ -9,6 +9,8 @@ namespace Delta.ECS.Unity.Editor
9
9
  internal readonly SceneWorld RuntimeWorld;
10
10
  internal readonly Entity RuntimeEntity;
11
11
 
12
+ internal bool IsRuntime => RuntimeWorld != null && RuntimeEntity.IsValid;
13
+
12
14
  internal EntityInspectorTarget(
13
15
  SceneAuthoring authoring,
14
16
  string stableId,
@@ -20,7 +22,5 @@ namespace Delta.ECS.Unity.Editor
20
22
  RuntimeWorld = runtimeWorld;
21
23
  RuntimeEntity = runtimeEntity;
22
24
  }
23
-
24
- internal bool IsRuntime => RuntimeWorld != null && RuntimeEntity.IsValid;
25
25
  }
26
26
  }
@@ -1,7 +1,10 @@
1
1
  using System;
2
+
2
3
  using Unity.Hierarchy;
4
+
3
5
  using UnityEditor;
4
6
  using UnityEditor.SceneManagement;
7
+
5
8
  using UnityEngine;
6
9
  using UnityEngine.SceneManagement;
7
10
 
@@ -11,33 +14,6 @@ namespace Delta.ECS.Unity.Editor
11
14
  {
12
15
  internal static event Action<SceneAuthoring> AuthoringChanged;
13
16
 
14
- [MenuItem("GameObject/Delta ECS Entity", false, 10)]
15
- private static void CreateEntityFromHierarchyMenu(MenuCommand command)
16
- {
17
- GameObject contextObject = command.context as GameObject;
18
- Scene scene = contextObject != null
19
- ? contextObject.scene
20
- : SceneManager.GetActiveScene();
21
-
22
- SceneAuthoring authoring = SceneAuthoring.GetOrCreateForScene(scene);
23
- CreateEntity(authoring);
24
- }
25
-
26
- [MenuItem("GameObject/Delta ECS Entity", true)]
27
- private static bool ValidateCreateEntityFromHierarchyMenu() =>
28
- !EditorApplication.isPlayingOrWillChangePlaymode;
29
-
30
- [MenuItem("Tools/Delta ECS/Create Entity", false, 31)]
31
- private static void CreateEntityMenu()
32
- {
33
- Scene scene = SceneManager.GetActiveScene();
34
- SceneAuthoring authoring = SceneAuthoring.GetOrCreateForScene(scene);
35
- CreateEntity(authoring);
36
- }
37
-
38
- [MenuItem("Tools/Delta ECS/Create Entity", true)]
39
- private static bool ValidateCreateEntityMenu() => !EditorApplication.isPlayingOrWillChangePlaymode;
40
-
41
17
  internal static EntityAuthoring CreateEntity(
42
18
  SceneAuthoring authoring,
43
19
  HierarchyView view = null)
@@ -81,5 +57,32 @@ namespace Delta.ECS.Unity.Editor
81
57
  EditorUtility.SetDirty(authoring);
82
58
  EditorSceneManager.MarkSceneDirty(authoring.gameObject.scene);
83
59
  }
60
+
61
+ [MenuItem("GameObject/Delta ECS Entity", false, 10)]
62
+ private static void CreateEntityFromHierarchyMenu(MenuCommand command)
63
+ {
64
+ GameObject contextObject = command.context as GameObject;
65
+ Scene scene = contextObject != null
66
+ ? contextObject.scene
67
+ : SceneManager.GetActiveScene();
68
+
69
+ SceneAuthoring authoring = SceneAuthoring.GetOrCreateForScene(scene);
70
+ CreateEntity(authoring);
71
+ }
72
+
73
+ [MenuItem("GameObject/Delta ECS Entity", true)]
74
+ private static bool ValidateCreateEntityFromHierarchyMenu() =>
75
+ !EditorApplication.isPlayingOrWillChangePlaymode;
76
+
77
+ [MenuItem("Tools/Delta ECS/Create Entity", false, 31)]
78
+ private static void CreateEntityMenu()
79
+ {
80
+ Scene scene = SceneManager.GetActiveScene();
81
+ SceneAuthoring authoring = SceneAuthoring.GetOrCreateForScene(scene);
82
+ CreateEntity(authoring);
83
+ }
84
+
85
+ [MenuItem("Tools/Delta ECS/Create Entity", true)]
86
+ private static bool ValidateCreateEntityMenu() => !EditorApplication.isPlayingOrWillChangePlaymode;
84
87
  }
85
88
  }