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 IEntityFunctions _entityFunctions;
|
||||||
private static MachineGraphConnectionEntityFactory _connectionFactory;
|
private static MachineGraphConnectionEntityFactory _connectionFactory;
|
||||||
private NativeHashSet<ulong> removedConnections = new(2000, Allocator.Persistent);
|
private NativeHashSet<ulong> removedConnections;
|
||||||
|
|
||||||
public bool RemoveBlock(EGID target)
|
public bool RemoveBlock(EGID target)
|
||||||
{
|
{
|
||||||
|
@ -44,6 +44,7 @@ namespace TechbloxModdingAPI.Blocks.Engines
|
||||||
|
|
||||||
public void Ready()
|
public void Ready()
|
||||||
{
|
{
|
||||||
|
removedConnections = new(2000, Allocator.Persistent);
|
||||||
}
|
}
|
||||||
|
|
||||||
public EntitiesDB entitiesDB { get; set; }
|
public EntitiesDB entitiesDB { get; set; }
|
||||||
|
@ -77,7 +78,8 @@ namespace TechbloxModdingAPI.Blocks.Engines
|
||||||
|
|
||||||
public JobHandle DeterministicStep(in float deltaTime, JobHandle inputDeps)
|
public JobHandle DeterministicStep(in float deltaTime, JobHandle inputDeps)
|
||||||
{
|
{
|
||||||
removedConnections.Clear();
|
if (removedConnections.IsCreated)
|
||||||
|
removedConnections.Clear();
|
||||||
return default;
|
return default;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -226,27 +226,27 @@ namespace TechbloxModdingAPI.Blocks.Engines
|
||||||
uint entityID = (output ? ports.firstOutputID : ports.firstInputID) + i;
|
uint entityID = (output ? ports.firstOutputID : ports.firstInputID) + i;
|
||||||
if (!mapper.TryGetArrayAndEntityIndex(entityID, out var index, out var array) ||
|
if (!mapper.TryGetArrayAndEntityIndex(entityID, out var index, out var array) ||
|
||||||
array[index].usage != portUsage) continue;
|
array[index].usage != portUsage) continue;
|
||||||
return new OptionalRef<PortEntityStruct>(array, index);
|
return new OptionalRef<PortEntityStruct>(array, index, new EGID(entityID, group));
|
||||||
}
|
}
|
||||||
|
|
||||||
return default;
|
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++)
|
for (uint i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
if ((wires[i].destinationPortUsage == port.usage && wires[i].destinationBlockEGID == blockID)
|
if ((wires[i].destinationPortUsage == port.usage && wires[i].destinationBlockEGID == blockID)
|
||||||
|| (wires[i].sourcePortUsage == port.usage && wires[i].sourceBlockEGID == blockID))
|
|| (wires[i].sourcePortUsage == port.usage && wires[i].sourceBlockEGID == blockID))
|
||||||
{
|
{
|
||||||
exists = true;
|
wireID = new EGID(ids[i], BuildModeWiresGroups.WiresGroup.Group);
|
||||||
return ref wires[i];
|
return new OptionalRef<WireEntityStruct>(wires, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exists = false;
|
|
||||||
WireEntityStruct[] defRef = new WireEntityStruct[1];
|
wireID = default;
|
||||||
return ref defRef[0];
|
return default;
|
||||||
}
|
}
|
||||||
|
|
||||||
public EGID MatchBlocksToWire(EGID startBlock, EGID endBlock, byte startPort = byte.MaxValue, byte endPort = byte.MaxValue)
|
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) };
|
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++)
|
for (int endIndex = 0; endIndex < endPorts.Length; endIndex++)
|
||||||
{
|
{
|
||||||
PortEntityStruct endPES = entitiesDB.QueryEntity<PortEntityStruct>(endPorts[endIndex]);
|
PortEntityStruct endPES = entitiesDB.QueryEntity<PortEntityStruct>(endPorts[endIndex]);
|
||||||
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>(
|
||||||
|
NamedExclusiveGroup<BuildModeWiresGroups.WiresGroup>.Group))
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
for (int w = 0; w < count; w++)
|
for (int w = 0; w < count; w++)
|
||||||
{
|
{
|
||||||
if ((wires[w].destinationPortUsage == endPES.usage && wires[w].destinationBlockEGID == endBlock)
|
if ((wires[w].destinationPortUsage == endPES.usage && wires[w].destinationBlockEGID == endBlock)
|
||||||
&& (wires[w].sourcePortUsage == startPES.usage && wires[w].sourceBlockEGID == startBlock))
|
&& (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()
|
public EGID[] GetElectricBlocks()
|
||||||
{
|
{
|
||||||
var res = new FasterList<EGID>();
|
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++)
|
for (int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
ref BlockPortsStruct s = ref coll[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>
|
/// <returns>The connected wire.</returns>
|
||||||
/// <param name="portId">Port identifier.</param>
|
/// <param name="portId">Port identifier.</param>
|
||||||
/// <param name="connected">Whether the port has a wire connected to it.</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>
|
/// <summary>
|
||||||
|
|
|
@ -5,6 +5,7 @@ using Svelto.ECS;
|
||||||
using Svelto.ECS.Experimental;
|
using Svelto.ECS.Experimental;
|
||||||
|
|
||||||
using TechbloxModdingAPI.Blocks.Engines;
|
using TechbloxModdingAPI.Blocks.Engines;
|
||||||
|
using TechbloxModdingAPI.Utility;
|
||||||
|
|
||||||
namespace TechbloxModdingAPI.Blocks
|
namespace TechbloxModdingAPI.Blocks
|
||||||
{
|
{
|
||||||
|
@ -45,9 +46,9 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
{
|
{
|
||||||
var port = signalEngine.MatchBlockIOToPort(end, endPort, false);
|
var port = signalEngine.MatchBlockIOToPort(end, endPort, false);
|
||||||
if (!port) return null;
|
if (!port) return null;
|
||||||
WireEntityStruct wire = signalEngine.MatchPortToWire(port, end.Id, out var exists);
|
var wire = signalEngine.MatchPortToWire(port, end.Id, out var egid);
|
||||||
return exists
|
return wire
|
||||||
? new Wire(wire.sourceBlockEGID, end.Id, wire.sourcePortUsage, endPort, wire.ID, false)
|
? new Wire(wire.Get().sourceBlockEGID, end.Id, wire.Get().sourcePortUsage, endPort, egid, false)
|
||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,9 +63,9 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
{
|
{
|
||||||
var port = signalEngine.MatchBlockIOToPort(start, startPort, true);
|
var port = signalEngine.MatchBlockIOToPort(start, startPort, true);
|
||||||
if (!port) return null;
|
if (!port) return null;
|
||||||
WireEntityStruct wire = signalEngine.MatchPortToWire(port, start.Id, out var exists);
|
var wire = signalEngine.MatchPortToWire(port, start.Id, out var egid);
|
||||||
return exists
|
return wire
|
||||||
? new Wire(start.Id, wire.destinationBlockEGID, startPort, wire.destinationPortUsage, wire.ID, false)
|
? new Wire(start.Id, wire.Get().destinationBlockEGID, startPort, wire.Get().destinationPortUsage, egid, false)
|
||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
using Svelto.ECS;
|
using Svelto.ECS;
|
||||||
using Svelto.ECS.Hybrid;
|
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>
|
/// <param name="group">The group of the entity if the object can have multiple</param>
|
||||||
/// <typeparam name="T">The component to query</typeparam>
|
/// <typeparam name="T">The component to query</typeparam>
|
||||||
/// <returns>A reference to the component or a dummy value</returns>
|
/// <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
|
where T : struct, IEntityViewComponent
|
||||||
{
|
{
|
||||||
EGID id = group == ExclusiveGroupStruct.Invalid ? obj.Id : new EGID(obj.Id.entityID, group);
|
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>
|
/// <param name="group">The group of the entity if the object can have multiple</param>
|
||||||
/// <typeparam name="T">The component to query</typeparam>
|
/// <typeparam name="T">The component to query</typeparam>
|
||||||
/// <returns>A reference to the component or a dummy value</returns>
|
/// <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
|
where T : struct, IEntityViewComponent
|
||||||
{
|
{
|
||||||
EGID id = group == ExclusiveGroupStruct.Invalid ? obj.Id : new EGID(obj.Id.entityID, group);
|
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>();
|
if (obj.InitData.Valid) return ref obj.InitData.Initializer(id).GetOrAdd<T>();
|
||||||
return ref opt.Get(); //Default value
|
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>
|
/// <param name="group">The group of the entity if the object can have multiple</param>
|
||||||
/// <typeparam name="T">The component to query</typeparam>
|
/// <typeparam name="T">The component to query</typeparam>
|
||||||
/// <returns>A reference to the component or a dummy value</returns>
|
/// <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
|
where T : unmanaged, IEntityComponent
|
||||||
{
|
{
|
||||||
EGID id = group == ExclusiveGroupStruct.Invalid ? obj.Id : new EGID(obj.Id.entityID, group);
|
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>
|
/// <param name="group">The group of the entity if the object can have multiple</param>
|
||||||
/// <typeparam name="T">The component to query</typeparam>
|
/// <typeparam name="T">The component to query</typeparam>
|
||||||
/// <returns>A reference to the component or a dummy value</returns>
|
/// <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
|
where T : unmanaged, IEntityComponent
|
||||||
{
|
{
|
||||||
EGID id = group == ExclusiveGroupStruct.Invalid ? obj.Id : new EGID(obj.Id.entityID, group);
|
EGID id = group == ExclusiveGroupStruct.Invalid ? obj.Id : new EGID(obj.Id.entityID, group);
|
||||||
|
@ -76,8 +78,9 @@ namespace TechbloxModdingAPI.Utility
|
||||||
/// <typeparam name="T">The component that changed</typeparam>
|
/// <typeparam name="T">The component that changed</typeparam>
|
||||||
public static void PublishEntityChangeDelayed<T>(this EntitiesDB entitiesDB, EGID id, int limit = 80)
|
public static void PublishEntityChangeDelayed<T>(this EntitiesDB entitiesDB, EGID id, int limit = 80)
|
||||||
where T : unmanaged, IEntityComponent
|
where T : unmanaged, IEntityComponent
|
||||||
{ //TODO: Doesn't seem to help
|
{
|
||||||
if(!ChangesToPublish.ContainsKey(typeof(T)))
|
//TODO: Doesn't seem to help
|
||||||
|
if (!ChangesToPublish.ContainsKey(typeof(T)))
|
||||||
ChangesToPublish.Add(typeof(T), (0, new HashSet<EGID>()));
|
ChangesToPublish.Add(typeof(T), (0, new HashSet<EGID>()));
|
||||||
var changes = ChangesToPublish[typeof(T)].Changes;
|
var changes = ChangesToPublish[typeof(T)].Changes;
|
||||||
if (changes.Contains(id)) return;
|
if (changes.Contains(id)) return;
|
||||||
|
@ -98,5 +101,15 @@ namespace TechbloxModdingAPI.Utility
|
||||||
yield return Yield.It;
|
yield return Yield.It;
|
||||||
ChangesToPublish[typeof(T)] = (0, changes);
|
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
|
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 State state;
|
||||||
private readonly uint index;
|
private readonly uint index;
|
||||||
private NB<T> array;
|
private NB<T> array;
|
||||||
|
@ -13,19 +14,21 @@ namespace TechbloxModdingAPI.Utility
|
||||||
private readonly EntityInitializer initializer;
|
private readonly EntityInitializer initializer;
|
||||||
//The possible fields are: (index && (array || managedArray)) || 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;
|
state = State.Native;
|
||||||
this.array = array;
|
this.array = array;
|
||||||
this.index = index;
|
this.index = index;
|
||||||
|
this.entityId = entityId;
|
||||||
initializer = default;
|
initializer = default;
|
||||||
}
|
}
|
||||||
|
|
||||||
public OptionalRef(MB<T> array, uint index)
|
public OptionalRef(MB<T> array, uint index, EGID entityId = default)
|
||||||
{
|
{
|
||||||
state = State.Managed;
|
state = State.Managed;
|
||||||
managedArray = array;
|
managedArray = array;
|
||||||
this.index = index;
|
this.index = index;
|
||||||
|
this.entityId = entityId;
|
||||||
initializer = default;
|
initializer = default;
|
||||||
this.array = default;
|
this.array = default;
|
||||||
}
|
}
|
||||||
|
@ -35,8 +38,9 @@ namespace TechbloxModdingAPI.Utility
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="obj">The object with the initializer</param>
|
/// <param name="obj">The object with the initializer</param>
|
||||||
/// <param name="unmanaged">Whether the struct is unmanaged</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)
|
if (obj.InitData.Valid)
|
||||||
{
|
{
|
||||||
initializer = obj.InitData.Initializer(obj.Id);
|
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 bool(OptionalRef<T> opt) => opt.state != State.Empty;
|
||||||
|
|
||||||
|
public static implicit operator EGID(OptionalRef<T> opt) => opt.entityId;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates an instance of a struct T that can be referenced.
|
/// Creates an instance of a struct T that can be referenced.
|
||||||
/// </summary>
|
/// </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