Start updating to Techblox 2022.08.11.09.42 and start work on RefCollection
What have I got myself into
This commit is contained in:
parent
55344d1352
commit
f70b65e796
8 changed files with 166 additions and 34 deletions
|
@ -22,7 +22,7 @@ namespace TechbloxModdingAPI.Blocks.Engines
|
|||
{
|
||||
private static IEntityFunctions _entityFunctions;
|
||||
private static MachineGraphConnectionEntityFactory _connectionFactory;
|
||||
private NativeHashSet<ulong> removedConnections = new(2000, Allocator.Persistent);
|
||||
private NativeHashSet<ulong> removedConnections;
|
||||
|
||||
public bool RemoveBlock(EGID target)
|
||||
{
|
||||
|
@ -44,6 +44,7 @@ namespace TechbloxModdingAPI.Blocks.Engines
|
|||
|
||||
public void Ready()
|
||||
{
|
||||
removedConnections = new(2000, Allocator.Persistent);
|
||||
}
|
||||
|
||||
public EntitiesDB entitiesDB { get; set; }
|
||||
|
@ -77,6 +78,7 @@ namespace TechbloxModdingAPI.Blocks.Engines
|
|||
|
||||
public JobHandle DeterministicStep(in float deltaTime, JobHandle inputDeps)
|
||||
{
|
||||
if (removedConnections.IsCreated)
|
||||
removedConnections.Clear();
|
||||
return default;
|
||||
}
|
||||
|
|
|
@ -226,27 +226,27 @@ namespace TechbloxModdingAPI.Blocks.Engines
|
|||
uint entityID = (output ? ports.firstOutputID : ports.firstInputID) + i;
|
||||
if (!mapper.TryGetArrayAndEntityIndex(entityID, out var index, out var array) ||
|
||||
array[index].usage != portUsage) continue;
|
||||
return new OptionalRef<PortEntityStruct>(array, index);
|
||||
return new OptionalRef<PortEntityStruct>(array, index, new EGID(entityID, group));
|
||||
}
|
||||
|
||||
return default;
|
||||
}
|
||||
|
||||
public ref WireEntityStruct MatchPortToWire(PortEntityStruct port, EGID blockID, out bool exists)
|
||||
public OptionalRef<WireEntityStruct> MatchPortToWire(PortEntityStruct port, EGID blockID, out EGID wireID)
|
||||
{
|
||||
var (wires, count) = entitiesDB.QueryEntities<WireEntityStruct>(NamedExclusiveGroup<BuildModeWiresGroups.WiresGroup>.Group);
|
||||
var (wires, ids, count) = entitiesDB.QueryEntities<WireEntityStruct>(NamedExclusiveGroup<BuildModeWiresGroups.WiresGroup>.Group);
|
||||
for (uint i = 0; i < count; i++)
|
||||
{
|
||||
if ((wires[i].destinationPortUsage == port.usage && wires[i].destinationBlockEGID == blockID)
|
||||
|| (wires[i].sourcePortUsage == port.usage && wires[i].sourceBlockEGID == blockID))
|
||||
{
|
||||
exists = true;
|
||||
return ref wires[i];
|
||||
wireID = new EGID(ids[i], BuildModeWiresGroups.WiresGroup.Group);
|
||||
return new OptionalRef<WireEntityStruct>(wires, i);
|
||||
}
|
||||
}
|
||||
exists = false;
|
||||
WireEntityStruct[] defRef = new WireEntityStruct[1];
|
||||
return ref defRef[0];
|
||||
|
||||
wireID = default;
|
||||
return default;
|
||||
}
|
||||
|
||||
public EGID MatchBlocksToWire(EGID startBlock, EGID endBlock, byte startPort = byte.MaxValue, byte endPort = byte.MaxValue)
|
||||
|
@ -275,19 +275,23 @@ namespace TechbloxModdingAPI.Blocks.Engines
|
|||
endPorts = new EGID[] {new EGID(ports.firstInputID + endPort, NamedExclusiveGroup<BuildModeWiresGroups.InputPortsGroup>.Group) };
|
||||
}
|
||||
|
||||
var (wires, count) = entitiesDB.QueryEntities<WireEntityStruct>(NamedExclusiveGroup<BuildModeWiresGroups.WiresGroup>.Group);
|
||||
for (int endIndex = 0; endIndex < endPorts.Length; endIndex++)
|
||||
{
|
||||
PortEntityStruct endPES = entitiesDB.QueryEntity<PortEntityStruct>(endPorts[endIndex]);
|
||||
for (int startIndex = 0; startIndex < startPorts.Length; startIndex++)
|
||||
{
|
||||
PortEntityStruct startPES = entitiesDB.QueryEntity<PortEntityStruct>(startPorts[startIndex]);
|
||||
foreach (var wire 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))
|
||||
{
|
||||
return wires[w].ID;
|
||||
return new EGID(ids[w], NamedExclusiveGroup<BuildModeWiresGroups.WiresGroup>.Group);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -308,12 +312,12 @@ namespace TechbloxModdingAPI.Blocks.Engines
|
|||
public EGID[] GetElectricBlocks()
|
||||
{
|
||||
var res = new FasterList<EGID>();
|
||||
foreach (var ((coll, count), _) in entitiesDB.QueryEntities<BlockPortsStruct>())
|
||||
foreach (var ((coll, ids, count), _) in entitiesDB.QueryEntities<BlockPortsStruct>())
|
||||
{
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
ref BlockPortsStruct s = ref coll[i];
|
||||
//res.Add(s.ID); - TODO
|
||||
//res.Add(s.ID); - TODO: Would need to search for the groups for each block
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -46,9 +46,9 @@ namespace TechbloxModdingAPI.Blocks
|
|||
/// <returns>The connected wire.</returns>
|
||||
/// <param name="portId">Port identifier.</param>
|
||||
/// <param name="connected">Whether the port has a wire connected to it.</param>
|
||||
protected ref WireEntityStruct GetConnectedWire(PortEntityStruct port, out bool connected)
|
||||
protected OptionalRef<WireEntityStruct> GetConnectedWire(PortEntityStruct port, out EGID egid)
|
||||
{
|
||||
return ref SignalEngine.MatchPortToWire(port, Id, out connected);
|
||||
return SignalEngine.MatchPortToWire(port, Id, out egid);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -5,6 +5,7 @@ using Svelto.ECS;
|
|||
using Svelto.ECS.Experimental;
|
||||
|
||||
using TechbloxModdingAPI.Blocks.Engines;
|
||||
using TechbloxModdingAPI.Utility;
|
||||
|
||||
namespace TechbloxModdingAPI.Blocks
|
||||
{
|
||||
|
@ -45,9 +46,9 @@ namespace TechbloxModdingAPI.Blocks
|
|||
{
|
||||
var port = signalEngine.MatchBlockIOToPort(end, endPort, false);
|
||||
if (!port) return null;
|
||||
WireEntityStruct wire = signalEngine.MatchPortToWire(port, end.Id, out var exists);
|
||||
return exists
|
||||
? new Wire(wire.sourceBlockEGID, end.Id, wire.sourcePortUsage, endPort, wire.ID, false)
|
||||
var wire = signalEngine.MatchPortToWire(port, end.Id, out var egid);
|
||||
return wire
|
||||
? new Wire(wire.Get().sourceBlockEGID, end.Id, wire.Get().sourcePortUsage, endPort, egid, false)
|
||||
: null;
|
||||
}
|
||||
|
||||
|
@ -62,9 +63,9 @@ namespace TechbloxModdingAPI.Blocks
|
|||
{
|
||||
var port = signalEngine.MatchBlockIOToPort(start, startPort, true);
|
||||
if (!port) return null;
|
||||
WireEntityStruct wire = signalEngine.MatchPortToWire(port, start.Id, out var exists);
|
||||
return exists
|
||||
? new Wire(start.Id, wire.destinationBlockEGID, startPort, wire.destinationPortUsage, wire.ID, false)
|
||||
var wire = signalEngine.MatchPortToWire(port, start.Id, out var egid);
|
||||
return wire
|
||||
? new Wire(start.Id, wire.Get().destinationBlockEGID, startPort, wire.Get().destinationPortUsage, egid, false)
|
||||
: null;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Svelto.ECS;
|
||||
using Svelto.ECS.Hybrid;
|
||||
|
||||
|
@ -29,7 +31,8 @@ namespace TechbloxModdingAPI.Utility
|
|||
/// <param name="group">The group of the entity if the object can have multiple</param>
|
||||
/// <typeparam name="T">The component to query</typeparam>
|
||||
/// <returns>A reference to the component or a dummy value</returns>
|
||||
public static OptionalRef<T> QueryEntityOptional<T>(this EntitiesDB entitiesDB, EcsObjectBase obj, ExclusiveGroupStruct group = default)
|
||||
public static OptionalRef<T> QueryEntityOptional<T>(this EntitiesDB entitiesDB, EcsObjectBase obj,
|
||||
ExclusiveGroupStruct group = default)
|
||||
where T : struct, IEntityViewComponent
|
||||
{
|
||||
EGID id = group == ExclusiveGroupStruct.Invalid ? obj.Id : new EGID(obj.Id.entityID, group);
|
||||
|
@ -45,7 +48,8 @@ namespace TechbloxModdingAPI.Utility
|
|||
/// <param name="group">The group of the entity if the object can have multiple</param>
|
||||
/// <typeparam name="T">The component to query</typeparam>
|
||||
/// <returns>A reference to the component or a dummy value</returns>
|
||||
public static ref T QueryEntityOrDefault<T>(this EntitiesDB entitiesDB, EcsObjectBase obj, ExclusiveGroupStruct group = default)
|
||||
public static ref T QueryEntityOrDefault<T>(this EntitiesDB entitiesDB, EcsObjectBase obj,
|
||||
ExclusiveGroupStruct group = default)
|
||||
where T : struct, IEntityViewComponent
|
||||
{
|
||||
EGID id = group == ExclusiveGroupStruct.Invalid ? obj.Id : new EGID(obj.Id.entityID, group);
|
||||
|
@ -54,5 +58,19 @@ namespace TechbloxModdingAPI.Utility
|
|||
if (obj.InitData.Valid) return ref obj.InitData.Initializer(id).GetOrAdd<T>();
|
||||
return ref opt.Get(); //Default value
|
||||
}
|
||||
|
||||
/// <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 : struct, IBaseEntityComponent
|
||||
{
|
||||
return entitiesDB.QueryEntities<T>(group);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -33,7 +33,8 @@ namespace TechbloxModdingAPI.Utility
|
|||
/// <param name="group">The group of the entity if the object can have multiple</param>
|
||||
/// <typeparam name="T">The component to query</typeparam>
|
||||
/// <returns>A reference to the component or a dummy value</returns>
|
||||
public static OptionalRef<T> QueryEntityOptional<T>(this EntitiesDB entitiesDB, EcsObjectBase obj, ExclusiveGroupStruct group = default)
|
||||
public static OptionalRef<T> QueryEntityOptional<T>(this EntitiesDB entitiesDB, EcsObjectBase obj,
|
||||
ExclusiveGroupStruct group = default)
|
||||
where T : unmanaged, IEntityComponent
|
||||
{
|
||||
EGID id = group == ExclusiveGroupStruct.Invalid ? obj.Id : new EGID(obj.Id.entityID, group);
|
||||
|
@ -49,7 +50,8 @@ namespace TechbloxModdingAPI.Utility
|
|||
/// <param name="group">The group of the entity if the object can have multiple</param>
|
||||
/// <typeparam name="T">The component to query</typeparam>
|
||||
/// <returns>A reference to the component or a dummy value</returns>
|
||||
public static ref T QueryEntityOrDefault<T>(this EntitiesDB entitiesDB, EcsObjectBase obj, ExclusiveGroupStruct group = default)
|
||||
public static ref T QueryEntityOrDefault<T>(this EntitiesDB entitiesDB, EcsObjectBase obj,
|
||||
ExclusiveGroupStruct group = default)
|
||||
where T : unmanaged, IEntityComponent
|
||||
{
|
||||
EGID id = group == ExclusiveGroupStruct.Invalid ? obj.Id : new EGID(obj.Id.entityID, group);
|
||||
|
@ -76,7 +78,8 @@ namespace TechbloxModdingAPI.Utility
|
|||
/// <typeparam name="T">The component that changed</typeparam>
|
||||
public static void PublishEntityChangeDelayed<T>(this EntitiesDB entitiesDB, EGID id, int limit = 80)
|
||||
where T : unmanaged, IEntityComponent
|
||||
{ //TODO: Doesn't seem to help
|
||||
{
|
||||
//TODO: Doesn't seem to help
|
||||
if (!ChangesToPublish.ContainsKey(typeof(T)))
|
||||
ChangesToPublish.Add(typeof(T), (0, new HashSet<EGID>()));
|
||||
var changes = ChangesToPublish[typeof(T)].Changes;
|
||||
|
@ -98,5 +101,15 @@ namespace TechbloxModdingAPI.Utility
|
|||
yield return Yield.It;
|
||||
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
|
||||
{
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,8 +4,9 @@ using Svelto.ECS;
|
|||
|
||||
namespace TechbloxModdingAPI.Utility
|
||||
{
|
||||
public ref struct OptionalRef<T> where T : struct, IEntityComponent
|
||||
public ref struct OptionalRef<T> where T : struct, IBaseEntityComponent
|
||||
{
|
||||
private readonly EGID entityId;
|
||||
private readonly State state;
|
||||
private readonly uint index;
|
||||
private NB<T> array;
|
||||
|
@ -13,19 +14,21 @@ namespace TechbloxModdingAPI.Utility
|
|||
private readonly EntityInitializer initializer;
|
||||
//The possible fields are: (index && (array || managedArray)) || initializer
|
||||
|
||||
public OptionalRef(NB<T> array, uint index)
|
||||
public OptionalRef(NB<T> array, uint index, EGID entityId = default)
|
||||
{
|
||||
state = State.Native;
|
||||
this.array = array;
|
||||
this.index = index;
|
||||
this.entityId = entityId;
|
||||
initializer = default;
|
||||
}
|
||||
|
||||
public OptionalRef(MB<T> array, uint index)
|
||||
public OptionalRef(MB<T> array, uint index, EGID entityId = default)
|
||||
{
|
||||
state = State.Managed;
|
||||
managedArray = array;
|
||||
this.index = index;
|
||||
this.entityId = entityId;
|
||||
initializer = default;
|
||||
this.array = default;
|
||||
}
|
||||
|
@ -35,8 +38,9 @@ namespace TechbloxModdingAPI.Utility
|
|||
/// </summary>
|
||||
/// <param name="obj">The object with the initializer</param>
|
||||
/// <param name="unmanaged">Whether the struct is unmanaged</param>
|
||||
public OptionalRef(EcsObjectBase obj, bool unmanaged)
|
||||
public OptionalRef(EcsObjectBase obj, bool unmanaged, EGID entityId = default)
|
||||
{
|
||||
this.entityId = entityId;
|
||||
if (obj.InitData.Valid)
|
||||
{
|
||||
initializer = obj.InitData.Initializer(obj.Id);
|
||||
|
@ -80,6 +84,8 @@ namespace TechbloxModdingAPI.Utility
|
|||
|
||||
public static implicit operator bool(OptionalRef<T> opt) => opt.state != State.Empty;
|
||||
|
||||
public static implicit operator EGID(OptionalRef<T> opt) => opt.entityId;
|
||||
|
||||
/// <summary>
|
||||
/// Creates an instance of a struct T that can be referenced.
|
||||
/// </summary>
|
||||
|
|
88
TechbloxModdingAPI/Utility/RefCollection.cs
Normal file
88
TechbloxModdingAPI/Utility/RefCollection.cs
Normal file
|
@ -0,0 +1,88 @@
|
|||
using System;
|
||||
using Svelto.DataStructures;
|
||||
using Svelto.ECS;
|
||||
using Svelto.ECS.Hybrid;
|
||||
using Svelto.ECS.Internal;
|
||||
|
||||
namespace TechbloxModdingAPI.Utility
|
||||
{
|
||||
public 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 RefCollection(EntityCollection<T> coll, T inst = default)
|
||||
{
|
||||
if (inst is IEntityComponent)
|
||||
{
|
||||
DeconstructCollection<T, T>(coll);
|
||||
}
|
||||
if (typeof(T).IsAssignableFrom(typeof(IEntityViewComponent)))
|
||||
{
|
||||
(managedArray, managedIDs, count) = coll2;
|
||||
}
|
||||
}
|
||||
|
||||
private void DeconstructCollection<TM, TN>(EntityCollection<T> coll) where TM : struct, IEntityViewComponent
|
||||
where TN : unmanaged, IEntityComponent
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
public Enumerator GetEnumerator() => new(this);
|
||||
|
||||
public ref struct Enumerator
|
||||
{
|
||||
private RefCollection<T> collection;
|
||||
private uint index;
|
||||
public Enumerator(RefCollection<T> collection)
|
||||
{
|
||||
index = default;
|
||||
this.collection = collection;
|
||||
}
|
||||
|
||||
public OptionalRef<T> Current => collection.coll.[index];
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private static void Test<TN>(EntityCollection<TN> coll) where TN : unmanaged, IEntityComponent
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue