namespace Unity.VisualScripting
{
///
/// Toggles the control flow with on and off triggers.
///
[UnitCategory("Control")]
[UnitOrder(18)]
[UnitFooterPorts(ControlInputs = true, ControlOutputs = true)]
public sealed class ToggleFlow : Unit, IGraphElementWithData
{
public class Data : IGraphElementData
{
public bool isOn;
}
///
/// Whether the toggle should start in the on state.
///
[Serialize]
[Inspectable]
[UnitHeaderInspectable("Start On")]
[InspectorToggleLeft]
public bool startOn { get; set; } = true;
///
/// Entry point to the toggle.
///
[DoNotSerialize]
[PortLabelHidden]
public ControlInput enter { get; private set; }
///
/// Trigger to turn on the flow through the toggle.
///
[DoNotSerialize]
[PortLabel("On")]
public ControlInput turnOn { get; private set; }
///
/// Trigger to turn off the flow through the toggle.
///
[DoNotSerialize]
[PortLabel("Off")]
public ControlInput turnOff { get; private set; }
///
/// Trigger to toggle the flow through the toggle.
///
[DoNotSerialize]
public ControlInput toggle { get; private set; }
///
/// Triggered on entry if the flow is on.
///
[DoNotSerialize]
[PortLabel("On")]
public ControlOutput exitOn { get; private set; }
///
/// Triggered on entry if the flow is off.
///
[DoNotSerialize]
[PortLabel("Off")]
public ControlOutput exitOff { get; private set; }
///
/// Triggered when the flow gets turned on.
///
[DoNotSerialize]
public ControlOutput turnedOn { get; private set; }
///
/// Triggered when the flow gets turned off.
///
[DoNotSerialize]
public ControlOutput turnedOff { get; private set; }
///
/// Whether the flow is currently on.
///
[DoNotSerialize]
public ValueOutput isOn { get; private set; }
protected override void Definition()
{
enter = ControlInput(nameof(enter), Enter);
turnOn = ControlInput(nameof(turnOn), TurnOn);
turnOff = ControlInput(nameof(turnOff), TurnOff);
toggle = ControlInput(nameof(toggle), Toggle);
exitOn = ControlOutput(nameof(exitOn));
exitOff = ControlOutput(nameof(exitOff));
turnedOn = ControlOutput(nameof(turnedOn));
turnedOff = ControlOutput(nameof(turnedOff));
isOn = ValueOutput(nameof(isOn), IsOn);
Succession(enter, exitOn);
Succession(enter, exitOff);
Succession(turnOn, turnedOn);
Succession(turnOff, turnedOff);
Succession(toggle, turnedOn);
Succession(toggle, turnedOff);
}
public IGraphElementData CreateData()
{
return new Data() { isOn = startOn };
}
private bool IsOn(Flow flow)
{
return flow.stack.GetElementData(this).isOn;
}
private ControlOutput Enter(Flow flow)
{
return IsOn(flow) ? exitOn : exitOff;
}
private ControlOutput TurnOn(Flow flow)
{
var data = flow.stack.GetElementData(this);
if (data.isOn)
{
return null;
}
data.isOn = true;
return turnedOn;
}
private ControlOutput TurnOff(Flow flow)
{
var data = flow.stack.GetElementData(this);
if (!data.isOn)
{
return null;
}
data.isOn = false;
return turnedOff;
}
private ControlOutput Toggle(Flow flow)
{
var data = flow.stack.GetElementData(this);
data.isOn = !data.isOn;
return data.isOn ? turnedOn : turnedOff;
}
}
}