com.artromskiy.deltaecs.unity 0.0.54 → 0.0.57
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 +8 -0
- package/Editor/BoundEntityRootEditor.cs +107 -104
- package/Editor/ComponentDropdown.cs +3 -0
- package/Editor/ComponentListController.cs +2 -1
- package/Editor/ComponentPropertyBagFields.cs +97 -93
- package/Editor/EditorLifecycle.cs +1 -0
- package/Editor/EntityInspectorTarget.cs +2 -2
- package/Editor/HierarchyMenu.cs +30 -27
- package/Editor/HierarchyNodeHandler.cs +156 -152
- package/Editor/HierarchySelection.cs +8 -5
- package/Editor/InspectorState.cs +16 -14
- package/Editor/SceneEntityInspectorView.cs +134 -131
- package/Editor/SelectionProxyBridge.cs +3 -0
- package/Editor/SelectionProxyEditor.cs +3 -2
- package/README.md +1 -1
- package/Runtime/ComponentData.cs +16 -14
- package/Runtime/EntityAuthoring.cs +1 -0
- package/Runtime/EntityContext.cs +7 -6
- package/Runtime/EntityReference.cs +1 -0
- package/Runtime/PropertyBagValueAccess.cs +6 -4
- package/Runtime/SceneAuthoring.cs +41 -40
- package/Runtime/SceneData.cs +1 -0
- package/Runtime/SceneWorld.cs +141 -139
- package/Runtime/SceneWorldExtensions.cs +2 -0
- package/Runtime/ThrowHelpers.cs +1 -0
- package/Runtime/ViewBindingSystem.cs +2 -0
- package/Runtime/ViewPrefabCatalog.cs +1 -0
- package/package.json +1 -1
package/Runtime/SceneWorld.cs
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
using System;
|
|
2
2
|
using System.Collections.Generic;
|
|
3
3
|
using System.Diagnostics.CodeAnalysis;
|
|
4
|
+
|
|
4
5
|
using Delta.ECS;
|
|
5
6
|
using Delta.ECS.Integration;
|
|
7
|
+
|
|
6
8
|
using UnityEngine;
|
|
7
9
|
using UnityEngine.SceneManagement;
|
|
8
10
|
|
|
@@ -30,92 +32,169 @@ namespace Delta.ECS.Unity
|
|
|
30
32
|
private bool _disposed;
|
|
31
33
|
|
|
32
34
|
public World World => _world;
|
|
35
|
+
|
|
36
|
+
public Entity[] AuthoredEntities
|
|
37
|
+
{
|
|
38
|
+
get
|
|
39
|
+
{
|
|
40
|
+
var entities = new Entity[_entitiesByStableId.Count];
|
|
41
|
+
_entitiesByStableId.Values.CopyTo(entities, 0);
|
|
42
|
+
return entities;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
33
45
|
internal IEcsWorld Integration => _integration;
|
|
34
46
|
internal SceneData SceneData => _sceneData;
|
|
35
47
|
internal Scene UnityScene => _authoring != null ? _authoring.gameObject.scene : default;
|
|
36
48
|
internal bool IsBound => !_disposed;
|
|
37
49
|
|
|
50
|
+
internal SceneWorld(World world, SceneData sceneData)
|
|
51
|
+
: this(world, sceneData, null, ownsWorld: false, registerLiveWorld: true)
|
|
52
|
+
{
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
private SceneWorld(World world, SceneData sceneData,
|
|
56
|
+
SceneAuthoring authoring, bool ownsWorld, bool registerLiveWorld)
|
|
57
|
+
{
|
|
58
|
+
_world = world ?? UnityThrowHelpers.ThrowArgumentNull<World>(nameof(world));
|
|
59
|
+
_sceneData = sceneData ?? UnityThrowHelpers.ThrowArgumentNull<SceneData>(nameof(sceneData));
|
|
60
|
+
_authoring = authoring;
|
|
61
|
+
_integration = world;
|
|
62
|
+
_ownsWorld = ownsWorld;
|
|
63
|
+
|
|
64
|
+
_sceneData.EnsureStableIds();
|
|
65
|
+
_integration.Initialize();
|
|
66
|
+
RebuildAuthoringEntities();
|
|
67
|
+
if (registerLiveWorld)
|
|
68
|
+
{
|
|
69
|
+
LiveWorlds.Add(this);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
38
73
|
/// <summary>Returns the integration-owned runtime context for a loaded Unity scene.</summary>
|
|
39
74
|
public static SceneWorld GetForScene(Scene scene) => SceneWorldRuntime.GetForScene(scene);
|
|
40
75
|
|
|
41
|
-
|
|
76
|
+
/// <summary>Resolves the live ECS world and entity currently associated with a Unity view.</summary>
|
|
77
|
+
public static bool TryGetBoundEntity(GameObject view, [NotNullWhen(true)] out World world, out Entity entity)
|
|
42
78
|
{
|
|
43
|
-
|
|
79
|
+
if (view != null && TryFindLiveWorld(view, out SceneWorld sceneWorld, out entity))
|
|
44
80
|
{
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
{
|
|
48
|
-
sceneWorld = candidate;
|
|
49
|
-
return true;
|
|
50
|
-
}
|
|
81
|
+
world = sceneWorld.World;
|
|
82
|
+
return true;
|
|
51
83
|
}
|
|
52
84
|
|
|
53
|
-
|
|
85
|
+
world = null;
|
|
86
|
+
entity = default;
|
|
54
87
|
return false;
|
|
55
88
|
}
|
|
56
89
|
|
|
57
|
-
|
|
90
|
+
/// <summary>Registers a transient runtime association; it is not written into scene data.</summary>
|
|
91
|
+
public bool BindView(Entity entity, GameObject view)
|
|
58
92
|
{
|
|
59
|
-
|
|
93
|
+
if (view == null || !_integration.IsAlive(entity))
|
|
60
94
|
{
|
|
61
|
-
|
|
62
|
-
if (!candidate._disposed && candidate.TryGetEntity(view, out entity))
|
|
63
|
-
{
|
|
64
|
-
sceneWorld = candidate;
|
|
65
|
-
return true;
|
|
66
|
-
}
|
|
95
|
+
return false;
|
|
67
96
|
}
|
|
68
97
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
98
|
+
UnityEngine.EntityId viewId = view.GetEntityId();
|
|
99
|
+
if (_entitiesByView.TryGetValue(viewId, out Entity previousEntity))
|
|
100
|
+
{
|
|
101
|
+
_viewsByEntity.Remove(previousEntity);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (_viewsByEntity.TryGetValue(entity, out GameObject previousView) && previousView != null)
|
|
105
|
+
{
|
|
106
|
+
_entitiesByView.Remove(previousView.GetEntityId());
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
_viewsByEntity[entity] = view;
|
|
110
|
+
_entitiesByView[viewId] = entity;
|
|
111
|
+
return true;
|
|
72
112
|
}
|
|
73
113
|
|
|
74
|
-
|
|
75
|
-
public static bool TryGetBoundEntity(GameObject view, [NotNullWhen(true)] out World world, out Entity entity)
|
|
114
|
+
public void UnbindView(Entity entity)
|
|
76
115
|
{
|
|
77
|
-
if (
|
|
116
|
+
if (_viewsByEntity.Remove(entity, out GameObject view) && view != null)
|
|
78
117
|
{
|
|
79
|
-
|
|
80
|
-
|
|
118
|
+
_entitiesByView.Remove(view.GetEntityId());
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
public bool TryFindFirstEntity<T>(out Entity entity) where T : struct
|
|
123
|
+
{
|
|
124
|
+
if (_world.Components.TryGetPrimary(typeof(T), out ComponentId componentId))
|
|
125
|
+
{
|
|
126
|
+
foreach (Entity candidate in _entitiesByStableId.Values)
|
|
127
|
+
{
|
|
128
|
+
if (_integration.IsAlive(candidate) && _world.Has(candidate, componentId))
|
|
129
|
+
{
|
|
130
|
+
entity = candidate;
|
|
131
|
+
return true;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
81
134
|
}
|
|
82
135
|
|
|
83
|
-
world = null;
|
|
84
136
|
entity = default;
|
|
85
137
|
return false;
|
|
86
138
|
}
|
|
87
139
|
|
|
88
|
-
public Entity
|
|
140
|
+
public bool HasComponent<T>(Entity entity) where T : struct =>
|
|
141
|
+
_world.IsAlive(entity)
|
|
142
|
+
&& _world.Components.TryGetPrimary(typeof(T), out ComponentId componentId)
|
|
143
|
+
&& _world.Has(entity, componentId);
|
|
144
|
+
|
|
145
|
+
public void Dispose()
|
|
89
146
|
{
|
|
90
|
-
|
|
147
|
+
if (_disposed)
|
|
91
148
|
{
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
_disposed = true;
|
|
153
|
+
LiveWorlds.Remove(this);
|
|
154
|
+
DestroyCurrentAuthoringEntities();
|
|
155
|
+
_entitiesByStableId.Clear();
|
|
156
|
+
_stableIdsByEntity.Clear();
|
|
157
|
+
_viewsByEntity.Clear();
|
|
158
|
+
_entitiesByView.Clear();
|
|
159
|
+
_integration.Shutdown();
|
|
160
|
+
|
|
161
|
+
if (_ownsWorld)
|
|
162
|
+
{
|
|
163
|
+
_world.Dispose();
|
|
95
164
|
}
|
|
96
165
|
}
|
|
97
166
|
|
|
98
|
-
internal
|
|
99
|
-
: this(world, sceneData, null, ownsWorld: false, registerLiveWorld: true)
|
|
167
|
+
internal static bool TryFindLiveWorld(SceneData sceneData, out SceneWorld sceneWorld)
|
|
100
168
|
{
|
|
169
|
+
for (int i = LiveWorlds.Count - 1; i >= 0; i--)
|
|
170
|
+
{
|
|
171
|
+
SceneWorld candidate = LiveWorlds[i];
|
|
172
|
+
if (!candidate._disposed && ReferenceEquals(candidate._sceneData, sceneData))
|
|
173
|
+
{
|
|
174
|
+
sceneWorld = candidate;
|
|
175
|
+
return true;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
sceneWorld = null;
|
|
180
|
+
return false;
|
|
101
181
|
}
|
|
102
182
|
|
|
103
|
-
|
|
104
|
-
SceneAuthoring authoring, bool ownsWorld, bool registerLiveWorld)
|
|
183
|
+
internal static bool TryFindLiveWorld(GameObject view, out SceneWorld sceneWorld, out Entity entity)
|
|
105
184
|
{
|
|
106
|
-
|
|
107
|
-
_sceneData = sceneData ?? UnityThrowHelpers.ThrowArgumentNull<SceneData>(nameof(sceneData));
|
|
108
|
-
_authoring = authoring;
|
|
109
|
-
_integration = world;
|
|
110
|
-
_ownsWorld = ownsWorld;
|
|
111
|
-
|
|
112
|
-
_sceneData.EnsureStableIds();
|
|
113
|
-
_integration.Initialize();
|
|
114
|
-
RebuildAuthoringEntities();
|
|
115
|
-
if (registerLiveWorld)
|
|
185
|
+
for (int i = LiveWorlds.Count - 1; i >= 0; i--)
|
|
116
186
|
{
|
|
117
|
-
LiveWorlds
|
|
187
|
+
SceneWorld candidate = LiveWorlds[i];
|
|
188
|
+
if (!candidate._disposed && candidate.TryGetEntity(view, out entity))
|
|
189
|
+
{
|
|
190
|
+
sceneWorld = candidate;
|
|
191
|
+
return true;
|
|
192
|
+
}
|
|
118
193
|
}
|
|
194
|
+
|
|
195
|
+
sceneWorld = null;
|
|
196
|
+
entity = default;
|
|
197
|
+
return false;
|
|
119
198
|
}
|
|
120
199
|
|
|
121
200
|
internal static SceneWorld CreatePreview(SceneData sceneData)
|
|
@@ -173,17 +252,6 @@ namespace Delta.ECS.Unity
|
|
|
173
252
|
}
|
|
174
253
|
}
|
|
175
254
|
|
|
176
|
-
private static World CreateWorld(int initialEntityCapacity)
|
|
177
|
-
{
|
|
178
|
-
var layouts = new ComponentRegistry();
|
|
179
|
-
foreach (IGeneratedComponentRegistration registration in GeneratedComponentCatalog.GetRegistrations())
|
|
180
|
-
{
|
|
181
|
-
layouts.Register(registration);
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
return new World(layouts, initialEntityCapacity);
|
|
185
|
-
}
|
|
186
|
-
|
|
187
255
|
internal void RebuildAuthoringEntities()
|
|
188
256
|
{
|
|
189
257
|
ThrowIfDisposed();
|
|
@@ -315,38 +383,6 @@ namespace Delta.ECS.Unity
|
|
|
315
383
|
return false;
|
|
316
384
|
}
|
|
317
385
|
|
|
318
|
-
/// <summary>Registers a transient runtime association; it is not written into scene data.</summary>
|
|
319
|
-
public bool BindView(Entity entity, GameObject view)
|
|
320
|
-
{
|
|
321
|
-
if (view == null || !_integration.IsAlive(entity))
|
|
322
|
-
{
|
|
323
|
-
return false;
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
UnityEngine.EntityId viewId = view.GetEntityId();
|
|
327
|
-
if (_entitiesByView.TryGetValue(viewId, out Entity previousEntity))
|
|
328
|
-
{
|
|
329
|
-
_viewsByEntity.Remove(previousEntity);
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
if (_viewsByEntity.TryGetValue(entity, out GameObject previousView) && previousView != null)
|
|
333
|
-
{
|
|
334
|
-
_entitiesByView.Remove(previousView.GetEntityId());
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
_viewsByEntity[entity] = view;
|
|
338
|
-
_entitiesByView[viewId] = entity;
|
|
339
|
-
return true;
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
public void UnbindView(Entity entity)
|
|
343
|
-
{
|
|
344
|
-
if (_viewsByEntity.Remove(entity, out GameObject view) && view != null)
|
|
345
|
-
{
|
|
346
|
-
_entitiesByView.Remove(view.GetEntityId());
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
|
|
350
386
|
internal bool TryGetDescriptor(ComponentData data, out ComponentDescriptor descriptor)
|
|
351
387
|
{
|
|
352
388
|
descriptor = default;
|
|
@@ -514,29 +550,6 @@ namespace Delta.ECS.Unity
|
|
|
514
550
|
&& _integration.Remove(entity, new[] { descriptor.Id });
|
|
515
551
|
}
|
|
516
552
|
|
|
517
|
-
public bool TryFindFirstEntity<T>(out Entity entity) where T : struct
|
|
518
|
-
{
|
|
519
|
-
if (_world.Components.TryGetPrimary(typeof(T), out ComponentId componentId))
|
|
520
|
-
{
|
|
521
|
-
foreach (Entity candidate in _entitiesByStableId.Values)
|
|
522
|
-
{
|
|
523
|
-
if (_integration.IsAlive(candidate) && _world.Has(candidate, componentId))
|
|
524
|
-
{
|
|
525
|
-
entity = candidate;
|
|
526
|
-
return true;
|
|
527
|
-
}
|
|
528
|
-
}
|
|
529
|
-
}
|
|
530
|
-
|
|
531
|
-
entity = default;
|
|
532
|
-
return false;
|
|
533
|
-
}
|
|
534
|
-
|
|
535
|
-
public bool HasComponent<T>(Entity entity) where T : struct =>
|
|
536
|
-
_world.IsAlive(entity)
|
|
537
|
-
&& _world.Components.TryGetPrimary(typeof(T), out ComponentId componentId)
|
|
538
|
-
&& _world.Has(entity, componentId);
|
|
539
|
-
|
|
540
553
|
internal bool TryGetAuthoring(string stableId, out EntityAuthoring authoring)
|
|
541
554
|
{
|
|
542
555
|
IList<EntityAuthoring> entities = _sceneData.Entities;
|
|
@@ -554,26 +567,15 @@ namespace Delta.ECS.Unity
|
|
|
554
567
|
return false;
|
|
555
568
|
}
|
|
556
569
|
|
|
557
|
-
|
|
570
|
+
private static World CreateWorld(int initialEntityCapacity)
|
|
558
571
|
{
|
|
559
|
-
|
|
572
|
+
var layouts = new ComponentRegistry();
|
|
573
|
+
foreach (IGeneratedComponentRegistration registration in GeneratedComponentCatalog.GetRegistrations())
|
|
560
574
|
{
|
|
561
|
-
|
|
575
|
+
layouts.Register(registration);
|
|
562
576
|
}
|
|
563
577
|
|
|
564
|
-
|
|
565
|
-
LiveWorlds.Remove(this);
|
|
566
|
-
DestroyCurrentAuthoringEntities();
|
|
567
|
-
_entitiesByStableId.Clear();
|
|
568
|
-
_stableIdsByEntity.Clear();
|
|
569
|
-
_viewsByEntity.Clear();
|
|
570
|
-
_entitiesByView.Clear();
|
|
571
|
-
_integration.Shutdown();
|
|
572
|
-
|
|
573
|
-
if (_ownsWorld)
|
|
574
|
-
{
|
|
575
|
-
_world.Dispose();
|
|
576
|
-
}
|
|
578
|
+
return new World(layouts, initialEntityCapacity);
|
|
577
579
|
}
|
|
578
580
|
|
|
579
581
|
private void DestroyCurrentAuthoringEntities()
|
|
@@ -605,6 +607,17 @@ namespace Delta.ECS.Unity
|
|
|
605
607
|
private static readonly Dictionary<Scene, SceneWorld> WorldsByScene = new();
|
|
606
608
|
private static bool _initialized;
|
|
607
609
|
|
|
610
|
+
internal static SceneWorld GetForScene(Scene scene)
|
|
611
|
+
{
|
|
612
|
+
if (!Application.isPlaying)
|
|
613
|
+
{
|
|
614
|
+
UnityThrowHelpers.ThrowInvalidOperation("Runtime scene worlds are only available in Play Mode.");
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
EnsureInitialized();
|
|
618
|
+
return EnsureForScene(scene);
|
|
619
|
+
}
|
|
620
|
+
|
|
608
621
|
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
|
|
609
622
|
private static void ResetForPlaySession()
|
|
610
623
|
{
|
|
@@ -621,17 +634,6 @@ namespace Delta.ECS.Unity
|
|
|
621
634
|
}
|
|
622
635
|
}
|
|
623
636
|
|
|
624
|
-
internal static SceneWorld GetForScene(Scene scene)
|
|
625
|
-
{
|
|
626
|
-
if (!Application.isPlaying)
|
|
627
|
-
{
|
|
628
|
-
UnityThrowHelpers.ThrowInvalidOperation("Runtime scene worlds are only available in Play Mode.");
|
|
629
|
-
}
|
|
630
|
-
|
|
631
|
-
EnsureInitialized();
|
|
632
|
-
return EnsureForScene(scene);
|
|
633
|
-
}
|
|
634
|
-
|
|
635
637
|
private static void EnsureInitialized()
|
|
636
638
|
{
|
|
637
639
|
if (_initialized)
|
package/Runtime/ThrowHelpers.cs
CHANGED