using Content.Server.DeviceLinking.Components;
using Content.Server.DeviceNetwork;
using Content.Shared.DeviceLinking;
using Content.Shared.DeviceLinking.Events;
namespace Content.Server.DeviceLinking.Systems;
///
/// Handles the control of output based on the input and enable ports.
///
public sealed class MemoryCellSystem : EntitySystem
{
[Dependency] private readonly DeviceLinkSystem _deviceLink = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent(OnInit);
SubscribeLocalEvent(OnSignalReceived);
}
public override void Update(float deltaTime)
{
base.Update(deltaTime);
var query = EntityQueryEnumerator();
while (query.MoveNext(out var uid, out var comp, out var source))
{
if (comp.InputState == SignalState.Momentary)
comp.InputState = SignalState.Low;
if (comp.EnableState == SignalState.Momentary)
comp.EnableState = SignalState.Low;
UpdateOutput((uid, comp, source));
}
}
private void OnInit(Entity ent, ref ComponentInit args)
{
var (uid, comp) = ent;
_deviceLink.EnsureSinkPorts(uid, comp.InputPort, comp.EnablePort);
_deviceLink.EnsureSourcePorts(uid, comp.OutputPort);
}
private void OnSignalReceived(Entity ent, ref SignalReceivedEvent args)
{
var state = SignalState.Momentary;
args.Data?.TryGetValue(DeviceNetworkConstants.LogicState, out state);
if (args.Port == ent.Comp.InputPort)
ent.Comp.InputState = state;
else if (args.Port == ent.Comp.EnablePort)
ent.Comp.EnableState = state;
UpdateOutput(ent);
}
private void UpdateOutput(Entity ent)
{
if (!Resolve(ent, ref ent.Comp2))
return;
if (ent.Comp1.EnableState == SignalState.Low)
return;
var value = ent.Comp1.InputState != SignalState.Low;
if (value == ent.Comp1.LastOutput)
return;
ent.Comp1.LastOutput = value;
_deviceLink.SendSignal(ent, ent.Comp1.OutputPort, value, ent.Comp2);
}
}