Browse Source

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
feature/tb.update
NorbiPeti 1 year ago
parent
commit
5117b69500
Signed by: NorbiPeti <szatmari.norbert.peter@gmail.com> GPG Key ID: DBA4C4549A927E56
5 changed files with 64 additions and 73 deletions
  1. +5
    -8
      TechbloxModdingAPI/Blocks/Engines/SignalEngine.cs
  2. +3
    -2
      TechbloxModdingAPI/Utility/ManagedApiExtensions.cs
  3. +12
    -7
      TechbloxModdingAPI/Utility/NativeApiExtensions.cs
  4. +5
    -0
      TechbloxModdingAPI/Utility/OptionalRef.cs
  5. +39
    -56
      TechbloxModdingAPI/Utility/RefCollection.cs

+ 5
- 8
TechbloxModdingAPI/Blocks/Engines/SignalEngine.cs View File

@@ -281,17 +281,14 @@ namespace TechbloxModdingAPI.Blocks.Engines
for (int startIndex = 0; startIndex < startPorts.Length; startIndex++)
{
PortEntityStruct startPES = entitiesDB.QueryEntity<PortEntityStruct>(startPorts[startIndex]);
foreach (var wire in entitiesDB.QueryEntitiesOptional<WireEntityStruct>(
foreach (var wireOpt in entitiesDB.QueryEntitiesOptional<WireEntityStruct>(
NamedExclusiveGroup<BuildModeWiresGroups.WiresGroup>.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<BuildModeWiresGroups.WiresGroup>.Group);
return wireOpt.EGID;
}
}
}


+ 3
- 2
TechbloxModdingAPI/Utility/ManagedApiExtensions.cs View File

@@ -68,9 +68,10 @@ namespace TechbloxModdingAPI.Utility
/// <typeparam name="T"></typeparam>
/// <typeparam name="TR"></typeparam>
/// <returns></returns>
public static RefCollection<T> QueryEntitiesOptional<T>(this EntitiesDB entitiesDB, ExclusiveGroupStruct group) where T : struct, IBaseEntityComponent
public static RefCollection<T> QueryEntitiesOptional<T>(this EntitiesDB entitiesDB, ExclusiveGroupStruct group) where T : struct, IEntityViewComponent
{
return entitiesDB.QueryEntities<T>(group);
var (buffer, ids, count) = entitiesDB.QueryEntities<T>(group);
return new RefCollection<T>(count, buffer, ids, group);
}
}
}

+ 12
- 7
TechbloxModdingAPI/Utility/NativeApiExtensions.cs View File

@@ -102,14 +102,19 @@ namespace TechbloxModdingAPI.Utility
ChangesToPublish[typeof(T)] = (0, changes);
}

public static IEnumerable<TR> QueryEntities<T, TR>(this EntitiesDB entitiesDB, ExclusiveGroupStruct group,
ManagedApiExtensions.EntityEnumeratorSelect<T, TR> select) where T : unmanaged, IEntityComponent
/// <summary>
/// Query entities as OptionalRefs. The elements always exist, it's just a nice way to encapsulate the data.
/// </summary>
/// <param name="entitiesDB"></param>
/// <param name="group"></param>
/// <param name="select"></param>
/// <typeparam name="T"></typeparam>
/// <typeparam name="TR"></typeparam>
/// <returns></returns>
public static RefCollection<T> QueryEntitiesOptional<T>(this EntitiesDB entitiesDB, ExclusiveGroupStruct group) where T : unmanaged, IEntityComponent
{
var (coll, ids, count) = entitiesDB.QueryEntities<T>(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<T>(group);
return new RefCollection<T>(count, buffer, ids, group);
}
}
}

+ 5
- 0
TechbloxModdingAPI/Utility/OptionalRef.cs View File

@@ -77,6 +77,11 @@ namespace TechbloxModdingAPI.Utility
set => Get() = value;
}

/// <summary>
/// The ID of the entity this component belongs to.
/// </summary>
public EGID EGID => entityId;

public bool Exists => state != State.Empty;
public T? Nullable() => this ? Get() : default;



+ 39
- 56
TechbloxModdingAPI/Utility/RefCollection.cs View File

@@ -6,83 +6,66 @@ using Svelto.ECS.Internal;

namespace TechbloxModdingAPI.Utility
{
public ref struct RefCollection<T> where T : struct, IBaseEntityComponent
public readonly ref struct RefCollection<T> where T : struct, IBaseEntityComponent
{
private readonly bool managed;
private int count;
private NB<T> nativeArray;
private MB<T> managedArray;
private NativeEntityIDs nativeIDs;
private ManagedEntityIDs managedIDs;
private readonly int count;
private readonly NB<T> nativeArray;
private readonly MB<T> managedArray;
private readonly NativeEntityIDs nativeIDs;
private readonly ManagedEntityIDs managedIDs;
private readonly ExclusiveGroupStruct group;

private RefCollection(EntityCollection<T> coll, T inst = default)
public RefCollection(int count, MB<T> managedArray, ManagedEntityIDs managedIDs, ExclusiveGroupStruct group)
{
if (inst is IEntityComponent)
{
DeconstructCollection<T, T>(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<TM, TN>(EntityCollection<T> coll) where TM : struct, IEntityViewComponent
where TN : unmanaged, IEntityComponent
public RefCollection(int count, NB<T> nativeArray, NativeEntityIDs nativeIDs, ExclusiveGroupStruct group)
{
switch (coll)
{
case EntityCollection<TM> cm:
{
MB<TM> ma;
(ma, managedIDs, count) = cm;
if (ma is MB<T> mb)
managedArray = mb;
else
throw new InvalidCastException("Expected managed buffer in managed entity collection! Wut");
break;
}
case EntityCollection<TN> cn:
{
NB<TN> na;
(na, nativeIDs, count) = cn;
if (na is NB<T> nb)
nativeArray = nb;
else
throw new InvalidCastException("Expected native buffer in native entity collection! Wut");
break;
}
}
}

public static implicit operator RefCollection<T>(EntityCollection<T> coll)
{
return new RefCollection<T>(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<T> collection;
private uint index;
private RefCollection<T> coll;
private int index;

public Enumerator(RefCollection<T> collection)
{
index = default;
this.collection = collection;
index = -1;
coll = collection;
}

public OptionalRef<T> Current => collection.coll.[index];
public OptionalRef<T> Current
{
get
{
if (coll.count <= index && index >= 0) return default;
if (coll.managed)
return new OptionalRef<T>(coll.managedArray, (uint)index,
new EGID(coll.managedIDs[index], coll.group));
return new OptionalRef<T>(coll.nativeArray, (uint)index,
new EGID(coll.nativeIDs[index], coll.group));
}
}

public bool MoveNext()
{
return true;
return ++index < coll.count;
}
}

private static void Test<TN>(EntityCollection<TN> coll) where TN : unmanaged, IEntityComponent
{
}
}
}

Loading…
Cancel
Save