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
This commit is contained in:
parent
f70b65e796
commit
5117b69500
5 changed files with 64 additions and 73 deletions
|
@ -281,17 +281,14 @@ namespace TechbloxModdingAPI.Blocks.Engines
|
||||||
for (int startIndex = 0; startIndex < startPorts.Length; startIndex++)
|
for (int startIndex = 0; startIndex < startPorts.Length; startIndex++)
|
||||||
{
|
{
|
||||||
PortEntityStruct startPES = entitiesDB.QueryEntity<PortEntityStruct>(startPorts[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))
|
NamedExclusiveGroup<BuildModeWiresGroups.WiresGroup>.Group))
|
||||||
{
|
{
|
||||||
|
var wire = wireOpt.Get();
|
||||||
}
|
if ((wire.destinationPortUsage == endPES.usage && wire.destinationBlockEGID == endBlock)
|
||||||
for (int w = 0; w < count; w++)
|
&& (wire.sourcePortUsage == startPES.usage && wire.sourceBlockEGID == startBlock))
|
||||||
{
|
{
|
||||||
if ((wires[w].destinationPortUsage == endPES.usage && wires[w].destinationBlockEGID == endBlock)
|
return wireOpt.EGID;
|
||||||
&& (wires[w].sourcePortUsage == startPES.usage && wires[w].sourceBlockEGID == startBlock))
|
|
||||||
{
|
|
||||||
return new EGID(ids[w], NamedExclusiveGroup<BuildModeWiresGroups.WiresGroup>.Group);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,9 +68,10 @@ namespace TechbloxModdingAPI.Utility
|
||||||
/// <typeparam name="T"></typeparam>
|
/// <typeparam name="T"></typeparam>
|
||||||
/// <typeparam name="TR"></typeparam>
|
/// <typeparam name="TR"></typeparam>
|
||||||
/// <returns></returns>
|
/// <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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -102,14 +102,19 @@ namespace TechbloxModdingAPI.Utility
|
||||||
ChangesToPublish[typeof(T)] = (0, changes);
|
ChangesToPublish[typeof(T)] = (0, changes);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IEnumerable<TR> QueryEntities<T, TR>(this EntitiesDB entitiesDB, ExclusiveGroupStruct group,
|
/// <summary>
|
||||||
ManagedApiExtensions.EntityEnumeratorSelect<T, TR> select) where T : unmanaged, IEntityComponent
|
/// 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);
|
var (buffer, ids, count) = entitiesDB.QueryEntities<T>(group);
|
||||||
for (uint i = 0; i < count; i++)
|
return new RefCollection<T>(count, buffer, ids, group);
|
||||||
{
|
|
||||||
yield return select(ref coll[i], new EGID(ids[i], group));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -77,6 +77,11 @@ namespace TechbloxModdingAPI.Utility
|
||||||
set => Get() = value;
|
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 bool Exists => state != State.Empty;
|
||||||
public T? Nullable() => this ? Get() : default;
|
public T? Nullable() => this ? Get() : default;
|
||||||
|
|
||||||
|
|
|
@ -6,83 +6,66 @@ using Svelto.ECS.Internal;
|
||||||
|
|
||||||
namespace TechbloxModdingAPI.Utility
|
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 readonly bool managed;
|
||||||
private int count;
|
private readonly int count;
|
||||||
private NB<T> nativeArray;
|
private readonly NB<T> nativeArray;
|
||||||
private MB<T> managedArray;
|
private readonly MB<T> managedArray;
|
||||||
private NativeEntityIDs nativeIDs;
|
private readonly NativeEntityIDs nativeIDs;
|
||||||
private ManagedEntityIDs managedIDs;
|
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)
|
this.count = count;
|
||||||
{
|
this.managedArray = managedArray;
|
||||||
DeconstructCollection<T, T>(coll);
|
this.managedIDs = managedIDs;
|
||||||
}
|
this.group = group;
|
||||||
if (typeof(T).IsAssignableFrom(typeof(IEntityViewComponent)))
|
managed = true;
|
||||||
{
|
nativeArray = default;
|
||||||
(managedArray, managedIDs, count) = coll2;
|
nativeIDs = default;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DeconstructCollection<TM, TN>(EntityCollection<T> coll) where TM : struct, IEntityViewComponent
|
public RefCollection(int count, NB<T> nativeArray, NativeEntityIDs nativeIDs, ExclusiveGroupStruct group)
|
||||||
where TN : unmanaged, IEntityComponent
|
|
||||||
{
|
{
|
||||||
switch (coll)
|
this.count = count;
|
||||||
{
|
this.nativeArray = nativeArray;
|
||||||
case EntityCollection<TM> cm:
|
this.nativeIDs = nativeIDs;
|
||||||
{
|
this.group = group;
|
||||||
MB<TM> ma;
|
managed = false;
|
||||||
(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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Enumerator GetEnumerator() => new(this);
|
public Enumerator GetEnumerator() => new(this);
|
||||||
|
|
||||||
public ref struct Enumerator
|
public ref struct Enumerator
|
||||||
{
|
{
|
||||||
private RefCollection<T> collection;
|
private RefCollection<T> coll;
|
||||||
private uint index;
|
private int index;
|
||||||
|
|
||||||
public Enumerator(RefCollection<T> collection)
|
public Enumerator(RefCollection<T> collection)
|
||||||
{
|
{
|
||||||
index = default;
|
index = -1;
|
||||||
this.collection = collection;
|
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()
|
public bool MoveNext()
|
||||||
{
|
{
|
||||||
return true;
|
return ++index < coll.count;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private static void Test<TN>(EntityCollection<TN> coll) where TN : unmanaged, IEntityComponent
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue