com.artromskiy.deltaecs.unity 0.0.61 → 0.0.63

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.63
4
+
5
+ - Published with the matching DeltaECS NuGet packages.
6
+
7
+ ## 0.0.62
8
+
9
+ - Published with the matching DeltaECS NuGet packages.
10
+
3
11
  ## 0.0.61
4
12
 
5
13
  - Published with the matching DeltaECS NuGet packages.
@@ -3,7 +3,6 @@ using System.Collections.Generic;
3
3
  using System.Linq;
4
4
  using System.Reflection;
5
5
 
6
- using Delta.ECS.Integration;
7
6
 
8
7
  using UnityEditor.IMGUI.Controls;
9
8
 
@@ -13,13 +12,13 @@ namespace Delta.ECS.Unity.Editor
13
12
  {
14
13
  internal sealed class ComponentDropdown : AdvancedDropdown
15
14
  {
16
- private readonly ComponentDescriptor[] _components;
17
- private readonly Func<ComponentDescriptor, string> _getMenuPath;
18
- private readonly Action<ComponentDescriptor> _add;
19
- private readonly Dictionary<int, ComponentDescriptor> _items = new();
15
+ private readonly ComponentId[] _components;
16
+ private readonly Func<ComponentId, string> _getMenuPath;
17
+ private readonly Action<ComponentId> _add;
18
+ private readonly Dictionary<int, ComponentId> _items = new();
20
19
 
21
- public ComponentDropdown(ComponentDescriptor[] components,
22
- Func<ComponentDescriptor, string> getMenuPath, Action<ComponentDescriptor> add)
20
+ public ComponentDropdown(ComponentId[] components,
21
+ Func<ComponentId, string> getMenuPath, Action<ComponentId> add)
23
22
  : base(new AdvancedDropdownState())
24
23
  {
25
24
  _components = components;
@@ -67,9 +66,9 @@ namespace Delta.ECS.Unity.Editor
67
66
 
68
67
  protected override void ItemSelected(AdvancedDropdownItem item)
69
68
  {
70
- if (_items.TryGetValue(item.id, out ComponentDescriptor descriptor))
69
+ if (_items.TryGetValue(item.id, out ComponentId componentId))
71
70
  {
72
- _add(descriptor);
71
+ _add(componentId);
73
72
  }
74
73
  }
75
74
  }
@@ -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, ComponentDescriptor descriptor,
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(descriptor.ValueType);
30
+ IPropertyBag propertyBag = PropertyBag.GetPropertyBag(componentType);
32
31
  if (propertyBag == null)
33
32
  {
34
33
  return Array.Empty<ComponentPropertyBinding>();
@@ -20,6 +20,7 @@ namespace Delta.ECS.Unity.Editor
20
20
  {
21
21
  private const double RuntimeHierarchyRefreshInterval = 0.5d;
22
22
  private static readonly ComponentId[] NoRequiredComponents = Array.Empty<ComponentId>();
23
+ private static readonly SchemaId HiddenEntitySchema = new(ViewComponentSchemaIds.HideFromEntityHierarchy);
23
24
  private static double _nextRuntimeHierarchyRefresh;
24
25
  private static bool _wasPlaying;
25
26
  private static readonly HashSet<HierarchyNodeHandler> Instances = new();
@@ -269,6 +270,30 @@ namespace Delta.ECS.Unity.Editor
269
270
  return true;
270
271
  }
271
272
 
273
+ private static bool IsHiddenFromHierarchy(
274
+ EntityAuthoring authoring,
275
+ SceneWorld runtimeWorld,
276
+ Entity runtimeEntity)
277
+ {
278
+ if (runtimeWorld != null && runtimeWorld.World.IsAlive(runtimeEntity))
279
+ {
280
+ return runtimeWorld.World.Has(runtimeEntity, runtimeWorld.HiddenEntityHierarchyComponentId);
281
+ }
282
+
283
+ IList<ComponentData> components = authoring.Components;
284
+ for (int index = 0; index < components.Count; index++)
285
+ {
286
+ if (components[index] != null
287
+ && components[index].TryGetSchemaId(out SchemaId schema)
288
+ && schema == HiddenEntitySchema)
289
+ {
290
+ return true;
291
+ }
292
+ }
293
+
294
+ return false;
295
+ }
296
+
272
297
  private void BindToView(HierarchyView view) => OnBindView(view);
273
298
 
274
299
  private void OnEntityNameChanged(ChangeEvent<string> evt)
@@ -458,7 +483,7 @@ namespace Delta.ECS.Unity.Editor
458
483
  || (runtimeWorld != null
459
484
  && runtimeWorld.World.IsAlive(runtimeEntity)
460
485
  && runtimeWorld.TryGetView(runtimeEntity, out _));
461
- if (hasView)
486
+ if (hasView || IsHiddenFromHierarchy(authoring, runtimeWorld, runtimeEntity))
462
487
  {
463
488
  continue;
464
489
  }
@@ -569,7 +594,8 @@ namespace Delta.ECS.Unity.Editor
569
594
  HierarchyNode sceneNode,
570
595
  SceneWorld runtimeWorld)
571
596
  {
572
- Query query = runtimeWorld.World.WhereAll(NoRequiredComponents);
597
+ Query query = runtimeWorld.World.WhereNone(runtimeWorld.HiddenEntityHierarchyComponentId)
598
+ .WhereAll(NoRequiredComponents);
573
599
  bool changed = false;
574
600
  runtimeWorld.World.ForEachEntity(in query, entity =>
575
601
  {
@@ -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;
@@ -191,19 +190,15 @@ namespace Delta.ECS.Unity.Editor
191
190
 
192
191
  private static Label CreateEntityIcon() => CreateClassLabel("◆", "ecs-entity-icon");
193
192
 
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
- }
193
+ private ComponentRegistry Components => (_target.IsRuntime ? _target.RuntimeWorld : _previewWorld).World.Components;
202
194
 
203
- private static string GetComponentMenuPath(ComponentDescriptor descriptor)
195
+ private ComponentId? TryGetComponentId(ComponentData data)
196
+ => _previewWorld.TryGetComponentId(data, out ComponentId componentId) ? componentId : null;
197
+
198
+ private string GetComponentMenuPath(ComponentId componentId)
204
199
  {
205
- string namespacePath = descriptor.ValueType.Namespace?.Replace('.', '/') ?? string.Empty;
206
- string shortName = GetShortTypeName(descriptor.ValueType);
200
+ string namespacePath = Components.GetComponentType(componentId).Namespace?.Replace('.', '/') ?? string.Empty;
201
+ string shortName = GetShortTypeName(Components.GetComponentType(componentId));
207
202
  return string.IsNullOrEmpty(namespacePath) ? shortName : $"{namespacePath}/{shortName}";
208
203
  }
209
204
 
@@ -414,26 +409,26 @@ namespace Delta.ECS.Unity.Editor
414
409
  });
415
410
  }
416
411
 
417
- private VisualElement BuildAuthoringComponentCard(EntityAuthoring authoring, ComponentData data, ComponentDescriptor descriptor)
412
+ private VisualElement BuildAuthoringComponentCard(EntityAuthoring authoring, ComponentData data, ComponentId componentId)
418
413
  {
419
- return BuildComponentCard(descriptor, body =>
414
+ return BuildComponentCard(componentId, body =>
420
415
  {
421
- if (descriptor.IsTag)
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, descriptor, out ComponentSnapshot snapshot, out EcsReadError readError))
422
+ if (!_previewWorld.TryRead(authoring, componentId, out object value))
428
423
  {
429
- body.Add(new HelpBox($"Could not read component: {readError.Code}.", HelpBoxMessageType.Error));
424
+ body.Add(new HelpBox("Could not read component.", HelpBoxMessageType.Error));
430
425
  return;
431
426
  }
432
427
 
433
- DrawEditableValue(body, authoring, data, descriptor, snapshot.Value);
428
+ DrawEditableValue(body, authoring, data, componentId, value);
434
429
  },
435
- descriptor.IsTag ? null : () => ResetComponent(authoring, data, descriptor),
436
- () => RemoveComponent(authoring, data, descriptor));
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
- ComponentDescriptor[] available = Array.FindAll(
466
- _previewWorld.Integration.Catalog.Components.ToArray(),
467
- descriptor => (descriptor.Capabilities & ComponentCapabilities.Write) != 0
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
- descriptor => AddComponent(authoring, descriptor))
465
+ componentId => AddComponent(authoring, componentId))
472
466
  .Show(button.worldBound);
