From 5117b695007b77c357d46e3b64b7b2721b4a45c2 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Thu, 29 Sep 2022 01:26:51 +0200 Subject: [PATCH] Fix RefCollection and start using it to query multiple users - I overcomplicated in the beginning - It doesn't shorten the code that much but it provides a stable interface and it's easier to use so I guess it's nice --- .../Blocks/Engines/SignalEngine.cs | 13 +-- .../Utility/ManagedApiExtensions.cs | 5 +- .../Utility/NativeApiExtensions.cs | 19 ++-- TechbloxModdingAPI/Utility/OptionalRef.cs | 5 + TechbloxModdingAPI/Utility/RefCollection.cs | 95 ++++++++----------- 5 files changed, 64 insertions(+), 73 deletions(-) diff --git a/TechbloxModdingAPI/Blocks/Engines/SignalEngine.cs b/TechbloxModdingAPI/Blocks/Engines/SignalEngine.cs index a30f638..75dbddc 100644 --- a/TechbloxModdingAPI/Blocks/Engines/SignalEngine.cs +++ b/TechbloxModdingAPI/Blocks/Engines/SignalEngine.cs @@ -281,17 +281,14 @@ namespace TechbloxModdingAPI.Blocks.Engines for (int startIndex = 0; startIndex < startPorts.Length; startIndex++) { PortEntityStruct startPES = entitiesDB.QueryEntity(startPorts[startIndex]); - foreach (var wire in entitiesDB.QueryEntitiesOptional( + foreach (var wireOpt in entitiesDB.QueryEntitiesOptional( NamedExclusiveGroup.Group)) { - - } - for (int w = 0; w < count; w++) - { - if ((wires[w].destinationPortUsage == endPES.usage && wires[w].destinationBlockEGID == endBlock) - && (wires[w].sourcePortUsage == startPES.usage && wires[w].sourceBlockEGID == startBlock)) + var wire = wireOpt.Get(); + if ((wire.destinationPortUsage == endPES.usage && wire.destinationBlockEGID == endBlock) + && (wire.sourcePortUsage == startPES.usage && wire.sourceBlockEGID == startBlock)) { - return new EGID(ids[w], NamedExclusiveGroup.Group); + return wireOpt.EGID; } } } diff --git a/TechbloxModdingAPI/Utility/ManagedApiExtensions.cs b/TechbloxModdingAPI/Utility/ManagedApiExtensions.cs index fb8d758..cf61e14 100644 --- a/TechbloxModdingAPI/Utility/ManagedApiExtensions.cs +++ b/TechbloxModdingAPI/Utility/ManagedApiExtensions.cs @@ -68,9 +68,10 @@ namespace TechbloxModdingAPI.Utility /// /// /// - public static RefCollection QueryEntitiesOptional(this EntitiesDB entitiesDB, ExclusiveGroupStruct group) where T : struct, IBaseEntityComponent + public static RefCollection QueryEntitiesOptional(this EntitiesDB entitiesDB, ExclusiveGroupStruct group) where T : struct, IEntityViewComponent { - return entitiesDB.QueryEntities(group); + var (buffer, ids, count) = entitiesDB.QueryEntities(group); + return new RefCollection(count, buffer, ids, group); } } } \ No newline at end of file diff --git a/TechbloxModdingAPI/Utility/NativeApiExtensions.cs b/TechbloxModdingAPI/Utility/NativeApiExtensions.cs index a673bc4..c20a4b2 100644 --- a/TechbloxModdingAPI/Utility/NativeApiExtensions.cs +++ b/TechbloxModdingAPI/Utility/NativeApiExtensions.cs @@ -102,14 +102,19 @@ namespace TechbloxModdingAPI.Utility ChangesToPublish[typeof(T)] = (0, changes); } - public static IEnumerable QueryEntities(this EntitiesDB entitiesDB, ExclusiveGroupStruct group, - ManagedApiExtensions.EntityEnumeratorSelect select) where T : unmanaged, IEntityComponent + /// + /// Query entities as OptionalRefs. The elements always exist, it's just a nice way to encapsulate the data. + /// + /// + /// + /// + /// + /// + /// + public static RefCollection QueryEntitiesOptional(this EntitiesDB entitiesDB, ExclusiveGroupStruct group) where T : unmanaged, IEntityComponent { - var (coll, ids, count) = entitiesDB.QueryEntities(group); - for (uint i = 0; i < count; i++) - { - yield return select(ref coll[i], new EGID(ids[i], group)); - } + var (buffer, ids, count) = entitiesDB.QueryEntities(group); + return new RefCollection(count, buffer, ids, group); } } } \ No newline at end of file diff --git a/TechbloxModdingAPI/Utility/OptionalRef.cs b/TechbloxModdingAPI/Utility/OptionalRef.cs index e1dfb4b..b89ff88 100644 --- a/TechbloxModdingAPI/Utility/OptionalRef.cs +++ b/TechbloxModdingAPI/Utility/OptionalRef.cs @@ -77,6 +77,11 @@ namespace TechbloxModdingAPI.Utility set => Get() = value; } + /// + /// The ID of the entity this component belongs to. + /// + public EGID EGID => entityId; + public bool Exists => state != State.Empty; public T? Nullable() => this ? Get() : default; diff --git a/TechbloxModdingAPI/Utility/RefCollection.cs b/TechbloxModdingAPI/Utility/RefCollection.cs index 13a91d2..be76390 100644 --- a/TechbloxModdingAPI/Utility/RefCollection.cs +++ b/TechbloxModdingAPI/Utility/RefCollection.cs @@ -6,83 +6,66 @@ using Svelto.ECS.Internal; namespace TechbloxModdingAPI.Utility { - public ref struct RefCollection where T : struct, IBaseEntityComponent + public readonly ref struct RefCollection where T : struct, IBaseEntityComponent { private readonly bool managed; - private int count; - private NB nativeArray; - private MB managedArray; - private NativeEntityIDs nativeIDs; - private ManagedEntityIDs managedIDs; + private readonly int count; + private readonly NB nativeArray; + private readonly MB managedArray; + private readonly NativeEntityIDs nativeIDs; + private readonly ManagedEntityIDs managedIDs; + private readonly ExclusiveGroupStruct group; - private RefCollection(EntityCollection coll, T inst = default) + public RefCollection(int count, MB managedArray, ManagedEntityIDs managedIDs, ExclusiveGroupStruct group) { - if (inst is IEntityComponent) - { - DeconstructCollection(coll); - } - if (typeof(T).IsAssignableFrom(typeof(IEntityViewComponent))) - { - (managedArray, managedIDs, count) = coll2; - } + this.count = count; + this.managedArray = managedArray; + this.managedIDs = managedIDs; + this.group = group; + managed = true; + nativeArray = default; + nativeIDs = default; } - private void DeconstructCollection(EntityCollection coll) where TM : struct, IEntityViewComponent - where TN : unmanaged, IEntityComponent + public RefCollection(int count, NB nativeArray, NativeEntityIDs nativeIDs, ExclusiveGroupStruct group) { - switch (coll) - { - case EntityCollection cm: - { - MB ma; - (ma, managedIDs, count) = cm; - if (ma is MB mb) - managedArray = mb; - else - throw new InvalidCastException("Expected managed buffer in managed entity collection! Wut"); - break; - } - case EntityCollection cn: - { - NB na; - (na, nativeIDs, count) = cn; - if (na is NB nb) - nativeArray = nb; - else - throw new InvalidCastException("Expected native buffer in native entity collection! Wut"); - break; - } - } - } - - public static implicit operator RefCollection(EntityCollection coll) - { - return new RefCollection(coll); + this.count = count; + this.nativeArray = nativeArray; + this.nativeIDs = nativeIDs; + this.group = group; + managed = false; } public Enumerator GetEnumerator() => new(this); public ref struct Enumerator { - private RefCollection collection; - private uint index; + private RefCollection coll; + private int index; + public Enumerator(RefCollection collection) { - index = default; - this.collection = collection; + index = -1; + coll = collection; } - public OptionalRef Current => collection.coll.[index]; + public OptionalRef Current + { + get + { + if (coll.count <= index && index >= 0) return default; + if (coll.managed) + return new OptionalRef(coll.managedArray, (uint)index, + new EGID(coll.managedIDs[index], coll.group)); + return new OptionalRef(coll.nativeArray, (uint)index, + new EGID(coll.nativeIDs[index], coll.group)); + } + } public bool MoveNext() { - return true; + return ++index < coll.count; } } - - private static void Test(EntityCollection coll) where TN : unmanaged, IEntityComponent - { - - } } } \ No newline at end of file