2020-08-03 16:45:38 +00:00
|
|
|
|
using System;
|
|
|
|
|
using Svelto.ECS;
|
2020-07-10 22:30:58 +00:00
|
|
|
|
using Svelto.DataStructures;
|
2020-02-20 01:32:58 +00:00
|
|
|
|
using Gamecraft.Wires;
|
2019-12-25 19:25:53 +00:00
|
|
|
|
|
2020-05-12 00:28:26 +00:00
|
|
|
|
using GamecraftModdingAPI.Engines;
|
2019-12-25 19:25:53 +00:00
|
|
|
|
|
|
|
|
|
namespace GamecraftModdingAPI.Blocks
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
2020-01-04 00:54:35 +00:00
|
|
|
|
/// Engine which executes signal actions
|
2019-12-25 19:25:53 +00:00
|
|
|
|
/// </summary>
|
2020-08-03 16:45:38 +00:00
|
|
|
|
public class SignalEngine : IApiEngine, IFactoryEngine
|
2019-12-25 19:25:53 +00:00
|
|
|
|
{
|
2020-05-21 19:04:55 +00:00
|
|
|
|
public const float POSITIVE_HIGH = 1.0f;
|
|
|
|
|
public const float NEGATIVE_HIGH = -1.0f;
|
|
|
|
|
public const float HIGH = 1.0f;
|
|
|
|
|
public const float ZERO = 0.0f;
|
|
|
|
|
|
2019-12-25 19:25:53 +00:00
|
|
|
|
public string Name { get; } = "GamecraftModdingAPISignalGameEngine";
|
|
|
|
|
|
2020-03-12 22:36:23 +00:00
|
|
|
|
public EntitiesDB entitiesDB { set; private get; }
|
2020-05-12 00:28:26 +00:00
|
|
|
|
|
2020-08-03 16:45:38 +00:00
|
|
|
|
public IEntityFactory Factory { get; set; }
|
|
|
|
|
|
2020-05-12 00:28:26 +00:00
|
|
|
|
public bool isRemovable => false;
|
2019-12-25 19:25:53 +00:00
|
|
|
|
|
2020-05-12 00:28:26 +00:00
|
|
|
|
public bool IsInGame = false;
|
2019-12-25 19:25:53 +00:00
|
|
|
|
|
|
|
|
|
public void Dispose()
|
|
|
|
|
{
|
|
|
|
|
IsInGame = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Ready()
|
|
|
|
|
{
|
|
|
|
|
IsInGame = true;
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-03 16:45:38 +00:00
|
|
|
|
// implementations for block wiring
|
|
|
|
|
|
2020-08-03 17:24:35 +00:00
|
|
|
|
public WireEntityStruct CreateNewWire(EGID startBlock, byte startPort, EGID endBlock, byte endPort)
|
2020-08-03 16:45:38 +00:00
|
|
|
|
{
|
|
|
|
|
EGID wireEGID = new EGID(WiresExclusiveGroups.NewWireEntityId, NamedExclusiveGroup<WiresGroup>.Group);
|
2021-04-10 00:02:47 +00:00
|
|
|
|
EntityInitializer wireInitializer = Factory.BuildEntity<WireEntityDescriptor>(wireEGID);
|
2020-08-03 16:45:38 +00:00
|
|
|
|
wireInitializer.Init(new WireEntityStruct
|
|
|
|
|
{
|
|
|
|
|
sourceBlockEGID = startBlock,
|
|
|
|
|
sourcePortUsage = startPort,
|
|
|
|
|
destinationBlockEGID = endBlock,
|
|
|
|
|
destinationPortUsage = endPort,
|
2020-08-03 17:24:35 +00:00
|
|
|
|
ID = wireEGID
|
2020-08-03 16:45:38 +00:00
|
|
|
|
});
|
2020-08-03 17:24:35 +00:00
|
|
|
|
return wireInitializer.Get<WireEntityStruct>();
|
2020-08-03 16:45:38 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public ref WireEntityStruct GetWire(EGID wire)
|
|
|
|
|
{
|
|
|
|
|
if (!entitiesDB.Exists<WireEntityStruct>(wire))
|
|
|
|
|
{
|
|
|
|
|
throw new WiringException($"Wire {wire} does not exist");
|
|
|
|
|
}
|
|
|
|
|
return ref entitiesDB.QueryEntity<WireEntityStruct>(wire);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public ref PortEntityStruct GetPort(EGID port)
|
|
|
|
|
{
|
|
|
|
|
if (!entitiesDB.Exists<PortEntityStruct>(port))
|
|
|
|
|
{
|
|
|
|
|
throw new WiringException($"Port {port} does not exist (yet?)");
|
|
|
|
|
}
|
|
|
|
|
return ref entitiesDB.QueryEntity<PortEntityStruct>(port);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public ref PortEntityStruct GetPortByOffset(BlockPortsStruct bps, byte portNumber, bool input)
|
|
|
|
|
{
|
|
|
|
|
ExclusiveGroup group = input
|
|
|
|
|
? NamedExclusiveGroup<InputPortsGroup>.Group
|
|
|
|
|
: NamedExclusiveGroup<OutputPortsGroup>.Group;
|
|
|
|
|
uint id = (input ? bps.firstInputID : bps.firstOutputID) + portNumber;
|
|
|
|
|
EGID egid = new EGID(id, group);
|
|
|
|
|
if (!entitiesDB.Exists<PortEntityStruct>(egid))
|
|
|
|
|
{
|
|
|
|
|
throw new WiringException("Port does not exist");
|
|
|
|
|
}
|
|
|
|
|
return ref entitiesDB.QueryEntity<PortEntityStruct>(egid);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public ref PortEntityStruct GetPortByOffset(Block block, byte portNumber, bool input)
|
|
|
|
|
{
|
|
|
|
|
BlockPortsStruct bps = GetFromDbOrInitData<BlockPortsStruct>(block, block.Id, out bool exists);
|
|
|
|
|
if (!exists)
|
|
|
|
|
{
|
|
|
|
|
throw new BlockException("Block does not exist");
|
|
|
|
|
}
|
|
|
|
|
return ref GetPortByOffset(bps, portNumber, input);
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-07 17:55:00 +00:00
|
|
|
|
public ref T GetComponent<T>(EGID egid) where T : unmanaged, IEntityComponent
|
2020-08-03 16:45:38 +00:00
|
|
|
|
{
|
|
|
|
|
return ref entitiesDB.QueryEntity<T>(egid);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool Exists<T>(EGID egid) where T : struct, IEntityComponent
|
|
|
|
|
{
|
|
|
|
|
return entitiesDB.Exists<T>(egid);
|
|
|
|
|
}
|
2019-12-25 19:25:53 +00:00
|
|
|
|
|
2020-02-20 01:32:58 +00:00
|
|
|
|
public bool SetSignal(EGID blockID, float signal, out uint signalID, bool input = true)
|
2019-12-25 19:25:53 +00:00
|
|
|
|
{
|
2020-02-20 01:32:58 +00:00
|
|
|
|
signalID = GetSignalIDs(blockID, input)[0];
|
|
|
|
|
return SetSignal(signalID, signal);
|
2019-12-25 19:25:53 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-02-20 01:32:58 +00:00
|
|
|
|
public bool SetSignal(uint signalID, float signal, bool input = true)
|
2019-12-25 19:25:53 +00:00
|
|
|
|
{
|
2020-04-28 13:55:08 +00:00
|
|
|
|
var array = GetSignalStruct(signalID, out uint index, input);
|
2020-11-09 21:18:25 +00:00
|
|
|
|
var arrayB = array.ToBuffer();
|
|
|
|
|
if (array.count > 0) arrayB.buffer[index].valueAsFloat = signal;
|
2019-12-25 19:25:53 +00:00
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2020-02-20 01:32:58 +00:00
|
|
|
|
public float AddSignal(EGID blockID, float signal, out uint signalID, bool clamp = true, bool input = true)
|
2019-12-25 19:25:53 +00:00
|
|
|
|
{
|
2020-02-20 01:32:58 +00:00
|
|
|
|
signalID = GetSignalIDs(blockID, input)[0];
|
|
|
|
|
return AddSignal(signalID, signal, clamp, input);
|
2019-12-25 19:25:53 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-02-20 01:32:58 +00:00
|
|
|
|
public float AddSignal(uint signalID, float signal, bool clamp = true, bool input = true)
|
2019-12-25 19:25:53 +00:00
|
|
|
|
{
|
2020-04-28 13:55:08 +00:00
|
|
|
|
var array = GetSignalStruct(signalID, out uint index, input);
|
2020-11-09 21:18:25 +00:00
|
|
|
|
var arrayB = array.ToBuffer();
|
2020-06-12 15:27:36 +00:00
|
|
|
|
if (array.count > 0)
|
2020-04-28 13:55:08 +00:00
|
|
|
|
{
|
2020-11-09 21:18:25 +00:00
|
|
|
|
ref var channelData = ref arrayB.buffer[index];
|
2020-04-28 13:55:08 +00:00
|
|
|
|
channelData.valueAsFloat += signal;
|
|
|
|
|
if (clamp)
|
|
|
|
|
{
|
2020-05-21 19:04:55 +00:00
|
|
|
|
if (channelData.valueAsFloat > POSITIVE_HIGH)
|
2020-04-28 13:55:08 +00:00
|
|
|
|
{
|
2020-05-21 19:04:55 +00:00
|
|
|
|
channelData.valueAsFloat = POSITIVE_HIGH;
|
2020-04-28 13:55:08 +00:00
|
|
|
|
}
|
2020-05-21 19:04:55 +00:00
|
|
|
|
else if (channelData.valueAsFloat < NEGATIVE_HIGH)
|
2020-04-28 13:55:08 +00:00
|
|
|
|
{
|
2020-05-21 19:04:55 +00:00
|
|
|
|
channelData.valueAsFloat = NEGATIVE_HIGH;
|
2020-04-28 13:55:08 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return channelData.valueAsFloat;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return signal;
|
2019-12-25 19:25:53 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-02-20 01:32:58 +00:00
|
|
|
|
public float GetSignal(EGID blockID, out uint signalID, bool input = true)
|
2019-12-25 19:25:53 +00:00
|
|
|
|
{
|
2020-02-20 01:32:58 +00:00
|
|
|
|
signalID = GetSignalIDs(blockID, input)[0];
|
|
|
|
|
return GetSignal(signalID, input);
|
2019-12-25 19:25:53 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-02-20 01:32:58 +00:00
|
|
|
|
public float GetSignal(uint signalID, bool input = true)
|
2019-12-25 19:25:53 +00:00
|
|
|
|
{
|
2020-04-28 13:55:08 +00:00
|
|
|
|
var array = GetSignalStruct(signalID, out uint index, input);
|
2020-11-09 21:18:25 +00:00
|
|
|
|
var arrayB = array.ToBuffer();
|
|
|
|
|
return array.count > 0 ? arrayB.buffer[index].valueAsFloat : 0f;
|
2019-12-25 19:25:53 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-02-20 01:32:58 +00:00
|
|
|
|
public uint[] GetSignalIDs(EGID blockID, bool input = true)
|
|
|
|
|
{
|
|
|
|
|
ref BlockPortsStruct bps = ref entitiesDB.QueryEntity<BlockPortsStruct>(blockID);
|
|
|
|
|
uint[] signals;
|
|
|
|
|
if (input) {
|
|
|
|
|
signals = new uint[bps.inputCount];
|
|
|
|
|
for (uint i = 0u; i < bps.inputCount; i++)
|
|
|
|
|
{
|
|
|
|
|
signals[i] = bps.firstInputID + i;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
signals = new uint[bps.outputCount];
|
|
|
|
|
for (uint i = 0u; i < bps.outputCount; i++)
|
|
|
|
|
{
|
|
|
|
|
signals[i] = bps.firstOutputID + i;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return signals;
|
|
|
|
|
}
|
2019-12-25 19:25:53 +00:00
|
|
|
|
|
2020-05-21 19:04:55 +00:00
|
|
|
|
public EGID[] GetSignalInputs(EGID blockID)
|
|
|
|
|
{
|
|
|
|
|
BlockPortsStruct ports = entitiesDB.QueryEntity<BlockPortsStruct>(blockID);
|
|
|
|
|
EGID[] inputs = new EGID[ports.inputCount];
|
|
|
|
|
for (uint i = 0; i < ports.inputCount; i++)
|
|
|
|
|
{
|
|
|
|
|
inputs[i] = new EGID(i + ports.firstInputID, NamedExclusiveGroup<InputPortsGroup>.Group);
|
|
|
|
|
}
|
|
|
|
|
return inputs;
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-03 16:45:38 +00:00
|
|
|
|
public EGID[] GetSignalOutputs(EGID blockID)
|
2020-05-21 19:04:55 +00:00
|
|
|
|
{
|
|
|
|
|
BlockPortsStruct ports = entitiesDB.QueryEntity<BlockPortsStruct>(blockID);
|
|
|
|
|
EGID[] outputs = new EGID[ports.outputCount];
|
|
|
|
|
for (uint i = 0; i < ports.outputCount; i++)
|
|
|
|
|
{
|
|
|
|
|
outputs[i] = new EGID(i + ports.firstOutputID, NamedExclusiveGroup<OutputPortsGroup>.Group);
|
|
|
|
|
}
|
|
|
|
|
return outputs;
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-03 16:45:38 +00:00
|
|
|
|
public EGID MatchBlockInputToPort(Block block, byte portUsage, out bool exists)
|
|
|
|
|
{
|
|
|
|
|
BlockPortsStruct ports = GetFromDbOrInitData<BlockPortsStruct>(block, block.Id, out exists);
|
|
|
|
|
return new EGID(ports.firstInputID + portUsage, NamedExclusiveGroup<InputPortsGroup>.Group);
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-03 17:24:35 +00:00
|
|
|
|
public EGID MatchBlockInputToPort(EGID block, byte portUsage, out bool exists)
|
|
|
|
|
{
|
|
|
|
|
if (!entitiesDB.Exists<BlockPortsStruct>(block))
|
|
|
|
|
{
|
|
|
|
|
exists = false;
|
|
|
|
|
return default;
|
|
|
|
|
}
|
|
|
|
|
exists = true;
|
|
|
|
|
BlockPortsStruct ports = entitiesDB.QueryEntity<BlockPortsStruct>(block);
|
|
|
|
|
return new EGID(ports.firstInputID + portUsage, NamedExclusiveGroup<InputPortsGroup>.Group);
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-03 16:45:38 +00:00
|
|
|
|
public EGID MatchBlockOutputToPort(Block block, byte portUsage, out bool exists)
|
|
|
|
|
{
|
|
|
|
|
BlockPortsStruct ports = GetFromDbOrInitData<BlockPortsStruct>(block, block.Id, out exists);
|
|
|
|
|
return new EGID(ports.firstOutputID + portUsage, NamedExclusiveGroup<OutputPortsGroup>.Group);
|
|
|
|
|
}
|
2020-08-03 17:24:35 +00:00
|
|
|
|
|
|
|
|
|
public EGID MatchBlockOutputToPort(EGID block, byte portUsage, out bool exists)
|
|
|
|
|
{
|
|
|
|
|
if (!entitiesDB.Exists<BlockPortsStruct>(block))
|
|
|
|
|
{
|
|
|
|
|
exists = false;
|
|
|
|
|
return default;
|
|
|
|
|
}
|
|
|
|
|
exists = true;
|
|
|
|
|
BlockPortsStruct ports = entitiesDB.QueryEntity<BlockPortsStruct>(block);
|
|
|
|
|
return new EGID(ports.firstOutputID + portUsage, NamedExclusiveGroup<OutputPortsGroup>.Group);
|
|
|
|
|
}
|
2020-08-03 16:45:38 +00:00
|
|
|
|
|
2020-05-21 19:04:55 +00:00
|
|
|
|
public ref WireEntityStruct MatchPortToWire(EGID portID, EGID blockID, out bool exists)
|
|
|
|
|
{
|
|
|
|
|
ref PortEntityStruct port = ref entitiesDB.QueryEntity<PortEntityStruct>(portID);
|
2020-06-12 15:27:36 +00:00
|
|
|
|
var wires = entitiesDB.QueryEntities<WireEntityStruct>(NamedExclusiveGroup<WiresGroup>.Group);
|
2020-11-09 21:18:25 +00:00
|
|
|
|
var wiresB = wires.ToBuffer().buffer;
|
2020-06-12 15:27:36 +00:00
|
|
|
|
for (uint i = 0; i < wires.count; i++)
|
2020-05-21 19:04:55 +00:00
|
|
|
|
{
|
2020-11-09 21:18:25 +00:00
|
|
|
|
if ((wiresB[i].destinationPortUsage == port.usage && wiresB[i].destinationBlockEGID == blockID)
|
|
|
|
|
|| (wiresB[i].sourcePortUsage == port.usage && wiresB[i].sourceBlockEGID == blockID))
|
2020-05-21 19:04:55 +00:00
|
|
|
|
{
|
|
|
|
|
exists = true;
|
2020-11-09 21:18:25 +00:00
|
|
|
|
return ref wiresB[i];
|
2020-05-21 19:04:55 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
exists = false;
|
|
|
|
|
WireEntityStruct[] defRef = new WireEntityStruct[1];
|
|
|
|
|
return ref defRef[0];
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-03 16:45:38 +00:00
|
|
|
|
public ref WireEntityStruct MatchBlocksToWire(EGID startBlock, EGID endBlock, out bool exists, byte startPort = byte.MaxValue,
|
|
|
|
|
byte endPort = byte.MaxValue)
|
|
|
|
|
{
|
|
|
|
|
EGID[] startPorts;
|
|
|
|
|
if (startPort == byte.MaxValue)
|
|
|
|
|
{
|
|
|
|
|
// search all output ports on source block
|
|
|
|
|
startPorts = GetSignalOutputs(startBlock);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
BlockPortsStruct ports = entitiesDB.QueryEntity<BlockPortsStruct>(startBlock);
|
|
|
|
|
startPorts = new EGID[] {new EGID(ports.firstOutputID + startPort, NamedExclusiveGroup<OutputPortsGroup>.Group) };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
EGID[] endPorts;
|
|
|
|
|
if (startPort == byte.MaxValue)
|
|
|
|
|
{
|
|
|
|
|
// search all input ports on destination block
|
|
|
|
|
endPorts = GetSignalInputs(endBlock);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
BlockPortsStruct ports = entitiesDB.QueryEntity<BlockPortsStruct>(endBlock);
|
|
|
|
|
endPorts = new EGID[] {new EGID(ports.firstInputID + endPort, NamedExclusiveGroup<InputPortsGroup>.Group) };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
EntityCollection<WireEntityStruct> wires = entitiesDB.QueryEntities<WireEntityStruct>(NamedExclusiveGroup<WiresGroup>.Group);
|
2020-11-09 21:18:25 +00:00
|
|
|
|
var wiresB = wires.ToBuffer().buffer;
|
2020-08-03 16:45:38 +00:00
|
|
|
|
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]);
|
|
|
|
|
for (int w = 0; w < wires.count; w++)
|
|
|
|
|
{
|
2020-11-09 21:18:25 +00:00
|
|
|
|
if ((wiresB[w].destinationPortUsage == endPES.usage && wiresB[w].destinationBlockEGID == endBlock)
|
|
|
|
|
&& (wiresB[w].sourcePortUsage == startPES.usage && wiresB[w].sourceBlockEGID == startBlock))
|
2020-08-03 16:45:38 +00:00
|
|
|
|
{
|
|
|
|
|
exists = true;
|
2020-11-09 21:18:25 +00:00
|
|
|
|
return ref wiresB[w];
|
2020-08-03 16:45:38 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
exists = false;
|
|
|
|
|
WireEntityStruct[] defRef = new WireEntityStruct[1];
|
|
|
|
|
return ref defRef[0];
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-21 19:04:55 +00:00
|
|
|
|
public ref ChannelDataStruct GetChannelDataStruct(EGID portID, out bool exists)
|
|
|
|
|
{
|
|
|
|
|
ref PortEntityStruct port = ref entitiesDB.QueryEntity<PortEntityStruct>(portID);
|
2020-06-12 15:27:36 +00:00
|
|
|
|
var channels = entitiesDB.QueryEntities<ChannelDataStruct>(NamedExclusiveGroup<ChannelDataGroup>.Group);
|
2020-11-09 21:18:25 +00:00
|
|
|
|
var channelsB = channels.ToBuffer();
|
2020-06-12 15:27:36 +00:00
|
|
|
|
if (port.firstChannelIndexCachedInSim < channels.count)
|
2020-05-21 19:04:55 +00:00
|
|
|
|
{
|
|
|
|
|
exists = true;
|
2020-11-09 21:18:25 +00:00
|
|
|
|
return ref channelsB.buffer[port.firstChannelIndexCachedInSim];
|
2020-05-21 19:04:55 +00:00
|
|
|
|
}
|
|
|
|
|
exists = false;
|
|
|
|
|
ChannelDataStruct[] defRef = new ChannelDataStruct[1];
|
|
|
|
|
return ref defRef[0];
|
|
|
|
|
}
|
|
|
|
|
|
2020-02-20 01:32:58 +00:00
|
|
|
|
public EGID[] GetElectricBlocks()
|
2020-07-10 22:30:58 +00:00
|
|
|
|
{
|
|
|
|
|
var res = new FasterList<EGID>();
|
|
|
|
|
foreach (var (coll, _) in entitiesDB.QueryEntities<BlockPortsStruct>())
|
2020-11-09 21:18:25 +00:00
|
|
|
|
{
|
|
|
|
|
var collB = coll.ToBuffer();
|
|
|
|
|
for (int i = 0; i < coll.count; i++)
|
|
|
|
|
{
|
|
|
|
|
ref BlockPortsStruct s = ref collB.buffer[i];
|
|
|
|
|
res.Add(s.ID);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-07-10 22:30:58 +00:00
|
|
|
|
return res.ToArray();
|
2019-12-25 19:25:53 +00:00
|
|
|
|
}
|
2020-04-28 13:55:08 +00:00
|
|
|
|
|
2020-08-03 16:45:38 +00:00
|
|
|
|
public EGID[] WiredToInput(EGID block, byte port)
|
|
|
|
|
{
|
|
|
|
|
WireEntityStruct[] wireEntityStructs = Search(NamedExclusiveGroup<WiresGroup>.Group,
|
|
|
|
|
(WireEntityStruct wes) => wes.destinationPortUsage == port && wes.destinationBlockEGID == block);
|
|
|
|
|
EGID[] result = new EGID[wireEntityStructs.Length];
|
|
|
|
|
for (uint i = 0; i < wireEntityStructs.Length; i++)
|
|
|
|
|
{
|
|
|
|
|
result[i] = wireEntityStructs[i].ID;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public EGID[] WiredToOutput(EGID block, byte port)
|
|
|
|
|
{
|
|
|
|
|
WireEntityStruct[] wireEntityStructs = Search(NamedExclusiveGroup<WiresGroup>.Group,
|
|
|
|
|
(WireEntityStruct wes) => wes.sourcePortUsage == port && wes.sourceBlockEGID == block);
|
|
|
|
|
EGID[] result = new EGID[wireEntityStructs.Length];
|
|
|
|
|
for (uint i = 0; i < wireEntityStructs.Length; i++)
|
|
|
|
|
{
|
|
|
|
|
result[i] = wireEntityStructs[i].ID;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-09 21:18:25 +00:00
|
|
|
|
private T[] Search<T>(ExclusiveGroup group, Func<T, bool> isMatch) where T : unmanaged, IEntityComponent
|
2020-08-03 16:45:38 +00:00
|
|
|
|
{
|
|
|
|
|
FasterList<T> results = new FasterList<T>();
|
|
|
|
|
EntityCollection<T> components = entitiesDB.QueryEntities<T>(group);
|
2020-11-09 21:18:25 +00:00
|
|
|
|
var componentsB = components.ToBuffer();
|
2020-08-03 16:45:38 +00:00
|
|
|
|
for (uint i = 0; i < components.count; i++)
|
|
|
|
|
{
|
2020-11-09 21:18:25 +00:00
|
|
|
|
if (isMatch(componentsB.buffer[i]))
|
2020-08-03 16:45:38 +00:00
|
|
|
|
{
|
2020-11-09 21:18:25 +00:00
|
|
|
|
results.Add(componentsB.buffer[i]);
|
2020-08-03 16:45:38 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return results.ToArray();
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-07 17:55:00 +00:00
|
|
|
|
private ref T GetFromDbOrInitData<T>(Block block, EGID id, out bool exists) where T : unmanaged, IEntityComponent
|
2020-08-03 16:45:38 +00:00
|
|
|
|
{
|
|
|
|
|
T[] defRef = new T[1];
|
|
|
|
|
if (entitiesDB.Exists<T>(id))
|
|
|
|
|
{
|
|
|
|
|
exists = true;
|
|
|
|
|
return ref entitiesDB.QueryEntity<T>(id);
|
|
|
|
|
}
|
|
|
|
|
if (block == null || block.InitData.Group == null)
|
|
|
|
|
{
|
|
|
|
|
exists = false;
|
|
|
|
|
return ref defRef[0];
|
|
|
|
|
}
|
2021-04-30 20:36:54 +00:00
|
|
|
|
EntityInitializer initializer = new EntityInitializer(block.Id, block.InitData.Group, block.InitData.Reference);
|
2020-08-03 16:45:38 +00:00
|
|
|
|
if (initializer.Has<T>())
|
|
|
|
|
{
|
|
|
|
|
exists = true;
|
|
|
|
|
return ref initializer.Get<T>();
|
|
|
|
|
}
|
|
|
|
|
exists = false;
|
|
|
|
|
return ref defRef[0];
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-12 15:27:36 +00:00
|
|
|
|
private EntityCollection<ChannelDataStruct> GetSignalStruct(uint signalID, out uint index, bool input = true)
|
2020-04-28 13:55:08 +00:00
|
|
|
|
{
|
|
|
|
|
ExclusiveGroup group = input
|
|
|
|
|
? NamedExclusiveGroup<InputPortsGroup>.Group
|
|
|
|
|
: NamedExclusiveGroup<OutputPortsGroup>.Group;
|
|
|
|
|
if (entitiesDB.Exists<PortEntityStruct>(signalID, group))
|
|
|
|
|
{
|
|
|
|
|
index = entitiesDB.QueryEntity<PortEntityStruct>(signalID, group).anyChannelIndex;
|
2020-06-12 15:27:36 +00:00
|
|
|
|
var channelData =
|
|
|
|
|
entitiesDB.QueryEntities<ChannelDataStruct>(NamedExclusiveGroup<ChannelDataGroup>.Group);
|
2020-04-28 13:55:08 +00:00
|
|
|
|
return channelData;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
index = 0;
|
2020-06-12 15:27:36 +00:00
|
|
|
|
return default; //count: 0
|
2020-04-28 13:55:08 +00:00
|
|
|
|
}
|
2019-12-25 19:25:53 +00:00
|
|
|
|
}
|
|
|
|
|
}
|