473
467
  return button;
474
468
  }
475
469
 
476
- private VisualElement BuildComponentCard(ComponentDescriptor descriptor, Action<VisualElement> buildBody,
470
+ private VisualElement BuildComponentCard(ComponentId componentId, Action<VisualElement> buildBody,
477
471
  Action resetComponent = null, Action removeComponent = null)
478
472
  {
479
- bool expanded = IsComponentExpanded(descriptor.Schema.Value);
480
- return BuildComponentFoldout(GetShortTypeName(descriptor.ValueType), descriptor.Schema.Value, expanded, buildBody,
481
- header => AddComponentActions(header, descriptor, resetComponent, removeComponent));
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.Descriptor.Schema.Value == schema.Value);
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, ComponentDescriptor descriptor,
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(descriptor.Schema.Value, -1));
532
- actions.menu.AppendAction("Move Down", _ => MoveComponent(descriptor.Schema.Value, 1));
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
- ComponentDescriptor descriptor, object value)
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, descriptor, value,
554
- canWrite,
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, descriptor.ValueType, path, next))
550
+ if (!PropertyBagValueAccess.TrySetValue(ref updated, Components.GetComponentType(componentId), path, next))
559
551
  {
560
- Debug.LogWarning($"Could not edit a property on {descriptor.Name}: the property path is unavailable.", Authoring);
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 {descriptor.Name}");
567
- if (_previewWorld.TryWrite(authoring, data, descriptor, updated, out EcsWriteError writeError))
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 {descriptor.Name}: {writeError.Code}.", Authoring);
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 world = _target.RuntimeWorld;
613
+ SceneWorld sceneWorld = _target.RuntimeWorld;
622
614
  Entity entity = _target.RuntimeEntity;
623
- if (world == null || !world.IsBound || !world.Integration.IsAlive(entity))
615
+ if (sceneWorld == null || !sceneWorld.IsBound)
616
+ {
617
+ _header.Add(new HelpBox("The selected runtime entity is no longer alive.", HelpBoxMessageType.Warning));
618
+ return;
619
+ }
620
+
621
+ World world = sceneWorld.World;
622
+ if (!world.IsAlive(entity))
624
623
  {
625
624
  _header.Add(new HelpBox("The selected runtime entity is no longer alive.", HelpBoxMessageType.Warning));
626
625
  return;
627
626
  }
628
627
 
629
- _header.Add(BuildRuntimeHeader(world, entity));
630
- ComponentDescriptor[] components = ProjectRuntimeComponents(world, entity);
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 (ComponentDescriptor descriptor in components)
636
+ foreach (ComponentId componentId in components)
638
637
  {
639
- _componentEntries.Add(new ComponentEntry(null, descriptor));
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, ComponentDescriptor descriptor)
644
+ private VisualElement BuildRuntimeComponentCard(SceneWorld world, Entity entity, ComponentId componentId)
646
645
  {
647
- return BuildComponentCard(descriptor, body =>
646
+ return BuildComponentCard(componentId, body =>
648
647
  {
649
- if (descriptor.IsTag)
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, descriptor, out ComponentSnapshot snapshot, out EcsReadError error))
654
+ if (!world.TryRead(entity, componentId, out object value))
656
655
  {
657
- body.Add(new HelpBox($"Could not read component: {error.Code}.", HelpBoxMessageType.Error));
656
+ body.Add(new HelpBox("Could not read component.", HelpBoxMessageType.Error));
658
657
  return;
659
658
  }
660
659
 
661
- DrawRuntimeValue(body, world, entity, descriptor, snapshot);
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.Descriptor.Value)
683
- : entry.Descriptor.HasValue
684
- ? BuildAuthoringComponentCard(_authoringEntity, entry.Data, entry.Descriptor.Value)
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.Descriptor.HasValue)
705
- _runtimeBindings.RemoveAll(binding => binding.Descriptor.Schema == entry.Descriptor.Value.Schema);
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.Descriptor.HasValue
725
- ? (ulong?)entry.Descriptor.Value.Schema.Value
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<ComponentDescriptor> catalog = _previewWorld != null
734
- ? _previewWorld.Integration.Catalog.Components.ToArray()
732
+ IEnumerable<ComponentId> catalog = _previewWorld != null
733
+ ? _previewWorld.World.Components.GetComponentIds().ToArray()
735
734
  : _target.RuntimeWorld != null && _target.RuntimeWorld.IsBound
736
- ? _target.RuntimeWorld.Integration.Catalog.Components.ToArray()
737
- : Array.Empty<ComponentDescriptor>();
738
- foreach (ComponentDescriptor descriptor in catalog
739
- .OrderBy(descriptor => GetShortTypeName(descriptor.ValueType), StringComparer.Ordinal))
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(descriptor.Schema.Value))
740
+ if (!componentOrder.Contains(Components.GetSchemaId(componentId).Value))
742
741
  {
743
- componentOrder.Add(descriptor.Schema.Value);
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 ComponentDescriptor[] ProjectRuntimeComponents(SceneWorld world, Entity entity)
766
+ private ComponentId[] ProjectRuntimeComponents(SceneWorld world, Entity entity)
768
767
  {
769
- ReadOnlyMemory<ComponentDescriptor> catalog = world.Integration.Catalog.Components;
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
- Dictionary<ComponentId, ComponentDescriptor> descriptorsById = catalog.ToArray()
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 ComponentDescriptor[] OrderComponentDescriptors(IEnumerable<ComponentDescriptor> descriptors)
781
+ private ComponentId[] OrderComponents(IEnumerable<ComponentId> componentIds)
788
782
  {
789
- return descriptors
790
- .OrderBy(descriptor => GetComponentOrder(descriptor.Schema.Value))
791
- .ThenBy(descriptor => GetShortTypeName(descriptor.ValueType), StringComparer.Ordinal)
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
- ComponentDescriptor descriptor, ComponentSnapshot snapshot)
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, descriptor,
820
- snapshot.Value, canWrite,
821
- (path, next) => WriteRuntimeField(world, entity, descriptor, path, next),
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(descriptor, properties));
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 world, string label, Entity current,
826
+ private VisualElement CreateRuntimeEntityReferenceField(SceneWorld sceneWorld, string label, Entity current,
835
827
  Action<object> onChanged)
836
828
  {
837
- Entity[] authored = world.AuthoredEntities;
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.Integration.IsAlive(candidate)) continue;
845
- names.Add(GetRuntimeEntityName(world, candidate));
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.Integration.IsAlive(candidate)) continue;
852
+ if (!world.IsAlive(candidate)) continue;
860
853
  string name = names[nameIndex++];
