com.artromskiy.deltaecs.unity 0.0.62 → 0.0.64
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/ComponentDropdown.cs +8 -10
- package/Editor/ComponentPropertyBagFields.cs +2 -3
- package/Editor/SceneEntityInspectorView.cs +152 -149
- package/README.md +1 -1
- package/Runtime/ComponentData.cs +5 -6
- package/Runtime/SceneWorld.cs +53 -114
- package/Runtime/ViewComponents.cs +6 -6
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,8 +3,6 @@ using System.Collections.Generic;
|
|
|
3
3
|
using System.Linq;
|
|
4
4
|
using System.Reflection;
|
|
5
5
|
|
|
6
|
-
using Delta.ECS.Integration;
|
|
7
|
-
|
|
8
6
|
using UnityEditor.IMGUI.Controls;
|
|
9
7
|
|
|
10
8
|
using UnityEngine;
|
|
@@ -13,13 +11,13 @@ namespace Delta.ECS.Unity.Editor
|
|
|
13
11
|
{
|
|
14
12
|
internal sealed class ComponentDropdown : AdvancedDropdown
|
|
15
13
|
{
|
|
16
|
-
private readonly
|
|
17
|
-
private readonly Func<
|
|
18
|
-
private readonly Action<
|
|
19
|
-
private readonly Dictionary<int,
|
|
14
|
+
private readonly ComponentId[] _components;
|
|
15
|
+
private readonly Func<ComponentId, string> _getMenuPath;
|
|
16
|
+
private readonly Action<ComponentId> _add;
|
|
17
|
+
private readonly Dictionary<int, ComponentId> _items = new();
|
|
20
18
|
|
|
21
|
-
public ComponentDropdown(
|
|
22
|
-
Func<
|
|
19
|
+
public ComponentDropdown(ComponentId[] components,
|
|
20
|
+
Func<ComponentId, string> getMenuPath, Action<ComponentId> add)
|
|
23
21
|
: base(new AdvancedDropdownState())
|
|
24
22
|
{
|
|
25
23
|
_components = components;
|
|
@@ -67,9 +65,9 @@ namespace Delta.ECS.Unity.Editor
|
|
|
67
65
|
|
|
68
66
|
protected override void ItemSelected(AdvancedDropdownItem item)
|
|
69
67
|
{
|
|
70
|
-
if (_items.TryGetValue(item.id, out
|
|
68
|
+
if (_items.TryGetValue(item.id, out ComponentId componentId))
|
|
71
69
|
{
|
|
72
|
-
_add(
|
|
70
|
+
_add(componentId);
|
|
73
71
|
}
|
|
74
72
|
}
|
|
75
73
|
}
|
|
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
|
|
3
3
|
|
|
4
4
|
using Delta;
|
|
5
5
|
using Delta.ECS;
|
|
6
|
-
using Delta.ECS.Integration;
|
|
7
6
|
using Delta.ECS.Unity;
|
|
8
7
|
|
|
9
8
|
using Unity.Properties;
|
|
@@ -19,7 +18,7 @@ namespace Delta.ECS.Unity.Editor
|
|
|
19
18
|
|
|
20
19
|
internal static class ComponentPropertyBagFields
|
|
21
20
|
{
|
|
22
|
-
internal static ComponentPropertyBinding[] Build(VisualElement parent,
|
|
21
|
+
internal static ComponentPropertyBinding[] Build(VisualElement parent, Type componentType,
|
|
23
22
|
object value, bool canWrite, Action<string[], object> onChanged,
|
|
24
23
|
Func<string, Entity, Action<object>, VisualElement> createEntityField)
|
|
25
24
|
{
|
|
@@ -28,7 +27,7 @@ namespace Delta.ECS.Unity.Editor
|
|
|
28
27
|
return Array.Empty<ComponentPropertyBinding>();
|
|
29
28
|
}
|
|
30
29
|
|
|
31
|
-
IPropertyBag propertyBag = PropertyBag.GetPropertyBag(
|
|
30
|
+
IPropertyBag propertyBag = PropertyBag.GetPropertyBag(componentType);
|
|
32
31
|
if (propertyBag == null)
|
|
33
32
|
{
|
|
34
33
|
return Array.Empty<ComponentPropertyBinding>();
|
|
@@ -4,7 +4,6 @@ using System.Linq;
|
|
|
4
4
|
|
|
5
5
|
using Delta;
|
|
6
6
|
using Delta.ECS;
|
|
7
|
-
using Delta.ECS.Integration;
|
|
8
7
|
|
|
9
8
|
using UnityEditor;
|
|
10
9
|
using UnityEditor.UIElements;
|
|
@@ -35,6 +34,8 @@ namespace Delta.ECS.Unity.Editor
|
|
|
35
34
|
internal int ComponentCount => _componentEntries.Count;
|
|
36
35
|
private SceneAuthoring Authoring => _target.Authoring;
|
|
37
36
|
|
|
37
|
+
private ComponentRegistry Components => (_target.IsRuntime ? _target.RuntimeWorld : _previewWorld).World.Components;
|
|
38
|
+
|
|
38
39
|
public SceneEntityInspectorView(SelectionProxy proxy)
|
|
39
40
|
: this(() => proxy != null ? proxy.Target : default)
|
|
40
41
|
{
|
|
@@ -191,22 +192,6 @@ namespace Delta.ECS.Unity.Editor
|
|
|
191
192
|
|
|
192
193
|
private static Label CreateEntityIcon() => CreateClassLabel("◆", "ecs-entity-icon");
|
|
193
194
|
|
|
194
|
-
private static ComponentDescriptor? TryGetDescriptor(ComponentData data,
|
|
195
|
-
IReadOnlyDictionary<ulong, ComponentDescriptor> descriptors)
|
|
196
|
-
{
|
|
197
|
-
ulong? schema = GetSchemaId(data);
|
|
198
|
-
return schema.HasValue && descriptors.TryGetValue(schema.Value, out ComponentDescriptor descriptor)
|
|
199
|
-
? descriptor
|
|
200
|
-
: null;
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
private static string GetComponentMenuPath(ComponentDescriptor descriptor)
|
|
204
|
-
{
|
|
205
|
-
string namespacePath = descriptor.ValueType.Namespace?.Replace('.', '/') ?? string.Empty;
|
|
206
|
-
string shortName = GetShortTypeName(descriptor.ValueType);
|
|
207
|
-
return string.IsNullOrEmpty(namespacePath) ? shortName : $"{namespacePath}/{shortName}";
|
|
208
|
-
}
|
|
209
|
-
|
|
210
195
|
private static string GetShortTypeName(Type type)
|
|
211
196
|
{
|
|
212
197
|
string name = type.Name;
|
|
@@ -228,6 +213,16 @@ namespace Delta.ECS.Unity.Editor
|
|
|
228
213
|
private static int GetComponentOrder(ulong schema) =>
|
|
229
214
|
InspectorState.instance.GetComponentOrder(schema);
|
|
230
215
|
|
|
216
|
+
private ComponentId? TryGetComponentId(ComponentData data)
|
|
217
|
+
=> _previewWorld.TryGetComponentId(data, out ComponentId componentId) ? componentId : null;
|
|
218
|
+
|
|
219
|
+
private string GetComponentMenuPath(ComponentId componentId)
|
|
220
|
+
{
|
|
221
|
+
string namespacePath = Components.GetComponentType(componentId).Namespace?.Replace('.', '/') ?? string.Empty;
|
|
222
|
+
string shortName = GetShortTypeName(Components.GetComponentType(componentId));
|
|
223
|
+
return string.IsNullOrEmpty(namespacePath) ? shortName : $"{namespacePath}/{shortName}";
|
|
224
|
+
}
|
|
225
|
+
|
|
231
226
|
private void OnEntitySelectionChanged()
|
|
232
227
|
{
|
|
233
228
|
SyncSelection();
|
|
@@ -414,26 +409,26 @@ namespace Delta.ECS.Unity.Editor
|
|
|
414
409
|
});
|
|
415
410
|
}
|
|
416
411
|
|
|
417
|
-
private VisualElement BuildAuthoringComponentCard(EntityAuthoring authoring, ComponentData data,
|
|
412
|
+
private VisualElement BuildAuthoringComponentCard(EntityAuthoring authoring, ComponentData data, ComponentId componentId)
|
|
418
413
|
{
|
|
419
|
-
return BuildComponentCard(
|
|
414
|
+
return BuildComponentCard(componentId, body =>
|
|
420
415
|
{
|
|
421
|
-
if (
|
|
416
|
+
if (Components.IsTag(componentId))
|
|
422
417
|
{
|
|
423
418
|
body.Add(CreateClassLabel("Tag · membership only", "ecs-empty-component"));
|
|
424
419
|
return;
|
|
425
420
|
}
|
|
426
421
|
|
|
427
|
-
if (!_previewWorld.TryRead(authoring,
|
|
422
|
+
if (!_previewWorld.TryRead(authoring, componentId, out object value))
|
|
428
423
|
{
|
|
429
|
-
body.Add(new HelpBox(
|
|
424
|
+
body.Add(new HelpBox("Could not read component.", HelpBoxMessageType.Error));
|
|
430
425
|
return;
|
|
431
426
|
}
|
|
432
427
|
|
|
433
|
-
DrawEditableValue(body, authoring, data,
|
|
428
|
+
DrawEditableValue(body, authoring, data, componentId, value);
|
|
434
429
|
},
|
|
435
|
-
|
|
436
|
-
() => RemoveComponent(authoring, data,
|
|
430
|
+
Components.IsTag(componentId) ? null : () => ResetComponent(authoring, data, componentId),
|
|
431
|
+
() => RemoveComponent(authoring, data, componentId));
|
|
437
432
|
}
|
|
438
433
|
|
|
439
434
|
private VisualElement BuildUnknownComponentCard(EntityAuthoring authoring, ComponentData data)
|
|
@@ -462,23 +457,22 @@ namespace Delta.ECS.Unity.Editor
|
|
|
462
457
|
.Where(schema => schema.HasValue)
|
|
463
458
|
.Select(schema => schema.Value)
|
|
464
459
|
.ToHashSet();
|
|
465
|
-
|
|
466
|
-
_previewWorld.
|
|
467
|
-
|
|
468
|
-
&& !existingSchemas.Contains(descriptor.Schema.Value));
|
|
460
|
+
ComponentId[] available = Array.FindAll(
|
|
461
|
+
_previewWorld.World.Components.GetComponentIds().ToArray(),
|
|
462
|
+
componentId => !existingSchemas.Contains(Components.GetSchemaId(componentId).Value));
|
|
469
463
|
button.SetEnabled(available.Length != 0);
|
|
470
464
|
button.clicked += () => new ComponentDropdown(available, GetComponentMenuPath,
|
|
471
|
-
|
|
465
|
+
componentId => AddComponent(authoring, componentId))
|
|
472
466
|
.Show(button.worldBound);
|
|
473
467
|
return button;
|
|
474
468
|
}
|
|
475
469
|
|
|
476
|
-
private VisualElement BuildComponentCard(
|
|
470
|
+
private VisualElement BuildComponentCard(ComponentId componentId, Action<VisualElement> buildBody,
|
|
477
471
|
Action resetComponent = null, Action removeComponent = null)
|
|
478
472
|
{
|
|
479
|
-
bool expanded = IsComponentExpanded(
|
|
480
|
-
return BuildComponentFoldout(GetShortTypeName(
|
|
481
|
-
header => AddComponentActions(header,
|
|
473
|
+
bool expanded = IsComponentExpanded(Components.GetSchemaId(componentId).Value);
|
|
474
|
+
return BuildComponentFoldout(GetShortTypeName(Components.GetComponentType(componentId)), Components.GetSchemaId(componentId).Value, expanded, buildBody,
|
|
475
|
+
header => AddComponentActions(header, componentId, resetComponent, removeComponent));
|
|
482
476
|
}
|
|
483
477
|
|
|
484
478
|
private Foldout BuildComponentFoldout(string title, ulong? schema, bool expanded,
|
|
@@ -517,19 +511,19 @@ namespace Delta.ECS.Unity.Editor
|
|
|
517
511
|
body.Clear();
|
|
518
512
|
if (schema.HasValue)
|
|
519
513
|
{
|
|
520
|
-
_runtimeBindings.RemoveAll(binding => binding.
|
|
514
|
+
_runtimeBindings.RemoveAll(binding => Components.GetSchemaId(binding.Component).Value == schema.Value);
|
|
521
515
|
}
|
|
522
516
|
}
|
|
523
517
|
});
|
|
524
518
|
return foldout;
|
|
525
519
|
}
|
|
526
520
|
|
|
527
|
-
private void AddComponentActions(Toggle header,
|
|
521
|
+
private void AddComponentActions(Toggle header, ComponentId componentId,
|
|
528
522
|
Action resetComponent, Action removeComponent)
|
|
529
523
|
{
|
|
530
524
|
var actions = CreateComponentMenu();
|
|
531
|
-
actions.menu.AppendAction("Move Up", _ => MoveComponent(
|
|
532
|
-
actions.menu.AppendAction("Move Down", _ => MoveComponent(
|
|
525
|
+
actions.menu.AppendAction("Move Up", _ => MoveComponent(Components.GetSchemaId(componentId).Value, -1));
|
|
526
|
+
actions.menu.AppendAction("Move Down", _ => MoveComponent(Components.GetSchemaId(componentId).Value, 1));
|
|
533
527
|
if (resetComponent != null || removeComponent != null)
|
|
534
528
|
{
|
|
535
529
|
actions.menu.AppendSeparator();
|
|
@@ -545,33 +539,31 @@ namespace Delta.ECS.Unity.Editor
|
|
|
545
539
|
}
|
|
546
540
|
|
|
547
541
|
private void DrawEditableValue(VisualElement body, EntityAuthoring authoring, ComponentData data,
|
|
548
|
-
|
|
542
|
+
ComponentId componentId, object value)
|
|
549
543
|
{
|
|
550
|
-
bool canWrite = (descriptor.Capabilities & ComponentCapabilities.Write) != 0
|
|
551
|
-
&& descriptor.ValueType.IsValueType;
|
|
552
544
|
int previousChildCount = body.childCount;
|
|
553
|
-
ComponentPropertyBinding[] bindings = ComponentPropertyBagFields.Build(body,
|
|
554
|
-
|
|
545
|
+
ComponentPropertyBinding[] bindings = ComponentPropertyBagFields.Build(body, Components.GetComponentType(componentId), value,
|
|
546
|
+
true,
|
|
555
547
|
(path, next) =>
|
|
556
548
|
{
|
|
557
549
|
object updated = value;
|
|
558
|
-
if (!PropertyBagValueAccess.TrySetValue(ref updated,
|
|
550
|
+
if (!PropertyBagValueAccess.TrySetValue(ref updated, Components.GetComponentType(componentId), path, next))
|
|
559
551
|
{
|
|
560
|
-
Debug.LogWarning($"Could not edit a property on {
|
|
552
|
+
Debug.LogWarning($"Could not edit a property on {Components.GetComponentType(componentId).FullName ?? Components.GetComponentType(componentId).Name}: the property path is unavailable.", Authoring);
|
|
561
553
|
RefreshContent();
|
|
562
554
|
return;
|
|
563
555
|
}
|
|
564
556
|
|
|
565
557
|
if (Equals(updated, value)) return;
|
|
566
|
-
Undo.RecordObject(Authoring, $"Edit {
|
|
567
|
-
if (_previewWorld.TryWrite(authoring, data,
|
|
558
|
+
Undo.RecordObject(Authoring, $"Edit {Components.GetComponentType(componentId).FullName ?? Components.GetComponentType(componentId).Name}");
|
|
559
|
+
if (_previewWorld.TryWrite(authoring, data, componentId, updated))
|
|
568
560
|
{
|
|
569
561
|
value = updated;
|
|
570
562
|
MarkSceneDirty();
|
|
571
563
|
}
|
|
572
564
|
else
|
|
573
565
|
{
|
|
574
|
-
Debug.LogError($"Could not write {
|
|
566
|
+
Debug.LogError($"Could not write {Components.GetComponentType(componentId).FullName ?? Components.GetComponentType(componentId).Name}.", Authoring);
|
|
575
567
|
RefreshContent();
|
|
576
568
|
}
|
|
577
569
|
},
|
|
@@ -618,47 +610,54 @@ namespace Delta.ECS.Unity.Editor
|
|
|
618
610
|
private void BuildRuntimeEntity()
|
|
619
611
|
{
|
|
620
612
|
_runtimeBindings.Clear();
|
|
621
|
-
SceneWorld
|
|
613
|
+
SceneWorld sceneWorld = _target.RuntimeWorld;
|
|
622
614
|
Entity entity = _target.RuntimeEntity;
|
|
623
|
-
if (
|
|
615
|
+
if (sceneWorld == null || !sceneWorld.IsBound)
|
|
624
616
|
{
|
|
625
617
|
_header.Add(new HelpBox("The selected runtime entity is no longer alive.", HelpBoxMessageType.Warning));
|
|
626
618
|
return;
|
|
627
619
|
}
|
|
628
620
|
|
|
629
|
-
|
|
630
|
-
|
|
621
|
+
World world = sceneWorld.World;
|
|
622
|
+
if (!world.IsAlive(entity))
|
|
623
|
+
{
|
|
624
|
+
_header.Add(new HelpBox("The selected runtime entity is no longer alive.", HelpBoxMessageType.Warning));
|
|
625
|
+
return;
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
_header.Add(BuildRuntimeHeader(sceneWorld, entity));
|
|
629
|
+
ComponentId[] components = ProjectRuntimeComponents(sceneWorld, entity);
|
|
631
630
|
if (components == null)
|
|
632
631
|
{
|
|
633
632
|
_header.Add(new HelpBox("Could not read the selected entity's components.", HelpBoxMessageType.Error));
|
|
634
633
|
return;
|
|
635
634
|
}
|
|
636
635
|
|
|
637
|
-
foreach (
|
|
636
|
+
foreach (ComponentId componentId in components)
|
|
638
637
|
{
|
|
639
|
-
_componentEntries.Add(new ComponentEntry(null,
|
|
638
|
+
_componentEntries.Add(new ComponentEntry(null, componentId));
|
|
640
639
|
}
|
|
641
640
|
|
|
642
641
|
RenderComponentRows();
|
|
643
642
|
}
|
|
644
643
|
|
|
645
|
-
private VisualElement BuildRuntimeComponentCard(SceneWorld world, Entity entity,
|
|
644
|
+
private VisualElement BuildRuntimeComponentCard(SceneWorld world, Entity entity, ComponentId componentId)
|
|
646
645
|
{
|
|
647
|
-
return BuildComponentCard(
|
|
646
|
+
return BuildComponentCard(componentId, body =>
|
|
648
647
|
{
|
|
649
|
-
if (
|
|
648
|
+
if (Components.IsTag(componentId))
|
|
650
649
|
{
|
|
651
650
|
body.Add(CreateClassLabel("Tag · membership only", "ecs-empty-component"));
|
|
652
651
|
return;
|
|
653
652
|
}
|
|
654
653
|
|
|
655
|
-
if (!world.TryRead(entity,
|
|
654
|
+
if (!world.TryRead(entity, componentId, out object value))
|
|
656
655
|
{
|
|
657
|
-
body.Add(new HelpBox(
|
|
656
|
+
body.Add(new HelpBox("Could not read component.", HelpBoxMessageType.Error));
|
|
658
657
|
return;
|
|
659
658
|
}
|
|
660
659
|
|
|
661
|
-
DrawRuntimeValue(body, world, entity,
|
|
660
|
+
DrawRuntimeValue(body, world, entity, componentId, value);
|
|
662
661
|
});
|
|
663
662
|
}
|
|
664
663
|
|
|
@@ -679,9 +678,9 @@ namespace Delta.ECS.Unity.Editor
|
|
|
679
678
|
row.EnableInClassList("ecs-component-row", true);
|
|
680
679
|
row.userData = entry;
|
|
681
680
|
row.Add(_target.IsRuntime
|
|
682
|
-
? BuildRuntimeComponentCard(_target.RuntimeWorld, _target.RuntimeEntity, entry.
|
|
683
|
-
: entry.
|
|
684
|
-
? BuildAuthoringComponentCard(_authoringEntity, entry.Data, entry.
|
|
681
|
+
? BuildRuntimeComponentCard(_target.RuntimeWorld, _target.RuntimeEntity, entry.Component.Value)
|
|
682
|
+
: entry.Component.HasValue
|
|
683
|
+
? BuildAuthoringComponentCard(_authoringEntity, entry.Data, entry.Component.Value)
|
|
685
684
|
: BuildUnknownComponentCard(_authoringEntity, entry.Data));
|
|
686
685
|
}
|
|
687
686
|
|
|
@@ -701,8 +700,8 @@ namespace Delta.ECS.Unity.Editor
|
|
|
701
700
|
|
|
702
701
|
private void UnbindComponentItem(VisualElement row, int index)
|
|
703
702
|
{
|
|
704
|
-
if (row.userData is ComponentEntry entry && entry.
|
|
705
|
-
_runtimeBindings.RemoveAll(binding => binding.
|
|
703
|
+
if (row.userData is ComponentEntry entry && entry.Component.HasValue)
|
|
704
|
+
_runtimeBindings.RemoveAll(binding => Components.GetSchemaId(binding.Component) == Components.GetSchemaId(entry.Component.Value));
|
|
706
705
|
row.userData = null;
|
|
707
706
|
row.Clear();
|
|
708
707
|
}
|
|
@@ -721,8 +720,8 @@ namespace Delta.ECS.Unity.Editor
|
|
|
721
720
|
List<ulong> componentOrder = state.GetComponentOrderSnapshot();
|
|
722
721
|
|
|
723
722
|
ulong[] visibleOrder = _componentEntries
|
|
724
|
-
.Select(entry => entry.
|
|
725
|
-
? (ulong?)entry.
|
|
723
|
+
.Select(entry => entry.Component.HasValue
|
|
724
|
+
? (ulong?)Components.GetSchemaId(entry.Component.Value).Value
|
|
726
725
|
: GetSchemaId(entry.Data))
|
|
727
726
|
.Where(schema => schema.HasValue)
|
|
728
727
|
.Select(schema => schema.Value)
|
|
@@ -730,17 +729,17 @@ namespace Delta.ECS.Unity.Editor
|
|
|
730
729
|
.ToArray();
|
|
731
730
|
HashSet<ulong> visibleSchemas = visibleOrder.ToHashSet();
|
|
732
731
|
|
|
733
|
-
IEnumerable<
|
|
734
|
-
? _previewWorld.
|
|
732
|
+
IEnumerable<ComponentId> catalog = _previewWorld != null
|
|
733
|
+
? _previewWorld.World.Components.GetComponentIds().ToArray()
|
|
735
734
|
: _target.RuntimeWorld != null && _target.RuntimeWorld.IsBound
|
|
736
|
-
? _target.RuntimeWorld.
|
|
737
|
-
: Array.Empty<
|
|
738
|
-
foreach (
|
|
739
|
-
.OrderBy(
|
|
735
|
+
? _target.RuntimeWorld.World.Components.GetComponentIds().ToArray()
|
|
736
|
+
: Array.Empty<ComponentId>();
|
|
737
|
+
foreach (ComponentId componentId in catalog
|
|
738
|
+
.OrderBy(componentId => GetShortTypeName(Components.GetComponentType(componentId)), StringComparer.Ordinal))
|
|
740
739
|
{
|
|
741
|
-
if (!componentOrder.Contains(
|
|
740
|
+
if (!componentOrder.Contains(Components.GetSchemaId(componentId).Value))
|
|
742
741
|
{
|
|
743
|
-
componentOrder.Add(
|
|
742
|
+
componentOrder.Add(Components.GetSchemaId(componentId).Value);
|
|
744
743
|
}
|
|
745
744
|
}
|
|
746
745
|
|
|
@@ -764,9 +763,9 @@ namespace Delta.ECS.Unity.Editor
|
|
|
764
763
|
state.SetComponentOrder(componentOrder);
|
|
765
764
|
}
|
|
766
765
|
|
|
767
|
-
private
|
|
766
|
+
private ComponentId[] ProjectRuntimeComponents(SceneWorld world, Entity entity)
|
|
768
767
|
{
|
|
769
|
-
|
|
768
|
+
ReadOnlySpan<ComponentId> catalog = world.World.Components.GetComponentIds();
|
|
770
769
|
_runtimeComponentBuffer = new ComponentId[catalog.Length];
|
|
771
770
|
if (!world.TryGetComponents(entity, _runtimeComponentBuffer, out int count))
|
|
772
771
|
{
|
|
@@ -776,19 +775,14 @@ namespace Delta.ECS.Unity.Editor
|
|
|
776
775
|
|
|
777
776
|
_runtimeComponentIds = new ComponentId[count];
|
|
778
777
|
Array.Copy(_runtimeComponentBuffer, _runtimeComponentIds, count);
|
|
779
|
-
|
|
780
|
-
.ToDictionary(descriptor => descriptor.Id);
|
|
781
|
-
|
|
782
|
-
return OrderComponentDescriptors(_runtimeComponentIds
|
|
783
|
-
.Where(descriptorsById.ContainsKey)
|
|
784
|
-
.Select(id => descriptorsById[id]));
|
|
778
|
+
return OrderComponents(_runtimeComponentIds);
|
|
785
779
|
}
|
|
786
780
|
|
|
787
|
-
private
|
|
781
|
+
private ComponentId[] OrderComponents(IEnumerable<ComponentId> componentIds)
|
|
788
782
|
{
|
|
789
|
-
return
|
|
790
|
-
.OrderBy(
|
|
791
|
-
.ThenBy(
|
|
783
|
+
return componentIds
|
|
784
|
+
.OrderBy(componentId => GetComponentOrder(Components.GetSchemaId(componentId).Value))
|
|
785
|
+
.ThenBy(componentId => GetShortTypeName(Components.GetComponentType(componentId)), StringComparer.Ordinal)
|
|
792
786
|
.ToArray();
|
|
793
787
|
}
|
|
794
788
|
|
|
@@ -811,19 +805,17 @@ namespace Delta.ECS.Unity.Editor
|
|
|
811
805
|
}
|
|
812
806
|
|
|
813
807
|
private void DrawRuntimeValue(VisualElement body, SceneWorld world, Entity entity,
|
|
814
|
-
|
|
808
|
+
ComponentId componentId, object value)
|
|
815
809
|
{
|
|
816
|
-
bool canWrite = (descriptor.Capabilities & ComponentCapabilities.Write) != 0
|
|
817
|
-
&& descriptor.ValueType.IsValueType;
|
|
818
810
|
int previousChildCount = body.childCount;
|
|
819
|
-
ComponentPropertyBinding[] properties = ComponentPropertyBagFields.Build(body,
|
|
820
|
-
|
|
821
|
-
(path, next) => WriteRuntimeField(world, entity,
|
|
811
|
+
ComponentPropertyBinding[] properties = ComponentPropertyBagFields.Build(body, Components.GetComponentType(componentId),
|
|
812
|
+
value, true,
|
|
813
|
+
(path, next) => WriteRuntimeField(world, entity, componentId, path, next),
|
|
822
814
|
(label, current, onChanged) => CreateRuntimeEntityReferenceField(world, label, current, onChanged));
|
|
823
815
|
|
|
824
816
|
if (properties.Length > 0)
|
|
825
817
|
{
|
|
826
|
-
_runtimeBindings.Add(new RuntimeValueBinding(
|
|
818
|
+
_runtimeBindings.Add(new RuntimeValueBinding(componentId, properties));
|
|
827
819
|
}
|
|
828
820
|
else if (body.childCount == previousChildCount)
|
|
829
821
|
{
|
|
@@ -831,18 +823,19 @@ namespace Delta.ECS.Unity.Editor
|
|
|
831
823
|
}
|
|
832
824
|
}
|
|
833
825
|
|
|
834
|
-
private VisualElement CreateRuntimeEntityReferenceField(SceneWorld
|
|
826
|
+
private VisualElement CreateRuntimeEntityReferenceField(SceneWorld sceneWorld, string label, Entity current,
|
|
835
827
|
Action<object> onChanged)
|
|
836
828
|
{
|
|
837
|
-
|
|
829
|
+
World world = sceneWorld.World;
|
|
830
|
+
Entity[] authored = sceneWorld.AuthoredEntities;
|
|
838
831
|
var values = new List<Entity>(authored.Length + 2) { default };
|
|
839
832
|
var options = new List<string>(authored.Length + 2) { "None" };
|
|
840
833
|
var names = new List<string>(authored.Length);
|
|
841
834
|
for (int i = 0; i < authored.Length; i++)
|
|
842
835
|
{
|
|
843
836
|
Entity candidate = authored[i];
|
|
844
|
-
if (!world.
|
|
845
|
-
names.Add(GetRuntimeEntityName(
|
|
837
|
+
if (!world.IsAlive(candidate)) continue;
|
|
838
|
+
names.Add(GetRuntimeEntityName(sceneWorld, candidate));
|
|
846
839
|
}
|
|
847
840
|
|
|
848
841
|
HashSet<string> duplicateNames = names
|
|
@@ -856,9 +849,9 @@ namespace Delta.ECS.Unity.Editor
|
|
|
856
849
|
for (int i = 0; i < authored.Length; i++)
|
|
857
850
|
{
|
|
858
851
|
Entity candidate = authored[i];
|
|
859
|
-
if (!world.
|
|
852
|
+
if (!world.IsAlive(candidate)) continue;
|
|
860
853
|
string name = names[nameIndex++];
|
|
861
|
-
string stableId =
|
|
854
|
+
string stableId = sceneWorld.TryGetStableId(candidate, out string id) ? id : string.Empty;
|
|
862
855
|
values.Add(candidate);
|
|
863
856
|
options.Add(duplicateNames.Contains(name) && !string.IsNullOrEmpty(stableId)
|
|
864
857
|
? $"{name} ({stableId.Substring(0, Math.Min(8, stableId.Length))})"
|
|
@@ -869,7 +862,7 @@ namespace Delta.ECS.Unity.Editor
|
|
|
869
862
|
if (current.IsValid && currentIndex < 0)
|
|
870
863
|
{
|
|
871
864
|
values.Add(current);
|
|
872
|
-
options.Add($"Current ({FormatValue(typeof(Entity), current,
|
|
865
|
+
options.Add($"Current ({FormatValue(typeof(Entity), current, sceneWorld)})");
|
|
873
866
|
currentIndex = values.Count - 1;
|
|
874
867
|
}
|
|
875
868
|
|
|
@@ -893,27 +886,27 @@ namespace Delta.ECS.Unity.Editor
|
|
|
893
886
|
: entity.ToString();
|
|
894
887
|
}
|
|
895
888
|
|
|
896
|
-
private void WriteRuntimeField(SceneWorld world, Entity entity,
|
|
889
|
+
private void WriteRuntimeField(SceneWorld world, Entity entity, ComponentId componentId,
|
|
897
890
|
string[] path, object next)
|
|
898
891
|
{
|
|
899
|
-
if (!world.
|
|
892
|
+
if (!world.TryRead(entity, componentId, out object value))
|
|
900
893
|
{
|
|
901
|
-
Debug.LogWarning($"Could not read {
|
|
894
|
+
Debug.LogWarning($"Could not read {Components.GetComponentType(componentId).FullName ?? Components.GetComponentType(componentId).Name} before editing.");
|
|
902
895
|
RefreshRuntimeView();
|
|
903
896
|
return;
|
|
904
897
|
}
|
|
905
898
|
|
|
906
|
-
object updated =
|
|
907
|
-
if (!PropertyBagValueAccess.TrySetValue(ref updated,
|
|
899
|
+
object updated = value;
|
|
900
|
+
if (!PropertyBagValueAccess.TrySetValue(ref updated, Components.GetComponentType(componentId), path, next))
|
|
908
901
|
{
|
|
909
|
-
Debug.LogWarning($"Could not edit {
|
|
902
|
+
Debug.LogWarning($"Could not edit {Components.GetComponentType(componentId).FullName ?? Components.GetComponentType(componentId).Name}: the property path is unavailable.");
|
|
910
903
|
RefreshRuntimeView();
|
|
911
904
|
return;
|
|
912
905
|
}
|
|
913
906
|
|
|
914
|
-
if (!world.
|
|
907
|
+
if (!world.TryWrite(entity, componentId, updated))
|
|
915
908
|
{
|
|
916
|
-
Debug.LogWarning($"Could not edit {
|
|
909
|
+
Debug.LogWarning($"Could not edit {Components.GetComponentType(componentId).FullName ?? Components.GetComponentType(componentId).Name}.");
|
|
917
910
|
RefreshRuntimeView();
|
|
918
911
|
}
|
|
919
912
|
}
|
|
@@ -951,9 +944,23 @@ namespace Delta.ECS.Unity.Editor
|
|
|
951
944
|
return;
|
|
952
945
|
}
|
|
953
946
|
|
|
954
|
-
SceneWorld
|
|
947
|
+
SceneWorld sceneWorld = _target.RuntimeWorld;
|
|
955
948
|
Entity entity = _target.RuntimeEntity;
|
|
956
|
-
if (
|
|
949
|
+
if (sceneWorld == null || !sceneWorld.IsBound)
|
|
950
|
+
{
|
|
951
|
+
if (_runtimeComponentIds != null)
|
|
952
|
+
{
|
|
953
|
+
_runtimeComponentIds = null;
|
|
954
|
+
_runtimeComponentBuffer = null;
|
|
955
|
+
_runtimeBindings.Clear();
|
|
956
|
+
RefreshContent();
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
return;
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
World world = sceneWorld.World;
|
|
963
|
+
if (!world.IsAlive(entity))
|
|
957
964
|
{
|
|
958
965
|
if (_runtimeComponentIds != null)
|
|
959
966
|
{
|
|
@@ -972,7 +979,7 @@ namespace Delta.ECS.Unity.Editor
|
|
|
972
979
|
return;
|
|
973
980
|
}
|
|
974
981
|
|
|
975
|
-
if (!
|
|
982
|
+
if (!sceneWorld.TryGetComponents(entity, _runtimeComponentBuffer, out int count)
|
|
976
983
|
|| count != _runtimeComponentIds.Length)
|
|
977
984
|
{
|
|
978
985
|
RefreshContent();
|
|
@@ -991,7 +998,7 @@ namespace Delta.ECS.Unity.Editor
|
|
|
991
998
|
for (int i = 0; i < _runtimeBindings.Count; i++)
|
|
992
999
|
{
|
|
993
1000
|
RuntimeValueBinding binding = _runtimeBindings[i];
|
|
994
|
-
if (!
|
|
1001
|
+
if (!sceneWorld.TryRead(entity, binding.Component, out object componentValue))
|
|
995
1002
|
{
|
|
996
1003
|
continue;
|
|
997
1004
|
}
|
|
@@ -1006,10 +1013,10 @@ namespace Delta.ECS.Unity.Editor
|
|
|
1006
1013
|
continue;
|
|
1007
1014
|
}
|
|
1008
1015
|
|
|
1009
|
-
if (PropertyBagValueAccess.TryGetValue(
|
|
1010
|
-
property.Path, out object
|
|
1016
|
+
if (PropertyBagValueAccess.TryGetValue(componentValue, Components.GetComponentType(binding.Component),
|
|
1017
|
+
property.Path, out object fieldValue))
|
|
1011
1018
|
{
|
|
1012
|
-
SetRuntimeFieldValue(control, property.ValueType,
|
|
1019
|
+
SetRuntimeFieldValue(control, property.ValueType, fieldValue, sceneWorld);
|
|
1013
1020
|
}
|
|
1014
1021
|
}
|
|
1015
1022
|
}
|
|
@@ -1085,26 +1092,22 @@ namespace Delta.ECS.Unity.Editor
|
|
|
1085
1092
|
|
|
1086
1093
|
private ComponentEntry[] ProjectAuthoringComponents(EntityAuthoring authoring)
|
|
1087
1094
|
{
|
|
1088
|
-
Dictionary<ulong, ComponentDescriptor> descriptors = _previewWorld.Integration.Catalog.Components
|
|
1089
|
-
.ToArray()
|
|
1090
|
-
.ToDictionary(descriptor => descriptor.Schema.Value);
|
|
1091
|
-
|
|
1092
1095
|
return authoring.Components
|
|
1093
|
-
.Select(data => new ComponentEntry(data,
|
|
1094
|
-
.OrderBy(entry => entry.
|
|
1095
|
-
.ThenBy(entry => entry.
|
|
1096
|
-
? GetShortTypeName(entry.
|
|
1096
|
+
.Select(data => new ComponentEntry(data, TryGetComponentId(data)))
|
|
1097
|
+
.OrderBy(entry => entry.Component.HasValue ? GetComponentOrder(Components.GetSchemaId(entry.Component.Value).Value) : int.MaxValue)
|
|
1098
|
+
.ThenBy(entry => entry.Component.HasValue
|
|
1099
|
+
? GetShortTypeName(Components.GetComponentType(entry.Component.Value))
|
|
1097
1100
|
: entry.Data?.SchemaIdText ?? string.Empty, StringComparer.Ordinal)
|
|
1098
1101
|
.ToArray();
|
|
1099
1102
|
}
|
|
1100
1103
|
|
|
1101
|
-
private void AddComponent(EntityAuthoring authoring,
|
|
1104
|
+
private void AddComponent(EntityAuthoring authoring, ComponentId componentId)
|
|
1102
1105
|
{
|
|
1103
|
-
Undo.RecordObject(Authoring, $"Add {GetShortTypeName(
|
|
1104
|
-
ComponentData data = ComponentData.CreateDefault(
|
|
1105
|
-
if (!_previewWorld.AddComponent(authoring,
|
|
1106
|
+
Undo.RecordObject(Authoring, $"Add {GetShortTypeName(Components.GetComponentType(componentId))}");
|
|
1107
|
+
ComponentData data = ComponentData.CreateDefault(Components, componentId);
|
|
1108
|
+
if (!_previewWorld.AddComponent(authoring, componentId, data, out string failureReason))
|
|
1106
1109
|
{
|
|
1107
|
-
Debug.LogError($"Could not add {GetShortTypeName(
|
|
1110
|
+
Debug.LogError($"Could not add {GetShortTypeName(Components.GetComponentType(componentId))}: {failureReason}.", Authoring);
|
|
1108
1111
|
RebuildPreviewAndView();
|
|
1109
1112
|
return;
|
|
1110
1113
|
}
|
|
@@ -1115,16 +1118,16 @@ namespace Delta.ECS.Unity.Editor
|
|
|
1115
1118
|
}
|
|
1116
1119
|
|
|
1117
1120
|
private void RemoveComponent(EntityAuthoring authoring, ComponentData data,
|
|
1118
|
-
|
|
1121
|
+
ComponentId? componentId = null)
|
|
1119
1122
|
{
|
|
1120
1123
|
int index = authoring.Components.IndexOf(data);
|
|
1121
1124
|
if (index < 0 || index >= authoring.Components.Count) return;
|
|
1122
|
-
if (!
|
|
1125
|
+
if (!componentId.HasValue && _previewWorld.TryGetComponentId(data, out ComponentId resolved))
|
|
1123
1126
|
{
|
|
1124
|
-
|
|
1127
|
+
componentId = resolved;
|
|
1125
1128
|
}
|
|
1126
1129
|
|
|
1127
|
-
if (!
|
|
1130
|
+
if (!componentId.HasValue)
|
|
1128
1131
|
{
|
|
1129
1132
|
Undo.RecordObject(Authoring, "Remove Unregistered Delta ECS Component");
|
|
1130
1133
|
authoring.Components.RemoveAt(index);
|
|
@@ -1133,11 +1136,11 @@ namespace Delta.ECS.Unity.Editor
|
|
|
1133
1136
|
return;
|
|
1134
1137
|
}
|
|
1135
1138
|
|
|
1136
|
-
|
|
1137
|
-
Undo.RecordObject(Authoring, $"Remove {GetShortTypeName(component
|
|
1138
|
-
if (!_previewWorld.RemoveComponent(authoring, component
|
|
1139
|
+
ComponentId component = componentId.Value;
|
|
1140
|
+
Undo.RecordObject(Authoring, $"Remove {GetShortTypeName(Components.GetComponentType(component))}");
|
|
1141
|
+
if (!_previewWorld.RemoveComponent(authoring, component))
|
|
1139
1142
|
{
|
|
1140
|
-
Debug.LogError($"Could not remove {GetShortTypeName(component
|
|
1143
|
+
Debug.LogError($"Could not remove {GetShortTypeName(Components.GetComponentType(component))}.", Authoring);
|
|
1141
1144
|
return;
|
|
1142
1145
|
}
|
|
1143
1146
|
|
|
@@ -1146,18 +1149,18 @@ namespace Delta.ECS.Unity.Editor
|
|
|
1146
1149
|
RebuildPreviewAndView();
|
|
1147
1150
|
}
|
|
1148
1151
|
|
|
1149
|
-
private void ResetComponent(EntityAuthoring authoring, ComponentData data,
|
|
1152
|
+
private void ResetComponent(EntityAuthoring authoring, ComponentData data, ComponentId componentId)
|
|
1150
1153
|
{
|
|
1151
|
-
Undo.RecordObject(Authoring, $"Reset {GetShortTypeName(
|
|
1152
|
-
object value = Activator.CreateInstance(
|
|
1153
|
-
if (_previewWorld.TryWrite(authoring, data,
|
|
1154
|
-
else Debug.LogError($"Could not reset {GetShortTypeName(
|
|
1154
|
+
Undo.RecordObject(Authoring, $"Reset {GetShortTypeName(Components.GetComponentType(componentId))}");
|
|
1155
|
+
object value = Activator.CreateInstance(Components.GetComponentType(componentId));
|
|
1156
|
+
if (_previewWorld.TryWrite(authoring, data, componentId, value)) MarkSceneDirty();
|
|
1157
|
+
else Debug.LogError($"Could not reset {GetShortTypeName(Components.GetComponentType(componentId))}.", Authoring);
|
|
1155
1158
|
RefreshContent();
|
|
1156
1159
|
}
|
|
1157
1160
|
|
|
1158
1161
|
private void MoveComponent(ulong schema, int direction)
|
|
1159
1162
|
{
|
|
1160
|
-
int index = _componentEntries.FindIndex(entry => entry.
|
|
1163
|
+
int index = _componentEntries.FindIndex(entry => entry.Component.HasValue && Components.GetSchemaId(entry.Component.Value).Value == schema);
|
|
1161
1164
|
int next = index + direction;
|
|
1162
1165
|
if (index < 0 || next < 0 || next >= _componentEntries.Count) return;
|
|
1163
1166
|
_componentList.viewController.Move(index, next);
|
|
@@ -1201,22 +1204,22 @@ namespace Delta.ECS.Unity.Editor
|
|
|
1201
1204
|
private readonly struct ComponentEntry
|
|
1202
1205
|
{
|
|
1203
1206
|
public readonly ComponentData Data;
|
|
1204
|
-
public readonly
|
|
1205
|
-
public ComponentEntry(ComponentData data,
|
|
1207
|
+
public readonly ComponentId? Component;
|
|
1208
|
+
public ComponentEntry(ComponentData data, ComponentId? componentId)
|
|
1206
1209
|
{
|
|
1207
1210
|
Data = data;
|
|
1208
|
-
|
|
1211
|
+
Component = componentId;
|
|
1209
1212
|
}
|
|
1210
1213
|
}
|
|
1211
1214
|
|
|
1212
1215
|
private readonly struct RuntimeValueBinding
|
|
1213
1216
|
{
|
|
1214
|
-
public readonly
|
|
1217
|
+
public readonly ComponentId Component;
|
|
1215
1218
|
public readonly ComponentPropertyBinding[] Properties;
|
|
1216
1219
|
|
|
1217
|
-
public RuntimeValueBinding(
|
|
1220
|
+
public RuntimeValueBinding(ComponentId componentId, ComponentPropertyBinding[] properties)
|
|
1218
1221
|
{
|
|
1219
|
-
|
|
1222
|
+
Component = componentId;
|
|
1220
1223
|
Properties = properties;
|
|
1221
1224
|
}
|
|
1222
1225
|
}
|
package/README.md
CHANGED
package/Runtime/ComponentData.cs
CHANGED
|
@@ -2,7 +2,6 @@ using System;
|
|
|
2
2
|
using System.Collections.Generic;
|
|
3
3
|
|
|
4
4
|
using Delta.ECS;
|
|
5
|
-
using Delta.ECS.Integration;
|
|
6
5
|
|
|
7
6
|
using UnityEngine;
|
|
8
7
|
|
|
@@ -28,15 +27,15 @@ namespace Delta.ECS.Unity
|
|
|
28
27
|
_json = json;
|
|
29
28
|
}
|
|
30
29
|
|
|
31
|
-
public static ComponentData CreateDefault(
|
|
30
|
+
public static ComponentData CreateDefault(ComponentRegistry components, ComponentId componentId)
|
|
32
31
|
{
|
|
33
|
-
if (
|
|
32
|
+
if (components.IsTag(componentId))
|
|
34
33
|
{
|
|
35
|
-
return new ComponentData(
|
|
34
|
+
return new ComponentData(components.GetSchemaId(componentId).Value, "{}");
|
|
36
35
|
}
|
|
37
36
|
|
|
38
|
-
object value = Activator.CreateInstance(
|
|
39
|
-
return new ComponentData(
|
|
37
|
+
object value = Activator.CreateInstance(components.GetComponentType(componentId));
|
|
38
|
+
return new ComponentData(components.GetSchemaId(componentId).Value, JsonUtility.ToJson(value));
|
|
40
39
|
}
|
|
41
40
|
|
|
42
41
|
public bool TryGetSchemaId(out SchemaId schemaId)
|
package/Runtime/SceneWorld.cs
CHANGED
|
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
|
|
3
3
|
using System.Diagnostics.CodeAnalysis;
|
|
4
4
|
|
|
5
5
|
using Delta.ECS;
|
|
6
|
-
using Delta.ECS.Integration;
|
|
7
6
|
|
|
8
7
|
using UnityEngine;
|
|
9
8
|
using UnityEngine.SceneManagement;
|
|
@@ -25,7 +24,6 @@ namespace Delta.ECS.Unity
|
|
|
25
24
|
private readonly Dictionary<Entity, GameObject> _viewsByEntity = new();
|
|
26
25
|
private readonly Dictionary<UnityEngine.EntityId, Entity> _entitiesByView = new();
|
|
27
26
|
private readonly World _world;
|
|
28
|
-
private readonly IEcsWorld _integration;
|
|
29
27
|
private readonly SceneData _sceneData;
|
|
30
28
|
private readonly SceneAuthoring _authoring;
|
|
31
29
|
private readonly bool _ownsWorld;
|
|
@@ -33,7 +31,6 @@ namespace Delta.ECS.Unity
|
|
|
33
31
|
private bool _disposed;
|
|
34
32
|
|
|
35
33
|
public World World => _world;
|
|
36
|
-
internal ComponentId HiddenEntityHierarchyComponentId => _hiddenEntityHierarchyComponentId;
|
|
37
34
|
|
|
38
35
|
public Entity[] AuthoredEntities
|
|
39
36
|
{
|
|
@@ -44,28 +41,21 @@ namespace Delta.ECS.Unity
|
|
|
44
41
|
return entities;
|
|
45
42
|
}
|
|
46
43
|
}
|
|
47
|
-
internal
|
|
44
|
+
internal ComponentId HiddenEntityHierarchyComponentId => _hiddenEntityHierarchyComponentId;
|
|
48
45
|
internal SceneData SceneData => _sceneData;
|
|
49
46
|
internal Scene UnityScene => _authoring != null ? _authoring.gameObject.scene : default;
|
|
50
47
|
internal bool IsBound => !_disposed;
|
|
51
48
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
{
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
private SceneWorld(World world, SceneData sceneData,
|
|
58
|
-
SceneAuthoring authoring, bool ownsWorld, bool registerLiveWorld)
|
|
49
|
+
private SceneWorld(World world,
|
|
50
|
+
SceneData sceneData, SceneAuthoring authoring, bool ownsWorld, bool registerLiveWorld)
|
|
59
51
|
{
|
|
60
52
|
_world = world ?? UnityThrowHelpers.ThrowArgumentNull<World>(nameof(world));
|
|
61
53
|
_sceneData = sceneData ?? UnityThrowHelpers.ThrowArgumentNull<SceneData>(nameof(sceneData));
|
|
62
54
|
_authoring = authoring;
|
|
63
|
-
_integration = world;
|
|
64
55
|
_ownsWorld = ownsWorld;
|
|
65
56
|
_hiddenEntityHierarchyComponentId = world.Components.GetPrimary<HideFromEntityHierarchy>();
|
|
66
57
|
|
|
67
58
|
_sceneData.EnsureStableIds();
|
|
68
|
-
_integration.Initialize();
|
|
69
59
|
RebuildAuthoringEntities();
|
|
70
60
|
if (registerLiveWorld)
|
|
71
61
|
{
|
|
@@ -73,7 +63,7 @@ namespace Delta.ECS.Unity
|
|
|
73
63
|
}
|
|
74
64
|
}
|
|
75
65
|
|
|
76
|
-
/// <summary>Returns the
|
|
66
|
+
/// <summary>Returns the runtime context for a loaded Unity scene.</summary>
|
|
77
67
|
public static SceneWorld GetForScene(Scene scene) => SceneWorldRuntime.GetForScene(scene);
|
|
78
68
|
|
|
79
69
|
/// <summary>Resolves the live ECS world and entity currently associated with a Unity view.</summary>
|
|
@@ -93,7 +83,7 @@ namespace Delta.ECS.Unity
|
|
|
93
83
|
/// <summary>Registers a transient runtime association; it is not written into scene data.</summary>
|
|
94
84
|
public bool BindView(Entity entity, GameObject view)
|
|
95
85
|
{
|
|
96
|
-
if (view == null || !
|
|
86
|
+
if (view == null || !_world.IsAlive(entity))
|
|
97
87
|
{
|
|
98
88
|
return false;
|
|
99
89
|
}
|
|
@@ -128,7 +118,7 @@ namespace Delta.ECS.Unity
|
|
|
128
118
|
{
|
|
129
119
|
foreach (Entity candidate in _entitiesByStableId.Values)
|
|
130
120
|
{
|
|
131
|
-
if (
|
|
121
|
+
if (_world.IsAlive(candidate) && _world.Has(candidate, componentId))
|
|
132
122
|
{
|
|
133
123
|
entity = candidate;
|
|
134
124
|
return true;
|
|
@@ -159,7 +149,6 @@ namespace Delta.ECS.Unity
|
|
|
159
149
|
_stableIdsByEntity.Clear();
|
|
160
150
|
_viewsByEntity.Clear();
|
|
161
151
|
_entitiesByView.Clear();
|
|
162
|
-
_integration.Shutdown();
|
|
163
152
|
|
|
164
153
|
if (_ownsWorld)
|
|
165
154
|
{
|
|
@@ -220,7 +209,7 @@ namespace Delta.ECS.Unity
|
|
|
220
209
|
|
|
221
210
|
internal static SceneWorld CreatePreview(SceneData sceneData)
|
|
222
211
|
{
|
|
223
|
-
|
|
212
|
+
World world = CreateWorld(DefaultEntityCapacity);
|
|
224
213
|
try
|
|
225
214
|
{
|
|
226
215
|
return new SceneWorld(world, sceneData, null,
|
|
@@ -240,7 +229,7 @@ namespace Delta.ECS.Unity
|
|
|
240
229
|
UnityThrowHelpers.ThrowArgumentNull(nameof(authoring));
|
|
241
230
|
}
|
|
242
231
|
|
|
243
|
-
|
|
232
|
+
World world = CreateWorld(DefaultEntityCapacity);
|
|
244
233
|
try
|
|
245
234
|
{
|
|
246
235
|
return new SceneWorld(world, authoring.SceneData, authoring,
|
|
@@ -260,7 +249,7 @@ namespace Delta.ECS.Unity
|
|
|
260
249
|
UnityThrowHelpers.ThrowArgumentNull(nameof(authoring));
|
|
261
250
|
}
|
|
262
251
|
|
|
263
|
-
|
|
252
|
+
World world = CreateWorld(RuntimeEntityCapacity);
|
|
264
253
|
try
|
|
265
254
|
{
|
|
266
255
|
return new SceneWorld(world, authoring.SceneData, authoring,
|
|
@@ -295,10 +284,10 @@ namespace Delta.ECS.Unity
|
|
|
295
284
|
for (int componentIndex = 0; componentIndex < authoring.Components.Count; componentIndex++)
|
|
296
285
|
{
|
|
297
286
|
ComponentData data = authoring.Components[componentIndex];
|
|
298
|
-
if (
|
|
299
|
-
&& seenSchemas.Add(
|
|
287
|
+
if (TryGetComponentId(data, out ComponentId componentId)
|
|
288
|
+
&& seenSchemas.Add(_world.Components.GetSchemaId(componentId).Value))
|
|
300
289
|
{
|
|
301
|
-
componentIds.Add(
|
|
290
|
+
componentIds.Add(componentId);
|
|
302
291
|
}
|
|
303
292
|
else
|
|
304
293
|
{
|
|
@@ -306,7 +295,7 @@ namespace Delta.ECS.Unity
|
|
|
306
295
|
}
|
|
307
296
|
}
|
|
308
297
|
|
|
309
|
-
Entity entity =
|
|
298
|
+
Entity entity = _world.Create(componentIds.ToArray());
|
|
310
299
|
_entitiesByStableId.Add(authoring.StableId, entity);
|
|
311
300
|
_stableIdsByEntity.Add(entity, authoring.StableId);
|
|
312
301
|
}
|
|
@@ -323,21 +312,21 @@ namespace Delta.ECS.Unity
|
|
|
323
312
|
for (int componentIndex = 0; componentIndex < authoring.Components.Count; componentIndex++)
|
|
324
313
|
{
|
|
325
314
|
ComponentData data = authoring.Components[componentIndex];
|
|
326
|
-
if (!
|
|
315
|
+
if (!TryGetComponentId(data, out ComponentId componentId))
|
|
327
316
|
{
|
|
328
317
|
continue;
|
|
329
318
|
}
|
|
330
319
|
|
|
331
|
-
if (
|
|
320
|
+
if (_world.Components.IsTag(componentId))
|
|
332
321
|
{
|
|
333
322
|
continue;
|
|
334
323
|
}
|
|
335
324
|
|
|
336
|
-
object value = data.CreateValue(
|
|
337
|
-
if (
|
|
338
|
-
&& !
|
|
325
|
+
object value = data.CreateValue(_world.Components.GetComponentType(componentId), ResolveEntity);
|
|
326
|
+
if (TryRead(entity, componentId, out _)
|
|
327
|
+
&& !_world.TryWrite(entity, componentId, value))
|
|
339
328
|
{
|
|
340
|
-
Debug.LogError($"Failed to load {
|
|
329
|
+
Debug.LogError($"Failed to load {_world.Components.GetComponentType(componentId).FullName ?? _world.Components.GetComponentType(componentId).Name} on '{authoring.Name}'.");
|
|
341
330
|
}
|
|
342
331
|
}
|
|
343
332
|
}
|
|
@@ -369,7 +358,7 @@ namespace Delta.ECS.Unity
|
|
|
369
358
|
internal bool TryGetEntity(GameObject view, out Entity entity)
|
|
370
359
|
{
|
|
371
360
|
if (view != null && _entitiesByView.TryGetValue(view.GetEntityId(), out entity)
|
|
372
|
-
&&
|
|
361
|
+
&& _world.IsAlive(entity))
|
|
373
362
|
{
|
|
374
363
|
return true;
|
|
375
364
|
}
|
|
@@ -377,7 +366,7 @@ namespace Delta.ECS.Unity
|
|
|
377
366
|
if (view != null && _authoring != null
|
|
378
367
|
&& _authoring.TryGetStableId(view, out string stableId)
|
|
379
368
|
&& _entitiesByStableId.TryGetValue(stableId, out entity)
|
|
380
|
-
&&
|
|
369
|
+
&& _world.IsAlive(entity))
|
|
381
370
|
{
|
|
382
371
|
return true;
|
|
383
372
|
}
|
|
@@ -386,56 +375,42 @@ namespace Delta.ECS.Unity
|
|
|
386
375
|
return false;
|
|
387
376
|
}
|
|
388
377
|
|
|
389
|
-
internal bool
|
|
378
|
+
internal bool TryGetComponentId(ComponentData data, out ComponentId componentId)
|
|
390
379
|
{
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
return false;
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
ReadOnlyMemory<ComponentDescriptor> catalog = _integration.Catalog.Components;
|
|
398
|
-
for (int i = 0; i < catalog.Length; i++)
|
|
399
|
-
{
|
|
400
|
-
if (catalog.Span[i].Schema == schema)
|
|
401
|
-
{
|
|
402
|
-
descriptor = catalog.Span[i];
|
|
403
|
-
return true;
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
return false;
|
|
380
|
+
componentId = ComponentId.Invalid;
|
|
381
|
+
return data != null && data.TryGetSchemaId(out SchemaId schema)
|
|
382
|
+
&& _world.Components.TryGetComponentId(schema, out componentId);
|
|
408
383
|
}
|
|
409
384
|
|
|
410
|
-
internal bool TryRead(EntityAuthoring authoring,
|
|
411
|
-
out ComponentSnapshot snapshot, out EcsReadError error)
|
|
385
|
+
internal bool TryRead(EntityAuthoring authoring, ComponentId componentId, out object? value)
|
|
412
386
|
{
|
|
413
387
|
if (TryGetEntity(authoring, out Entity entity))
|
|
414
388
|
{
|
|
415
|
-
return TryRead(entity,
|
|
389
|
+
return TryRead(entity, componentId, out value);
|
|
416
390
|
}
|
|
417
391
|
|
|
418
|
-
|
|
419
|
-
error = default;
|
|
392
|
+
value = null;
|
|
420
393
|
return false;
|
|
421
394
|
}
|
|
422
395
|
|
|
423
|
-
internal bool TryRead(Entity entity,
|
|
424
|
-
|
|
425
|
-
|
|
396
|
+
internal bool TryRead(Entity entity, ComponentId componentId, out object? value)
|
|
397
|
+
=> _world.TryRead(entity, componentId, out value);
|
|
398
|
+
|
|
399
|
+
internal bool TryWrite(Entity entity, ComponentId componentId, object value)
|
|
400
|
+
=> _world.TryWrite(entity, componentId, value);
|
|
426
401
|
|
|
427
402
|
internal bool TryGetComponents(Entity entity, Span<ComponentId> destination, out int totalCount)
|
|
428
403
|
{
|
|
429
404
|
totalCount = 0;
|
|
430
|
-
if (!
|
|
405
|
+
if (!_world.IsAlive(entity))
|
|
431
406
|
{
|
|
432
407
|
return false;
|
|
433
408
|
}
|
|
434
409
|
|
|
435
|
-
|
|
410
|
+
ReadOnlySpan<ComponentId> components = _world.Components.GetComponentIds();
|
|
436
411
|
for (int index = 0; index < components.Length; index++)
|
|
437
412
|
{
|
|
438
|
-
ComponentId component = components
|
|
413
|
+
ComponentId component = components[index];
|
|
439
414
|
if (!_world.Has(entity, component))
|
|
440
415
|
{
|
|
441
416
|
continue;
|
|
@@ -453,26 +428,14 @@ namespace Delta.ECS.Unity
|
|
|
453
428
|
}
|
|
454
429
|
|
|
455
430
|
internal bool TryWrite(EntityAuthoring authoring, ComponentData data,
|
|
456
|
-
|
|
431
|
+
ComponentId componentId, object value)
|
|
457
432
|
{
|
|
458
|
-
if (!TryGetEntity(authoring, out Entity entity) || !
|
|
459
|
-
{
|
|
460
|
-
error = new EcsWriteError(EcsWriteErrorCode.EntityNotAlive);
|
|
461
|
-
return false;
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
if (!_integration.TryRead(entity, descriptor.Id, out ComponentSnapshot snapshot, out _))
|
|
465
|
-
{
|
|
466
|
-
error = new EcsWriteError(EcsWriteErrorCode.ComponentMissing);
|
|
467
|
-
return false;
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
if (!_integration.TryWrite(entity, descriptor.Id, value, out error))
|
|
433
|
+
if (!TryGetEntity(authoring, out Entity entity) || !_world.TryWrite(entity, componentId, value))
|
|
471
434
|
{
|
|
472
435
|
return false;
|
|
473
436
|
}
|
|
474
437
|
|
|
475
|
-
if (
|
|
438
|
+
if (_world.Components.IsTag(componentId))
|
|
476
439
|
{
|
|
477
440
|
data.StoreDefaultTag();
|
|
478
441
|
}
|
|
@@ -484,60 +447,41 @@ namespace Delta.ECS.Unity
|
|
|
484
447
|
return true;
|
|
485
448
|
}
|
|
486
449
|
|
|
487
|
-
internal bool AddComponent(EntityAuthoring authoring,
|
|
488
|
-
ComponentData data, out
|
|
450
|
+
internal bool AddComponent(EntityAuthoring authoring, ComponentId componentId,
|
|
451
|
+
ComponentData data, out string failureReason)
|
|
489
452
|
{
|
|
490
453
|
failureReason = null;
|
|
491
454
|
if (!TryGetEntity(authoring, out Entity entity))
|
|
492
455
|
{
|
|
493
|
-
error = new EcsWriteError(EcsWriteErrorCode.EntityNotAlive);
|
|
494
456
|
failureReason = "The authored entity is not bound to the preview world. Rebuild the preview and try again.";
|
|
495
457
|
return false;
|
|
496
458
|
}
|
|
497
459
|
|
|
498
|
-
if (!
|
|
460
|
+
if (!_world.IsAlive(entity))
|
|
499
461
|
{
|
|
500
|
-
error = new EcsWriteError(EcsWriteErrorCode.EntityNotAlive);
|
|
501
462
|
failureReason = "The entity is no longer alive in the preview world.";
|
|
502
463
|
return false;
|
|
503
464
|
}
|
|
504
465
|
|
|
505
|
-
if (!
|
|
466
|
+
if (!_world.Add(entity, componentId))
|
|
506
467
|
{
|
|
507
|
-
|
|
508
|
-
failureReason = _world.Has(entity, descriptor.Id)
|
|
468
|
+
failureReason = _world.Has(entity, componentId)
|
|
509
469
|
? "The component is already present in the preview world."
|
|
510
470
|
: "DeltaECS rejected the structural add without reporting a write error.";
|
|
511
471
|
return false;
|
|
512
472
|
}
|
|
513
473
|
|
|
514
|
-
if (
|
|
474
|
+
if (_world.Components.IsTag(componentId))
|
|
515
475
|
{
|
|
516
476
|
data.StoreDefaultTag();
|
|
517
|
-
error = default;
|
|
518
477
|
return true;
|
|
519
478
|
}
|
|
520
479
|
|
|
521
|
-
object value = data.CreateValue(
|
|
522
|
-
if (!
|
|
523
|
-
{
|
|
524
|
-
_integration.Remove(entity, new[] { descriptor.Id });
|
|
525
|
-
error = new EcsWriteError(readError.Code switch
|
|
526
|
-
{
|
|
527
|
-
EcsReadErrorCode.EntityNotAlive => EcsWriteErrorCode.EntityNotAlive,
|
|
528
|
-
EcsReadErrorCode.ComponentUnknown => EcsWriteErrorCode.ComponentUnknown,
|
|
529
|
-
EcsReadErrorCode.ComponentMissing => EcsWriteErrorCode.ComponentMissing,
|
|
530
|
-
EcsReadErrorCode.Unsupported => EcsWriteErrorCode.Unsupported,
|
|
531
|
-
_ => EcsWriteErrorCode.None
|
|
532
|
-
});
|
|
533
|
-
failureReason = $"The new component could not be read from the preview world ({readError.Code}).";
|
|
534
|
-
return false;
|
|
535
|
-
}
|
|
536
|
-
|
|
537
|
-
if (!_integration.TryWrite(entity, descriptor.Id, value, out error))
|
|
480
|
+
object value = data.CreateValue(_world.Components.GetComponentType(componentId), ResolveEntity);
|
|
481
|
+
if (!_world.TryWrite(entity, componentId, value))
|
|
538
482
|
{
|
|
539
|
-
|
|
540
|
-
failureReason =
|
|
483
|
+
_world.Remove(entity, componentId);
|
|
484
|
+
failureReason = "The default component value could not be written.";
|
|
541
485
|
return false;
|
|
542
486
|
}
|
|
543
487
|
|
|
@@ -545,13 +489,8 @@ namespace Delta.ECS.Unity
|
|
|
545
489
|
return true;
|
|
546
490
|
}
|
|
547
491
|
|
|
548
|
-
internal bool RemoveComponent(EntityAuthoring authoring,
|
|
549
|
-
out
|
|
550
|
-
{
|
|
551
|
-
error = default;
|
|
552
|
-
return TryGetEntity(authoring, out Entity entity)
|
|
553
|
-
&& _integration.Remove(entity, new[] { descriptor.Id });
|
|
554
|
-
}
|
|
492
|
+
internal bool RemoveComponent(EntityAuthoring authoring, ComponentId componentId)
|
|
493
|
+
=> TryGetEntity(authoring, out Entity entity) && _world.Remove(entity, componentId);
|
|
555
494
|
|
|
556
495
|
internal bool TryGetAuthoring(string stableId, out EntityAuthoring authoring)
|
|
557
496
|
{
|
|
@@ -586,9 +525,9 @@ namespace Delta.ECS.Unity
|
|
|
586
525
|
{
|
|
587
526
|
foreach (Entity entity in _entitiesByStableId.Values)
|
|
588
527
|
{
|
|
589
|
-
if (
|
|
528
|
+
if (_world.IsAlive(entity))
|
|
590
529
|
{
|
|
591
|
-
|
|
530
|
+
_world.Destroy(entity);
|
|
592
531
|
}
|
|
593
532
|
}
|
|
594
533
|
}
|
|
@@ -2,12 +2,6 @@ using Delta.ECS;
|
|
|
2
2
|
|
|
3
3
|
namespace Delta.ECS.Unity
|
|
4
4
|
{
|
|
5
|
-
internal static class ViewComponentSchemaIds
|
|
6
|
-
{
|
|
7
|
-
internal const ulong ViewToken = 0x405B11F5A17E14A1UL;
|
|
8
|
-
internal const ulong ViewBound = 0xB31CB42A81D3B164UL;
|
|
9
|
-
internal const ulong HideFromEntityHierarchy = 0x8C13A2E9764DB501UL;
|
|
10
|
-
}
|
|
11
5
|
|
|
12
6
|
/// <summary>Receives the entity context after a Unity view is bound to an entity.</summary>
|
|
13
7
|
public interface IEntityView
|
|
@@ -39,4 +33,10 @@ namespace Delta.ECS.Unity
|
|
|
39
33
|
public readonly struct HideFromEntityHierarchy
|
|
40
34
|
{
|
|
41
35
|
}
|
|
36
|
+
internal static class ViewComponentSchemaIds
|
|
37
|
+
{
|
|
38
|
+
internal const ulong ViewToken = 0x405B11F5A17E14A1UL;
|
|
39
|
+
internal const ulong ViewBound = 0xB31CB42A81D3B164UL;
|
|
40
|
+
internal const ulong HideFromEntityHierarchy = 0x8C13A2E9764DB501UL;
|
|
41
|
+
}
|
|
42
42
|
}
|