TechbloxModdingAPI/GamecraftModdingAPI/Blocks/SignalEngine.cs

204 lines
6.6 KiB
C#
Raw Normal View History

2020-05-13 14:52:21 +00:00
using Svelto.ECS;
2020-02-20 01:32:58 +00:00
using Gamecraft.Wires;
2020-05-12 00:28:26 +00:00
using GamecraftModdingAPI.Engines;
namespace GamecraftModdingAPI.Blocks
{
/// <summary>
2020-01-04 00:54:35 +00:00
/// Engine which executes signal actions
/// </summary>
public class SignalEngine : IApiEngine
{
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;
public string Name { get; } = "GamecraftModdingAPISignalGameEngine";
public EntitiesDB entitiesDB { set; private get; }
2020-05-12 00:28:26 +00:00
public bool isRemovable => false;
2020-05-12 00:28:26 +00:00
public bool IsInGame = false;
public void Dispose()
{
IsInGame = false;
}
public void Ready()
{
IsInGame = true;
}
// implementations for Signal static class
2020-02-20 01:32:58 +00:00
public bool SetSignal(EGID blockID, float signal, out uint signalID, bool input = true)
{
2020-02-20 01:32:58 +00:00
signalID = GetSignalIDs(blockID, input)[0];
return SetSignal(signalID, signal);
}
2020-02-20 01:32:58 +00:00
public bool SetSignal(uint signalID, float signal, bool input = true)
{
2020-04-28 13:55:08 +00:00
var array = GetSignalStruct(signalID, out uint index, input);
if (array.count > 0) array[index].valueAsFloat = signal;
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)
{
2020-02-20 01:32:58 +00:00
signalID = GetSignalIDs(blockID, input)[0];
return AddSignal(signalID, signal, clamp, input);
}
2020-02-20 01:32:58 +00:00
public float AddSignal(uint signalID, float signal, bool clamp = true, bool input = true)
{
2020-04-28 13:55:08 +00:00
var array = GetSignalStruct(signalID, out uint index, input);
if (array.count > 0)
2020-04-28 13:55:08 +00:00
{
ref var channelData = ref array[index];
channelData.valueAsFloat += signal;
if (clamp)
{
if (channelData.valueAsFloat > POSITIVE_HIGH)
2020-04-28 13:55:08 +00:00
{
channelData.valueAsFloat = POSITIVE_HIGH;
2020-04-28 13:55:08 +00:00
}
else if (channelData.valueAsFloat < NEGATIVE_HIGH)
2020-04-28 13:55:08 +00:00
{
channelData.valueAsFloat = NEGATIVE_HIGH;
2020-04-28 13:55:08 +00:00
}
return channelData.valueAsFloat;
}
}
return signal;
}
2020-02-20 01:32:58 +00:00
public float GetSignal(EGID blockID, out uint signalID, bool input = true)
{
2020-02-20 01:32:58 +00:00
signalID = GetSignalIDs(blockID, input)[0];
return GetSignal(signalID, input);
}
2020-02-20 01:32:58 +00:00
public float GetSignal(uint signalID, bool input = true)
{
2020-04-28 13:55:08 +00:00
var array = GetSignalStruct(signalID, out uint index, input);
return array.count > 0 ? array[index].valueAsFloat : 0f;
}
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;
}
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;
}
public EGID[] GetSignalOutputs(EGID blockID)
{
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;
}
public ref WireEntityStruct MatchPortToWire(EGID portID, EGID blockID, out bool exists)
{
ref PortEntityStruct port = ref entitiesDB.QueryEntity<PortEntityStruct>(portID);
var wires = entitiesDB.QueryEntities<WireEntityStruct>(NamedExclusiveGroup<WiresGroup>.Group);
for (uint i = 0; i < wires.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];
}
}
exists = false;
WireEntityStruct[] defRef = new WireEntityStruct[1];
return ref defRef[0];
}
public ref ChannelDataStruct GetChannelDataStruct(EGID portID, out bool exists)
{
ref PortEntityStruct port = ref entitiesDB.QueryEntity<PortEntityStruct>(portID);
var channels = entitiesDB.QueryEntities<ChannelDataStruct>(NamedExclusiveGroup<ChannelDataGroup>.Group);
if (port.firstChannelIndexCachedInSim < channels.count)
{
exists = true;
return ref channels[port.firstChannelIndexCachedInSim];
}
exists = false;
ChannelDataStruct[] defRef = new ChannelDataStruct[1];
return ref defRef[0];
}
2020-02-20 01:32:58 +00:00
public EGID[] GetElectricBlocks()
{
uint count = entitiesDB.Count<BlockPortsStruct>(BlockIdentifiers.OWNED_BLOCKS) + entitiesDB.Count<BlockPortsStruct>(BlockIdentifiers.FUNCTIONAL_BLOCK_PARTS);
uint i = 0;
2020-02-20 01:32:58 +00:00
EGID[] res = new EGID[count];
foreach (ref BlockPortsStruct s in entitiesDB.QueryEntities<BlockPortsStruct>(BlockIdentifiers.OWNED_BLOCKS))
{
2020-02-20 01:32:58 +00:00
res[i] = s.ID;
i++;
}
2020-02-20 01:32:58 +00:00
foreach (ref BlockPortsStruct s in entitiesDB.QueryEntities<BlockPortsStruct>(BlockIdentifiers.FUNCTIONAL_BLOCK_PARTS))
{
2020-02-20 01:32:58 +00:00
res[i] = s.ID;
i++;
}
2020-02-20 01:32:58 +00:00
return res;
}
2020-04-28 13:55:08 +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;
var channelData =
entitiesDB.QueryEntities<ChannelDataStruct>(NamedExclusiveGroup<ChannelDataGroup>.Group);
2020-04-28 13:55:08 +00:00
return channelData;
}
index = 0;
return default; //count: 0
2020-04-28 13:55:08 +00:00
}
}
}