Client LuaCsForBarotrauma
DelayComponent.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Globalization;
4 using System.Xml.Linq;
5 using Microsoft.Xna.Framework;
7 {
9  {
10  class DelayedSignal
11  {
12  public readonly Signal Signal;
13  //in number of frames
14  public int SendTimer;
15  //in number of frames
16  public int SendDuration;
17 
18  public DelayedSignal(Signal signal, int sendTimer)
19  {
20  Signal = signal;
21  SendTimer = sendTimer;
22  }
23  }
24 
25  private int signalQueueSize;
26  private int delayTicks;
27 
28  private readonly Queue<DelayedSignal> signalQueue = new Queue<DelayedSignal>();
29 
30  private DelayedSignal prevQueuedSignal;
31 
32  private float delay;
33  [InGameEditable(MinValueFloat = 0.0f, MaxValueFloat = 60.0f, DecimalCount = 2), Serialize(1.0f, IsPropertySaveable.Yes, description: "How long the item delays the signals (in seconds).", alwaysUseInstanceValues: true)]
34  public float Delay
35  {
36  get { return delay; }
37  set
38  {
39  if (value == delay) { return; }
40  delay = value;
41  delayTicks = (int)(delay / Timing.Step);
42  signalQueueSize = Math.Max(delayTicks, 1) * 2;
43  signalQueue.Clear();
44  }
45  }
46 
47  [InGameEditable, Serialize(false, IsPropertySaveable.Yes, description: "Should the component discard previously received signals when a new one is received.", alwaysUseInstanceValues: true)]
49  {
50  get;
51  set;
52  }
53 
54  [InGameEditable, Serialize(false, IsPropertySaveable.Yes, description: "Should the component discard previously received signals when the incoming signal changes.", alwaysUseInstanceValues: true)]
56  {
57  get;
58  set;
59  }
60 
62  : base (item, element)
63  {
64  IsActive = true;
65  }
66 
67  public override void Update(float deltaTime, Camera cam)
68  {
69  if (signalQueue.Count == 0)
70  {
71  IsActive = false;
72  return;
73  }
74 
75  foreach (var val in signalQueue)
76  {
77  val.SendTimer -= 1;
78  }
79  while (signalQueue.Count > 0 && signalQueue.Peek().SendTimer <= 0)
80  {
81  var signalOut = signalQueue.Peek();
82  signalOut.SendDuration -= 1;
83  item.SendSignal(new Signal(signalOut.Signal.value, sender: signalOut.Signal.sender, strength: signalOut.Signal.strength), "signal_out");
84  if (signalOut.SendDuration <= 0)
85  {
86  //check the queue isn't empty again, because sending the signal may empty it
87  //if this component is set to reset when it receives a signal and the signal is routed back to this component
88  signalQueue.TryDequeue(out _);
89  }
90  else
91  {
92  break;
93  }
94  }
95  }
96 
97  public override void ReceiveSignal(Signal signal, Connection connection)
98  {
99  switch (connection.Name)
100  {
101  case "signal_in":
102  if (signalQueue.Count >= signalQueueSize) { return; }
103  if (ResetWhenSignalReceived) { prevQueuedSignal = null; signalQueue.Clear(); }
104  if (ResetWhenDifferentSignalReceived && signalQueue.Count > 0 && signalQueue.Peek().Signal.value != signal.value)
105  {
106  prevQueuedSignal = null;
107  signalQueue.Clear();
108  }
109 
110  if (prevQueuedSignal != null &&
111  prevQueuedSignal.Signal.value == signal.value &&
112  MathUtils.NearlyEqual(prevQueuedSignal.Signal.strength, signal.strength) &&
113  ((prevQueuedSignal.SendTimer + prevQueuedSignal.SendDuration == delayTicks) || (prevQueuedSignal.SendTimer <= 0 && prevQueuedSignal.SendDuration > 0)))
114  {
115  prevQueuedSignal.SendDuration += 1;
116  return;
117  }
118 
119  prevQueuedSignal = new DelayedSignal(signal, delayTicks)
120  {
121  SendDuration = 1
122  };
123  signalQueue.Enqueue(prevQueuedSignal);
124  IsActive = true;
125  break;
126  case "set_delay":
127  if (float.TryParse(signal.value, NumberStyles.Any, CultureInfo.InvariantCulture, out float newDelay))
128  {
129  newDelay = MathHelper.Clamp(newDelay, 0, 60);
130  if (signalQueue.Count > 0 && newDelay != Delay)
131  {
132  prevQueuedSignal = null;
133  signalQueue.Clear();
134  }
135  Delay = newDelay;
136  }
137  break;
138  }
139  }
140  }
141 }
void SendSignal(string signal, string connectionName)
DelayComponent(Item item, ContentXElement element)
override void ReceiveSignal(Signal signal, Connection connection)
override void Update(float deltaTime, Camera cam)
The base class for components holding the different functionalities of the item