A game about forced loneliness, made by TACStudios
1namespace Unity.VisualScripting
2{
3 /// <summary>
4 /// Toggles the control flow with on and off triggers.
5 /// </summary>
6 [UnitCategory("Control")]
7 [UnitOrder(18)]
8 [UnitFooterPorts(ControlInputs = true, ControlOutputs = true)]
9 public sealed class ToggleFlow : Unit, IGraphElementWithData
10 {
11 public class Data : IGraphElementData
12 {
13 public bool isOn;
14 }
15
16 /// <summary>
17 /// Whether the toggle should start in the on state.
18 /// </summary>
19 [Serialize]
20 [Inspectable]
21 [UnitHeaderInspectable("Start On")]
22 [InspectorToggleLeft]
23 public bool startOn { get; set; } = true;
24
25 /// <summary>
26 /// Entry point to the toggle.
27 /// </summary>
28 [DoNotSerialize]
29 [PortLabelHidden]
30 public ControlInput enter { get; private set; }
31
32 /// <summary>
33 /// Trigger to turn on the flow through the toggle.
34 /// </summary>
35 [DoNotSerialize]
36 [PortLabel("On")]
37 public ControlInput turnOn { get; private set; }
38
39 /// <summary>
40 /// Trigger to turn off the flow through the toggle.
41 /// </summary>
42 [DoNotSerialize]
43 [PortLabel("Off")]
44 public ControlInput turnOff { get; private set; }
45
46 /// <summary>
47 /// Trigger to toggle the flow through the toggle.
48 /// </summary>
49 [DoNotSerialize]
50 public ControlInput toggle { get; private set; }
51
52 /// <summary>
53 /// Triggered on entry if the flow is on.
54 /// </summary>
55 [DoNotSerialize]
56 [PortLabel("On")]
57 public ControlOutput exitOn { get; private set; }
58
59 /// <summary>
60 /// Triggered on entry if the flow is off.
61 /// </summary>
62 [DoNotSerialize]
63 [PortLabel("Off")]
64 public ControlOutput exitOff { get; private set; }
65
66 /// <summary>
67 /// Triggered when the flow gets turned on.
68 /// </summary>
69 [DoNotSerialize]
70 public ControlOutput turnedOn { get; private set; }
71
72 /// <summary>
73 /// Triggered when the flow gets turned off.
74 /// </summary>
75 [DoNotSerialize]
76 public ControlOutput turnedOff { get; private set; }
77
78 /// <summary>
79 /// Whether the flow is currently on.
80 /// </summary>
81 [DoNotSerialize]
82 public ValueOutput isOn { get; private set; }
83
84 protected override void Definition()
85 {
86 enter = ControlInput(nameof(enter), Enter);
87 turnOn = ControlInput(nameof(turnOn), TurnOn);
88 turnOff = ControlInput(nameof(turnOff), TurnOff);
89 toggle = ControlInput(nameof(toggle), Toggle);
90
91 exitOn = ControlOutput(nameof(exitOn));
92 exitOff = ControlOutput(nameof(exitOff));
93 turnedOn = ControlOutput(nameof(turnedOn));
94 turnedOff = ControlOutput(nameof(turnedOff));
95
96 isOn = ValueOutput(nameof(isOn), IsOn);
97
98 Succession(enter, exitOn);
99 Succession(enter, exitOff);
100 Succession(turnOn, turnedOn);
101 Succession(turnOff, turnedOff);
102 Succession(toggle, turnedOn);
103 Succession(toggle, turnedOff);
104 }
105
106 public IGraphElementData CreateData()
107 {
108 return new Data() { isOn = startOn };
109 }
110
111 private bool IsOn(Flow flow)
112 {
113 return flow.stack.GetElementData<Data>(this).isOn;
114 }
115
116 private ControlOutput Enter(Flow flow)
117 {
118 return IsOn(flow) ? exitOn : exitOff;
119 }
120
121 private ControlOutput TurnOn(Flow flow)
122 {
123 var data = flow.stack.GetElementData<Data>(this);
124
125 if (data.isOn)
126 {
127 return null;
128 }
129
130 data.isOn = true;
131
132 return turnedOn;
133 }
134
135 private ControlOutput TurnOff(Flow flow)
136 {
137 var data = flow.stack.GetElementData<Data>(this);
138
139 if (!data.isOn)
140 {
141 return null;
142 }
143
144 data.isOn = false;
145
146 return turnedOff;
147 }
148
149 private ControlOutput Toggle(Flow flow)
150 {
151 var data = flow.stack.GetElementData<Data>(this);
152
153 data.isOn = !data.isOn;
154
155 return data.isOn ? turnedOn : turnedOff;
156 }
157 }
158}