MemoryCellSystem.cs 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. using Content.Server.DeviceLinking.Components;
  2. using Content.Server.DeviceLinking.Events;
  3. using Content.Server.DeviceNetwork;
  4. using Content.Shared.DeviceLinking;
  5. namespace Content.Server.DeviceLinking.Systems;
  6. /// <summary>
  7. /// Handles the control of output based on the input and enable ports.
  8. /// </summary>
  9. public sealed class MemoryCellSystem : EntitySystem
  10. {
  11. [Dependency] private readonly DeviceLinkSystem _deviceLink = default!;
  12. public override void Initialize()
  13. {
  14. base.Initialize();
  15. SubscribeLocalEvent<MemoryCellComponent, ComponentInit>(OnInit);
  16. SubscribeLocalEvent<MemoryCellComponent, SignalReceivedEvent>(OnSignalReceived);
  17. }
  18. public override void Update(float deltaTime)
  19. {
  20. base.Update(deltaTime);
  21. var query = EntityQueryEnumerator<MemoryCellComponent, DeviceLinkSourceComponent>();
  22. while (query.MoveNext(out var uid, out var comp, out var source))
  23. {
  24. if (comp.InputState == SignalState.Momentary)
  25. comp.InputState = SignalState.Low;
  26. if (comp.EnableState == SignalState.Momentary)
  27. comp.EnableState = SignalState.Low;
  28. UpdateOutput((uid, comp, source));
  29. }
  30. }
  31. private void OnInit(Entity<MemoryCellComponent> ent, ref ComponentInit args)
  32. {
  33. var (uid, comp) = ent;
  34. _deviceLink.EnsureSinkPorts(uid, comp.InputPort, comp.EnablePort);
  35. _deviceLink.EnsureSourcePorts(uid, comp.OutputPort);
  36. }
  37. private void OnSignalReceived(Entity<MemoryCellComponent> ent, ref SignalReceivedEvent args)
  38. {
  39. var state = SignalState.Momentary;
  40. args.Data?.TryGetValue(DeviceNetworkConstants.LogicState, out state);
  41. if (args.Port == ent.Comp.InputPort)
  42. ent.Comp.InputState = state;
  43. else if (args.Port == ent.Comp.EnablePort)
  44. ent.Comp.EnableState = state;
  45. UpdateOutput(ent);
  46. }
  47. private void UpdateOutput(Entity<MemoryCellComponent, DeviceLinkSourceComponent?> ent)
  48. {
  49. if (!Resolve(ent, ref ent.Comp2))
  50. return;
  51. if (ent.Comp1.EnableState == SignalState.Low)
  52. return;
  53. var value = ent.Comp1.InputState != SignalState.Low;
  54. if (value == ent.Comp1.LastOutput)
  55. return;
  56. ent.Comp1.LastOutput = value;
  57. _deviceLink.SendSignal(ent, ent.Comp1.OutputPort, value, ent.Comp2);
  58. }
  59. }