From a2a81bf47790dc88102afd6c12a0986de1c08b85 Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Tue, 10 Oct 2023 11:59:28 -0700 Subject: [PATCH] world transfer determinism --- src/DebugSystem.cs | 29 ++++++++++++++++++++++++----- src/EntityStorage.cs | 13 +++++++------ src/FilterSignature.cs | 2 -- src/FilterStorage.cs | 8 +++++--- 4 files changed, 36 insertions(+), 16 deletions(-) diff --git a/src/DebugSystem.cs b/src/DebugSystem.cs index de9027a..fcffd9e 100644 --- a/src/DebugSystem.cs +++ b/src/DebugSystem.cs @@ -13,12 +13,9 @@ namespace MoonTools.ECS { } - protected IEnumerable Debug_GetAllComponents(Entity entity) + protected ComponentEnumerator Debug_GetAllComponents(Entity entity) { - foreach (var typeIndex in EntityStorage.ComponentTypeIndices(entity.ID)) - { - yield return ComponentDepot.Debug_Get(entity.ID, typeIndex); - } + return new ComponentEnumerator(ComponentDepot, entity, EntityStorage.ComponentTypeIndices(entity.ID)); } protected IEnumerable Debug_GetEntities(Type componentType) @@ -39,6 +36,28 @@ namespace MoonTools.ECS } } } + + public ref struct ComponentEnumerator + { + private ComponentDepot ComponentDepot; + private Entity Entity; + private ReverseSpanEnumerator ComponentTypeIndices; + + public ComponentEnumerator GetEnumerator() => this; + + internal ComponentEnumerator( + ComponentDepot componentDepot, + Entity entity, + Collections.IndexableSet componentTypeIndices + ) { + ComponentDepot = componentDepot; + Entity = entity; + ComponentTypeIndices = componentTypeIndices.GetEnumerator(); + } + + public bool MoveNext() => ComponentTypeIndices.MoveNext(); + public object Current => ComponentDepot.Debug_Get(Entity.ID, ComponentTypeIndices.Current); + } } } #endif diff --git a/src/EntityStorage.cs b/src/EntityStorage.cs index b73ad05..3ff05de 100644 --- a/src/EntityStorage.cs +++ b/src/EntityStorage.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using MoonTools.ECS.Collections; namespace MoonTools.ECS { @@ -10,8 +11,8 @@ namespace MoonTools.ECS // FIXME: this is only needed in debug mode private readonly HashSet availableIDHash = new HashSet(); - private Dictionary> EntityToComponentTypeIndices = new Dictionary>(); - private Dictionary> EntityToRelationTypeIndices = new Dictionary>(); + private Dictionary> EntityToComponentTypeIndices = new Dictionary>(); + private Dictionary> EntityToRelationTypeIndices = new Dictionary>(); public int Count => nextID - availableIDs.Count; @@ -23,12 +24,12 @@ namespace MoonTools.ECS if (!EntityToComponentTypeIndices.ContainsKey(entity.ID)) { - EntityToComponentTypeIndices.Add(entity.ID, new HashSet()); + EntityToComponentTypeIndices.Add(entity.ID, new IndexableSet()); } if (!EntityToRelationTypeIndices.ContainsKey(entity.ID)) { - EntityToRelationTypeIndices.Add(entity.ID, new HashSet()); + EntityToRelationTypeIndices.Add(entity.ID, new IndexableSet()); } Tags[entity.ID] = tag; @@ -86,12 +87,12 @@ namespace MoonTools.ECS return Tags[entityID]; } - public HashSet ComponentTypeIndices(int entityID) + public IndexableSet ComponentTypeIndices(int entityID) { return EntityToComponentTypeIndices[entityID]; } - public HashSet RelationTypeIndices(int entityID) + public IndexableSet RelationTypeIndices(int entityID) { return EntityToRelationTypeIndices[entityID]; } diff --git a/src/FilterSignature.cs b/src/FilterSignature.cs index f0eeaba..7e94922 100644 --- a/src/FilterSignature.cs +++ b/src/FilterSignature.cs @@ -22,8 +22,6 @@ namespace MoonTools.ECS public bool Equals(FilterSignature other) { - // workaround for HashSet.SetEquals generating garbage - // maybe fixed in .NET 8? foreach (var included in Included) { if (!other.Included.Contains(included)) diff --git a/src/FilterStorage.cs b/src/FilterStorage.cs index 3cdf170..9d10c2c 100644 --- a/src/FilterStorage.cs +++ b/src/FilterStorage.cs @@ -148,10 +148,12 @@ namespace MoonTools.ECS } } - filterSignatureToEntityIDs[filterSignature].Add(entityID); - if (addCallbacks.TryGetValue(filterSignature, out var addCallback)) + if (filterSignatureToEntityIDs[filterSignature].Add(entityID)) { - addCallback(entityID); + if (addCallbacks.TryGetValue(filterSignature, out var addCallback)) + { + addCallback(entityID); + } } }