using System;
using Gamecraft.Wires;
using Svelto.ECS;
using Unity.Mathematics;
using GamecraftModdingAPI;
using GamecraftModdingAPI.Utility;
namespace GamecraftModdingAPI.Blocks
{
///
/// Common implementation for blocks that support wiring.
///
public class SignalingBlock : Block
{
public SignalingBlock(EGID id) : base(id)
{
}
public SignalingBlock(uint id) : base(id)
{
}
///
/// Generates the input port identifiers.
///
/// The input identifiers.
protected EGID[] GetInputIds()
{
return SignalEngine.GetSignalInputs(Id);
}
///
/// Generates the output port identifiers.
///
/// The output identifiers.
protected EGID[] GetOutputIds()
{
return SignalEngine.GetSignalOutputs(Id);
}
///
/// Gets the connected wire.
///
/// The connected wire.
/// Port identifier.
/// Whether the port has a wire connected to it.
protected ref WireEntityStruct GetConnectedWire(EGID portId, out bool connected)
{
return ref SignalEngine.MatchPortToWire(portId, Id, out connected);
}
///
/// [EXPERIMENTAL] Gets the channel data.
///
/// The channel data.
/// Port identifier.
/// Whether the channel actually exists.
protected ref ChannelDataStruct GetChannelData(EGID portId, out bool exists)
{
return ref SignalEngine.GetChannelDataStruct(portId, out exists);
}
///
/// The input port count.
///
public uint InputCount
{
get => BlockEngine.GetBlockInfo(this, (BlockPortsStruct st) => st.inputCount);
}
///
/// The output port count.
///
public uint OutputCount
{
get => BlockEngine.GetBlockInfo(this, (BlockPortsStruct st) => st.outputCount);
}
///
/// Connect an output on this block to an input on another block.
///
/// Output port number.
/// Input block.
/// Input port number.
/// The wire connection
/// The wire could not be created.
public Wire Connect(byte sourcePort, SignalingBlock destination, byte destinationPort)
{
if (sourcePort >= OutputCount)
{
throw new WiringException("Source port does not exist");
}
if (destinationPort >= destination.InputCount)
{
throw new WiringException("Destination port does not exist");
}
return Wire.Connect(this, sourcePort, destination, destinationPort);
}
///
/// The port's name.
/// This is localized to the user's language, so this is not reliable for port identification.
///
/// Port number.
/// Whether the port is an input (true) or an output (false).
/// The localized port name.
public string PortName(byte port, bool input)
{
BlockPortsStruct bps = BlockEngine.GetBlockInfo(this, (BlockPortsStruct a) => a);
PortEntityStruct pes = SignalEngine.GetPortByOffset(this, port, input);
return pes.portNameLocalised;
}
///
/// The input port's name.
///
/// Input port number.
/// The port name, localized to the user's language.
public string InputPortName(byte port) => PortName(port, true);
///
/// The output port's name.
///
/// Output port number.
/// The port name, localized to the user's language.
public string OutputPortName(byte port) => PortName(port, false);
///
/// All wires connected to the input port.
/// These wires will always be wired output -> input.
///
/// Port number.
/// Wires connected to the input port.
public Wire[] ConnectedToInput(byte port)
{
if (port >= InputCount) throw new WiringException($"Port input {port} does not exist");
EGID[] wireEgids = SignalEngine.WiredToInput(Id, port);
Wire[] wires = new Wire[wireEgids.Length];
for (uint i = 0; i < wireEgids.Length; i++)
{
wires[i] = new Wire(wireEgids[i]);
}
return wires;
}
///
/// All wires connected to the output port.
/// These wires will always be wired output -> input.
///
/// Port number.
/// Wires connected to the output port.
public Wire[] ConnectedToOutput(byte port)
{
if (port >= OutputCount) throw new WiringException($"Port output {port} does not exist");
EGID[] wireEgids = SignalEngine.WiredToOutput(Id, port);
Wire[] wires = new Wire[wireEgids.Length];
for (uint i = 0; i < wireEgids.Length; i++)
{
wires[i] = new Wire(wireEgids[i]);
}
return wires;
}
}
}