NorbiPeti
f403feb298
Removed BlockIdentifiers.OWNED_BLOCKS as the original got replaced with an array Added the correct group for each supported functional block Removed EntityFactory property from IEntitySerializer as it is provided on deserialization
195 lines
6.2 KiB
C#
195 lines
6.2 KiB
C#
using Svelto.ECS;
|
|
using Svelto.DataStructures;
|
|
using Gamecraft.Wires;
|
|
|
|
using GamecraftModdingAPI.Engines;
|
|
|
|
namespace GamecraftModdingAPI.Blocks
|
|
{
|
|
/// <summary>
|
|
/// 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; }
|
|
|
|
public bool isRemovable => false;
|
|
|
|
public bool IsInGame = false;
|
|
|
|
public void Dispose()
|
|
{
|
|
IsInGame = false;
|
|
}
|
|
|
|
public void Ready()
|
|
{
|
|
IsInGame = true;
|
|
}
|
|
|
|
// implementations for Signal static class
|
|
|
|
public bool SetSignal(EGID blockID, float signal, out uint signalID, bool input = true)
|
|
{
|
|
signalID = GetSignalIDs(blockID, input)[0];
|
|
return SetSignal(signalID, signal);
|
|
}
|
|
|
|
public bool SetSignal(uint signalID, float signal, bool input = true)
|
|
{
|
|
var array = GetSignalStruct(signalID, out uint index, input);
|
|
if (array.count > 0) array[index].valueAsFloat = signal;
|
|
return false;
|
|
}
|
|
|
|
public float AddSignal(EGID blockID, float signal, out uint signalID, bool clamp = true, bool input = true)
|
|
{
|
|
signalID = GetSignalIDs(blockID, input)[0];
|
|
return AddSignal(signalID, signal, clamp, input);
|
|
}
|
|
|
|
public float AddSignal(uint signalID, float signal, bool clamp = true, bool input = true)
|
|
{
|
|
var array = GetSignalStruct(signalID, out uint index, input);
|
|
if (array.count > 0)
|
|
{
|
|
ref var channelData = ref array[index];
|
|
channelData.valueAsFloat += signal;
|
|
if (clamp)
|
|
{
|
|
if (channelData.valueAsFloat > POSITIVE_HIGH)
|
|
{
|
|
channelData.valueAsFloat = POSITIVE_HIGH;
|
|
}
|
|
else if (channelData.valueAsFloat < NEGATIVE_HIGH)
|
|
{
|
|
channelData.valueAsFloat = NEGATIVE_HIGH;
|
|
}
|
|
|
|
return channelData.valueAsFloat;
|
|
}
|
|
}
|
|
|
|
return signal;
|
|
}
|
|
|
|
public float GetSignal(EGID blockID, out uint signalID, bool input = true)
|
|
{
|
|
signalID = GetSignalIDs(blockID, input)[0];
|
|
return GetSignal(signalID, input);
|
|
}
|
|
|
|
public float GetSignal(uint signalID, bool input = true)
|
|
{
|
|
var array = GetSignalStruct(signalID, out uint index, input);
|
|
return array.count > 0 ? array[index].valueAsFloat : 0f;
|
|
}
|
|
|
|
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];
|
|
}
|
|
|
|
public EGID[] GetElectricBlocks()
|
|
{
|
|
var res = new FasterList<EGID>();
|
|
foreach (var (coll, _) in entitiesDB.QueryEntities<BlockPortsStruct>())
|
|
foreach (ref BlockPortsStruct s in coll)
|
|
res.Add(s.ID);
|
|
return res.ToArray();
|
|
}
|
|
|
|
private EntityCollection<ChannelDataStruct> GetSignalStruct(uint signalID, out uint index, bool input = true)
|
|
{
|
|
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);
|
|
return channelData;
|
|
}
|
|
|
|
index = 0;
|
|
return default; //count: 0
|
|
}
|
|
}
|
|
}
|