861
- string stableId = world.TryGetStableId(candidate, out string id) ? id : string.Empty;
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, world)})");
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, ComponentDescriptor descriptor,
889
+ private void WriteRuntimeField(SceneWorld world, Entity entity, ComponentId componentId,
897
890
  string[] path, object next)
898
891
  {
899
- if (!world.Integration.TryRead(entity, descriptor.Id, out ComponentSnapshot snapshot, out EcsReadError readError))
892
+ if (!world.TryRead(entity, componentId, out object value))
900
893
  {
901
- Debug.LogWarning($"Could not read {descriptor.Name} before editing: {readError.Code}.");
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 = snapshot.Value;
907
- if (!PropertyBagValueAccess.TrySetValue(ref updated, descriptor.ValueType, path, next))
899
+ object updated = value;
900
+ if (!PropertyBagValueAccess.TrySetValue(ref updated, Components.GetComponentType(componentId), path, next))
908
901
  {
909
- Debug.LogWarning($"Could not edit {descriptor.Name}: the property path is unavailable.");
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.Integration.TryWrite(entity, descriptor.Id, updated, out EcsWriteError writeError))
907
+ if (!world.TryWrite(entity, componentId, updated))
915
908
  {
916
- Debug.LogWarning($"Could not edit {descriptor.Name}: {writeError.Code}.");
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 world = _target.RuntimeWorld;
947
+ SceneWorld sceneWorld = _target.RuntimeWorld;
955
948
  Entity entity = _target.RuntimeEntity;
956
- if (world == null || !world.IsBound || !world.Integration.IsAlive(entity))
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 (!world.TryGetComponents(entity, _runtimeComponentBuffer, out int count)
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 (!world.Integration.TryRead(entity, binding.Descriptor.Id, out ComponentSnapshot snapshot, out _))
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(snapshot.Value, binding.Descriptor.ValueType,
1010
- property.Path, out object value))
1016
+ if (PropertyBagValueAccess.TryGetValue(componentValue, Components.GetComponentType(binding.Component),
1017
+ property.Path, out object fieldValue))
1011
1018
  {
1012
- SetRuntimeFieldValue(control, property.ValueType, value, world);
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, TryGetDescriptor(data, descriptors)))
1094
- .OrderBy(entry => entry.Descriptor.HasValue ? GetComponentOrder(entry.Descriptor.Value.Schema.Value) : int.MaxValue)
1095
- .ThenBy(entry => entry.Descriptor.HasValue
1096
- ? GetShortTypeName(entry.Descriptor.Value.ValueType)
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, ComponentDescriptor descriptor)
1104
+ private void AddComponent(EntityAuthoring authoring, ComponentId componentId)
1102
1105
  {
1103
- Undo.RecordObject(Authoring, $"Add {GetShortTypeName(descriptor.ValueType)}");
1104
- ComponentData data = ComponentData.CreateDefault(descriptor);
1105
- if (!_previewWorld.AddComponent(authoring, descriptor, data, out EcsWriteError error, out string failureReason))
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(descriptor.ValueType)}: {failureReason ?? error.Code.ToString()}.", Authoring);
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
- ComponentDescriptor? descriptor = null)
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 (!descriptor.HasValue && _previewWorld.TryGetDescriptor(data, out ComponentDescriptor resolved))
1125
+ if (!componentId.HasValue && _previewWorld.TryGetComponentId(data, out ComponentId resolved))
1123
1126
  {
1124
- descriptor = resolved;
1127
+ componentId = resolved;
1125
1128
  }
1126
1129
 
1127
- if (!descriptor.HasValue)
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
- ComponentDescriptor component = descriptor.Value;
1137
- Undo.RecordObject(Authoring, $"Remove {GetShortTypeName(component.ValueType)}");
1138
- if (!_previewWorld.RemoveComponent(authoring, component, out EcsWriteError error))
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.ValueType)}: {error.Code}.", Authoring);
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, ComponentDescriptor descriptor)
1152
+ private void ResetComponent(EntityAuthoring authoring, ComponentData data, ComponentId componentId)
1150
1153
  {
1151
- Undo.RecordObject(Authoring, $"Reset {GetShortTypeName(descriptor.ValueType)}");
1152
- object value = Activator.CreateInstance(descriptor.ValueType);
1153
- if (_previewWorld.TryWrite(authoring, data, descriptor, value, out EcsWriteError error)) MarkSceneDirty();
1154
- else Debug.LogError($"Could not reset {GetShortTypeName(descriptor.ValueType)}: {error.Code}.", Authoring);
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.Descriptor?.Schema.Value == schema);
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 ComponentDescriptor? Descriptor;
1205
- public ComponentEntry(ComponentData data, ComponentDescriptor? descriptor)
1207
+ public readonly ComponentId? Component;
1208
+ public ComponentEntry(ComponentData data, ComponentId? componentId)
1206
1209
  {
1207
1210
  Data = data;
1208
- Descriptor = descriptor;
1211
+ Component = componentId;
1209
1212
  }
1210
1213
  }
1211
1214
 
1212
1215
  private readonly struct RuntimeValueBinding
1213
1216
  {
1214
- public readonly ComponentDescriptor Descriptor;
1217
+ public readonly ComponentId Component;
1215
1218
  public readonly ComponentPropertyBinding[] Properties;
1216
1219
 
1217
- public RuntimeValueBinding(ComponentDescriptor descriptor, ComponentPropertyBinding[] properties)
1220
+ public RuntimeValueBinding(ComponentId componentId, ComponentPropertyBinding[] properties)
1218
1221
  {
1219
- Descriptor = descriptor;
1222
+ Component = componentId;
1220
1223
  Properties = properties;
1221
1224
  }
1222
1225
  }
package/README.md CHANGED
@@ -18,7 +18,7 @@ Add the npm-compatible registry and package to the Unity project's
18
18
  }
19
19
  ],
20
20
  "dependencies": {
21
- "com.artromskiy.deltaecs.unity": "0.0.61"
21
+ "com.artromskiy.deltaecs.unity": "0.0.63"
22
22
  }
23
23
  }
24
24
  ```
@@ -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(ComponentDescriptor descriptor)
30
+ public static ComponentData CreateDefault(ComponentRegistry components, ComponentId componentId)
32
31
  {
33
- if (descriptor.IsTag)
32
+ if (components.IsTag(componentId))
34
33
  {
35
- return new ComponentData(descriptor.Schema.Value, "{}");
34
+ return new ComponentData(components.GetSchemaId(componentId).Value, "{}");
36
35
  }
37
36
 
38
- object value = Activator.CreateInstance(descriptor.ValueType);
39
- return new ComponentData(descriptor.Schema.Value, JsonUtility.ToJson(value));
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)
@@ -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,10 +24,10 @@ 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;
30
+ private readonly ComponentId _hiddenEntityHierarchyComponentId;
32
31
  private bool _disposed;
33
32
 
34
33
  public World World => _world;
@@ -42,27 +41,21 @@ namespace Delta.ECS.Unity
42
41
  return entities;
43
42
  }
44
43
  }
45
- internal IEcsWorld Integration => _integration;
44
+ internal ComponentId HiddenEntityHierarchyComponentId => _hiddenEntityHierarchyComponentId;
46
45
  internal SceneData SceneData => _sceneData;
47
46
  internal Scene UnityScene => _authoring != null ? _authoring.gameObject.scene : default;
48
47
  internal bool IsBound => !_disposed;
49
48
 
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)
49
+ private SceneWorld(World world,
50
+ SceneData sceneData, SceneAuthoring authoring, bool ownsWorld, bool registerLiveWorld)
57
51
  {
58
52
  _world = world ?? UnityThrowHelpers.ThrowArgumentNull<World>(nameof(world));
59
53
  _sceneData = sceneData ?? UnityThrowHelpers.ThrowArgumentNull<SceneData>(nameof(sceneData));
60
54
  _authoring = authoring;
61
- _integration = world;
62
55
  _ownsWorld = ownsWorld;
56
+ _hiddenEntityHierarchyComponentId = world.Components.GetPrimary<HideFromEntityHierarchy>();
63
57
 
64
58
  _sceneData.EnsureStableIds();
65
- _integration.Initialize();
66
59
  RebuildAuthoringEntities();
67
60
  if (registerLiveWorld)
68
61
  {
@@ -70,7 +63,7 @@ namespace Delta.ECS.Unity
70
63
  }
71
64
  }
72
65
 
73
- /// <summary>Returns the integration-owned runtime context for a loaded Unity scene.</summary>
66
+ /// <summary>Returns the runtime context for a loaded Unity scene.</summary>
74
67
  public static SceneWorld GetForScene(Scene scene) => SceneWorldRuntime.GetForScene(scene);
75
68
 
76
69
  /// <summary>Resolves the live ECS world and entity currently associated with a Unity view.</summary>
@@ -90,7 +83,7 @@ namespace Delta.ECS.Unity
90
83
  /// <summary>Registers a transient runtime association; it is not written into scene data.</summary>
91
84
  public bool BindView(Entity entity, GameObject view)
92
85
  {
93
- if (view == null || !_integration.IsAlive(entity))
86
+ if (view == null || !_world.IsAlive(entity))
94
87
  {
95
88
  return false;
96
89
  }
@@ -125,7 +118,7 @@ namespace Delta.ECS.Unity
125
118
  {
126
119
  foreach (Entity candidate in _entitiesByStableId.Values)
127
120
  {
128
- if (_integration.IsAlive(candidate) && _world.Has(candidate, componentId))
121
+ if (_world.IsAlive(candidate) && _world.Has(candidate, componentId))
129
122
  {
130
123
  entity = candidate;
131
124
  return true;
@@ -156,7 +149,6 @@ namespace Delta.ECS.Unity
156
149
  _stableIdsByEntity.Clear();
157
150
  _viewsByEntity.Clear();
158
151
  _entitiesByView.Clear();
159
- _integration.Shutdown();
160
152
 
161
153
  if (_ownsWorld)
162
154
  {
@@ -217,7 +209,7 @@ namespace Delta.ECS.Unity
217
209
 
218
210
  internal static SceneWorld CreatePreview(SceneData sceneData)
219
211
  {
220
- var world = CreateWorld(DefaultEntityCapacity);
212
+ World world = CreateWorld(DefaultEntityCapacity);
221
213
  try
222
214
  {
223
215
  return new SceneWorld(world, sceneData, null,
@@ -237,7 +229,7 @@ namespace Delta.ECS.Unity
237
229
  UnityThrowHelpers.ThrowArgumentNull(nameof(authoring));
238
230
  }
239
231
 
240
- var world = CreateWorld(DefaultEntityCapacity);
232
+ World world = CreateWorld(DefaultEntityCapacity);
241
233
  try
242
234
  {
243
235
  return new SceneWorld(world, authoring.SceneData, authoring,
@@ -257,7 +249,7 @@ namespace Delta.ECS.Unity
257
249
  UnityThrowHelpers.ThrowArgumentNull(nameof(authoring));
258
250
  }
259
251
 
260
- var world = CreateWorld(RuntimeEntityCapacity);
252
+ World world = CreateWorld(RuntimeEntityCapacity);
261
253
  try
262
254
  {
263
255
  return new SceneWorld(world, authoring.SceneData, authoring,
@@ -292,10 +284,10 @@ namespace Delta.ECS.Unity
292
284
  for (int componentIndex = 0; componentIndex < authoring.Components.Count; componentIndex++)
293
285
  {
294
286
  ComponentData data = authoring.Components[componentIndex];
295
- if (TryGetDescriptor(data, out ComponentDescriptor descriptor)
296
- && seenSchemas.Add(descriptor.Schema.Value))
287
+ if (TryGetComponentId(data, out ComponentId componentId)
288
+ && seenSchemas.Add(_world.Components.GetSchemaId(componentId).Value))
297
289
  {
298
- componentIds.Add(descriptor.Id);
290
+ componentIds.Add(componentId);
299
291
  }
300
292
  else
301
293
  {
@@ -303,7 +295,7 @@ namespace Delta.ECS.Unity
303
295
  }
304
296
  }
305
297
 
306
- Entity entity = _integration.Create(componentIds.ToArray());
298
+ Entity entity = _world.Create(componentIds.ToArray());
307
299
  _entitiesByStableId.Add(authoring.StableId, entity);
308
300
  _stableIdsByEntity.Add(entity, authoring.StableId);
309
301
  }
@@ -320,21 +312,21 @@ namespace Delta.ECS.Unity
320
312
  for (int componentIndex = 0; componentIndex < authoring.Components.Count; componentIndex++)
321
313
  {
322
314
  ComponentData data = authoring.Components[componentIndex];
323
- if (!TryGetDescriptor(data, out ComponentDescriptor descriptor))
315
+ if (!TryGetComponentId(data, out ComponentId componentId))
324
316
  {
325
317
  continue;
326
318
  }
327
319
 
328
- if (descriptor.IsTag)
320
+ if (_world.Components.IsTag(componentId))
329
321
  {
330
322
  continue;
331
323
  }
332
324
 
333
- object value = data.CreateValue(descriptor.ValueType, ResolveEntity);
334
- if (_integration.TryRead(entity, descriptor.Id, out _, out _)
335
- && !_integration.TryWrite(entity, descriptor.Id, value, out EcsWriteError error))
325
+ object value = data.CreateValue(_world.Components.GetComponentType(componentId), ResolveEntity);
326
+ if (TryRead(entity, componentId, out _)
327
+ && !_world.TryWrite(entity, componentId, value))
336
328
  {
337
- Debug.LogError($"Failed to load {descriptor.Name} on '{authoring.Name}': {error.Code}.");
329
+ Debug.LogError($"Failed to load {_world.Components.GetComponentType(componentId).FullName ?? _world.Components.GetComponentType(componentId).Name} on '{authoring.Name}'.");
338
330
  }
339
331
  }
340
332
  }
@@ -366,7 +358,7 @@ namespace Delta.ECS.Unity
366
358
  internal bool TryGetEntity(GameObject view, out Entity entity)
367
359
  {
368
360
  if (view != null && _entitiesByView.TryGetValue(view.GetEntityId(), out entity)
369
- && _integration.IsAlive(entity))
361
+ && _world.IsAlive(entity))
370
362
  {
371
363
  return true;
372
364
  }
@@ -374,7 +366,7 @@ namespace Delta.ECS.Unity
374
366
  if (view != null && _authoring != null
375
367
  && _authoring.TryGetStableId(view, out string stableId)
376
368
  && _entitiesByStableId.TryGetValue(stableId, out entity)
377
- && _integration.IsAlive(entity))
369
+ && _world.IsAlive(entity))
378
370
  {
379
371
  return true;
380
372
  }
@@ -383,56 +375,42 @@ namespace Delta.ECS.Unity
383
375
  return false;
384
376
  }
385
377
 
386
- internal bool TryGetDescriptor(ComponentData data, out ComponentDescriptor descriptor)
378
+ internal bool TryGetComponentId(ComponentData data, out ComponentId componentId)
387
379
  {
388
- descriptor = default;
389
- if (data == null || !data.TryGetSchemaId(out SchemaId schema))
390
- {
391
- return false;
392
- }
393
-
394
- ReadOnlyMemory<ComponentDescriptor> catalog = _integration.Catalog.Components;
395
- for (int i = 0; i < catalog.Length; i++)
396
- {
397
- if (catalog.Span[i].Schema == schema)
398
- {
399
- descriptor = catalog.Span[i];
400
- return true;
401
- }
402
- }
403
-
404
- return false;
380
+ componentId = ComponentId.Invalid;
381
+ return data != null && data.TryGetSchemaId(out SchemaId schema)
382
+ && _world.Components.TryGetComponentId(schema, out componentId);
405
383
  }
406
384
 
407
- internal bool TryRead(EntityAuthoring authoring, ComponentDescriptor descriptor,
408
- out ComponentSnapshot snapshot, out EcsReadError error)
385
+ internal bool TryRead(EntityAuthoring authoring, ComponentId componentId, out object? value)
409
386
  {
410
387
  if (TryGetEntity(authoring, out Entity entity))
411
388
  {
412
- return TryRead(entity, descriptor, out snapshot, out error);
389
+ return TryRead(entity, componentId, out value);
413
390
  }
414
391
 
415
- snapshot = default;
416
- error = default;
392
+ value = null;
417
393
  return false;
418
394
  }
419
395
 
420
- internal bool TryRead(Entity entity, ComponentDescriptor descriptor,
421
- out ComponentSnapshot snapshot, out EcsReadError error)
422
- => _integration.TryRead(entity, descriptor.Id, out snapshot, out error);
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);
423
401
 
424
402
  internal bool TryGetComponents(Entity entity, Span<ComponentId> destination, out int totalCount)
425
403
  {
426
404
  totalCount = 0;
427
- if (!_integration.IsAlive(entity))
405
+ if (!_world.IsAlive(entity))
428
406
  {
429
407
  return false;
430
408
  }
431
409
 
432
- ReadOnlyMemory<ComponentDescriptor> components = _integration.Catalog.Components;
410
+ ReadOnlySpan<ComponentId> components = _world.Components.GetComponentIds();
433
411
  for (int index = 0; index < components.Length; index++)
434
412
  {
435
- ComponentId component = components.Span[index].Id;
413
+ ComponentId component = components[index];
436
414
  if (!_world.Has(entity, component))
437
415
  {
438
416
  continue;
@@ -450,26 +428,14 @@ namespace Delta.ECS.Unity
450
428
  }
451
429
 
452
430
  internal bool TryWrite(EntityAuthoring authoring, ComponentData data,
453
- ComponentDescriptor descriptor, object value, out EcsWriteError error)
431
+ ComponentId componentId, object value)
454
432
  {
455
- if (!TryGetEntity(authoring, out Entity entity) || !_integration.IsAlive(entity))
433
+ if (!TryGetEntity(authoring, out Entity entity) || !_world.TryWrite(entity, componentId, value))
456
434
  {
457
- error = new EcsWriteError(EcsWriteErrorCode.EntityNotAlive);
458
435
  return false;
459
436
  }
460
437
 
461
- if (!_integration.TryRead(entity, descriptor.Id, out ComponentSnapshot snapshot, out _))
462
- {
463
- error = new EcsWriteError(EcsWriteErrorCode.ComponentMissing);
464
- return false;
465
- }
466
-
467
- if (!_integration.TryWrite(entity, descriptor.Id, value, out error))
468
- {
469
- return false;
470
- }
471
-
472
- if (descriptor.IsTag)
438
+ if (_world.Components.IsTag(componentId))
473
439
  {
474
440
  data.StoreDefaultTag();
475
441
  }
@@ -481,60 +447,41 @@ namespace Delta.ECS.Unity
481
447
  return true;
482
448
  }
483
449
 
484
- internal bool AddComponent(EntityAuthoring authoring, ComponentDescriptor descriptor,
485
- ComponentData data, out EcsWriteError error, out string failureReason)
450
+ internal bool AddComponent(EntityAuthoring authoring, ComponentId componentId,
451
+ ComponentData data, out string failureReason)
486
452
  {
487
453
  failureReason = null;
488
454
  if (!TryGetEntity(authoring, out Entity entity))
489
455
  {
490
- error = new EcsWriteError(EcsWriteErrorCode.EntityNotAlive);
491
456
  failureReason = "The authored entity is not bound to the preview world. Rebuild the preview and try again.";
492
457
  return false;
493
458
  }
494
459
 
495
- if (!_integration.IsAlive(entity))
460
+ if (!_world.IsAlive(entity))
496
461
  {
497
- error = new EcsWriteError(EcsWriteErrorCode.EntityNotAlive);
498
462
  failureReason = "The entity is no longer alive in the preview world.";
499
463
  return false;
500
464
  }
501
465
 
502
- if (!_integration.Add(entity, new[] { descriptor.Id }))
466
+ if (!_world.Add(entity, componentId))
503
467
  {
504
- error = default;
505
- failureReason = _world.Has(entity, descriptor.Id)
468
+ failureReason = _world.Has(entity, componentId)
506
469
  ? "The component is already present in the preview world."
507
470
  : "DeltaECS rejected the structural add without reporting a write error.";
508
471
  return false;
509
472
  }
510
473
 
511
- if (descriptor.IsTag)
474
+ if (_world.Components.IsTag(componentId))
512
475
  {
513
476
  data.StoreDefaultTag();
514
- error = default;
515
477
  return true;
516
478
  }
517
479
 
518
- object value = data.CreateValue(descriptor.ValueType, ResolveEntity);
519
- if (!_integration.TryRead(entity, descriptor.Id, out ComponentSnapshot snapshot, out EcsReadError readError))
480
+ object value = data.CreateValue(_world.Components.GetComponentType(componentId), ResolveEntity);
481
+ if (!_world.TryWrite(entity, componentId, value))
520
482
  {
521
- _integration.Remove(entity, new[] { descriptor.Id });
522
- error = new EcsWriteError(readError.Code switch
523
- {
524
- EcsReadErrorCode.EntityNotAlive => EcsWriteErrorCode.EntityNotAlive,
525
- EcsReadErrorCode.ComponentUnknown => EcsWriteErrorCode.ComponentUnknown,
526
- EcsReadErrorCode.ComponentMissing => EcsWriteErrorCode.ComponentMissing,
527
- EcsReadErrorCode.Unsupported => EcsWriteErrorCode.Unsupported,
528
- _ => EcsWriteErrorCode.None
529
- });
530
- failureReason = $"The new component could not be read from the preview world ({readError.Code}).";
531
- return false;
532
- }
533
-
534
- if (!_integration.TryWrite(entity, descriptor.Id, value, out error))
535
- {
536
- _integration.Remove(entity, new[] { descriptor.Id });
537
- failureReason = $"The default component value could not be written ({error.Code}).";
483
+ _world.Remove(entity, componentId);
484
+ failureReason = "The default component value could not be written.";
538
485
  return false;
539
486
  }
540
487
 
@@ -542,13 +489,8 @@ namespace Delta.ECS.Unity
542
489
  return true;
543
490
  }
544
491
 
545
- internal bool RemoveComponent(EntityAuthoring authoring, ComponentDescriptor descriptor,
546
- out EcsWriteError error)
547
- {
548
- error = default;
549
- return TryGetEntity(authoring, out Entity entity)
550
- && _integration.Remove(entity, new[] { descriptor.Id });
551
- }
492
+ internal bool RemoveComponent(EntityAuthoring authoring, ComponentId componentId)
493
+ => TryGetEntity(authoring, out Entity entity) && _world.Remove(entity, componentId);
552
494
 
553
495
  internal bool TryGetAuthoring(string stableId, out EntityAuthoring authoring)
554
496
  {
@@ -570,6 +512,7 @@ namespace Delta.ECS.Unity
570
512
  private static World CreateWorld(int initialEntityCapacity)
571
513
  {
572
514
  var layouts = new ComponentRegistry();
515
+ layouts.Register<HideFromEntityHierarchy>(new SchemaId(ViewComponentSchemaIds.HideFromEntityHierarchy));
573
516
  foreach (IGeneratedComponentRegistration registration in GeneratedComponentCatalog.GetRegistrations())
574
517
  {
575
518
  layouts.Register(registration);
@@ -582,9 +525,9 @@ namespace Delta.ECS.Unity
582
525
  {
583
526
  foreach (Entity entity in _entitiesByStableId.Values)
584
527
  {
585
- if (_integration.IsAlive(entity))
528
+ if (_world.IsAlive(entity))
586
529
  {
587
- _integration.Destroy(entity);
530
+ _world.Destroy(entity);
588
531
  }
589
532
  }
590
533
  }
@@ -2,6 +2,7 @@ using Delta.ECS;
2
2
 
3
3
  namespace Delta.ECS.Unity
4
4
  {
5
+
5
6
  /// <summary>Receives the entity context after a Unity view is bound to an entity.</summary>
6
7
  public interface IEntityView
7
8
  {
@@ -10,7 +11,7 @@ namespace Delta.ECS.Unity
10
11
  }
11
12
 
12
13
  /// <summary>Selects the Unity prefab used to represent an entity.</summary>
13
- [ComponentSchema(0x405B11F5A17E14A1UL)]
14
+ [ComponentSchema(ViewComponentSchemaIds.ViewToken)]
14
15
  public readonly struct ViewToken
15
16
  {
16
17
  /// <summary>Gets the identifier of the view prefab in a <see cref="ViewPrefabCatalog"/>.</summary>
@@ -21,8 +22,21 @@ namespace Delta.ECS.Unity
21
22
  }
22
23
 
23
24
  /// <summary>Marks an entity whose Unity view has already been bound.</summary>
24
- [ComponentSchema(0xB31CB42A81D3B164UL)]
25
+ [ComponentSchema(ViewComponentSchemaIds.ViewBound)]
25
26
  public struct ViewBound
26
27
  {
27
28
  }
29
+
30
+ /// <summary>Hides an unbound ECS entity from the Unity Hierarchy window while this tag is present.</summary>
31
+ /// <remarks>Entities bound to a GameObject keep their normal Unity hierarchy visibility.</remarks>
32
+ [ComponentSchema(ViewComponentSchemaIds.HideFromEntityHierarchy)]
33
+ public readonly struct HideFromEntityHierarchy
34
+ {
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
+ }
28
42
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "com.artromskiy.deltaecs.unity",
3
- "version": "0.0.61",
3
+ "version": "0.0.63",
4
4
  "displayName": "DeltaECS Unity",
5
5
  "description": "Unity scene authoring and editor integration for DeltaECS.",
6
6
  "unity": "6000.7",