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++)
|
||||
{
|
||||
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++)
|
||||
var wire = wireOpt.Get();
|
||||
if ((wire.destinationPortUsage == endPES.usage && wire.destinationBlockEGID == endBlock)
|
||||
&& (wire.sourcePortUsage == startPES.usage && wire.sourceBlockEGID == startBlock))
|
||||
{
|
||||
if ((wires[w].destinationPortUsage == endPES.usage && wires[w].destinationBlockEGID == endBlock)
|
||||
&& (wires[w].sourcePortUsage == startPES.usage && wires[w].sourceBlockEGID == startBlock))
|
||||
{
|
||||
return new EGID(ids[w], NamedExclusiveGroup<BuildModeWiresGroups.WiresGroup>.Group);
|
||||
return wireOpt.EGID;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
private static void Test<TN>(EntityCollection<TN> coll) where TN : unmanaged, IEntityComponent
|
||||
{
|
||||
|
||||
return ++index < coll.count;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue