Relations - RealityStop/Bolt.Addons.Community GitHub Wiki
You may notice by now that certain units may show up, dim, orange, or red. These warnings and errors actual have code you utilize in a units Definition to help express when ports may be required in some sort of fashion.
This will be a much shorter, and easier tutorial. There is only 4 methods to be concerned about, that will get your Units providing proper errors and warnings for the user, so less mistakes exist during runtime.
Input and Events, these are your typical control roots. It is not a limit though. When you have a unit that is in charge of starting flow in a graph, this is what we call a Control Root. If your unit does not implement it, and a control root unit is not connected either directly, or through units that are connected to this unit, it will appear as dimmed, or partially transparent. To solve this, we use isControlRoot
.
You have two options. Override the property itself (both its getter and or setter), or set it with or without some logic in Definition.
public override bool isControlRoot => true;
protected override void Definition()
{
isControlRoot = true;
}
Requirement, says two things:
-
When you enter a Control Input port, you expect to get the Value Input port.
-
When you get a Value Output port, you expect the use a Value Input port.
For instance, with our Type Writer, we require both text and the delay to be assigned when we enter the start port.
If you would like to actually see what the relationships look like, you can turn on relation in the graph toolbar.
This would be done like this:
protected override void Definition()
{
start = ControlInputCoroutine("start", WriteText);
text = ValueInput<string>("text");
delay = ValueInput<string>("delay");
current = ValueOutput<string>("current", (flow) => { return storedText; });
typed = ControlOutput("typed");
complete = ControlOutput("complete");
exit = ControlOutput("exit");
Requirement(text, start); // Start control input requires a value for text
Requirement(delay, start); // Start control input requires a value for delay
}
This is without the requirement

When a Unit has uses Requirement and the port does not have a DefaultValue or Connection it will give you a warning that the port requires a value.

Succession, deals with the success of flow entry to output. It says, that the specific output port of a unit, might require you to enter an input port for the output to be invoked. There is no visual errors here, as it is only done on a possible scenario. You can see how its layed out by looking at the relations.
We know that all output Control ports cannot happen until the start port is entered. This will be our succession. Take a look:
protected override void Definition()
{
start = ControlInputCoroutine("start", WriteText);
text = ValueInput<string>("text");
delay = ValueInput<string>("delay");
current = ValueOutput<string>("current", (flow) => { return storedText; });
typed = ControlOutput("typed");
complete = ControlOutput("complete");
exit = ControlOutput("exit");
Requirement(text, start);
Requirement(delay, start);
Succession(start, exit); // Start will trigger exit
Succession(start, typed); // Start will trigger typed
Succession(start, complete); // Start will trigger complete
}
This is the unit without Succession

This is the unit with Succession

Assignment is the last type of error handling for our units. This states one simple thing. Entering a ControlInput port may cause the output port to be assigned a value. In our case, when we enter, we immediately start assigning, but it is not in charge of assigning the variable itself. The coroutine does this. Just for example purposes, here is what that looks like:
protected override void Definition()
{
start = ControlInputCoroutine("start", WriteText);
text = ValueInput<string>("text");
delay = ValueInput<string>("delay");
current = ValueOutput<string>("current", (flow) => { return storedText; });
typed = ControlOutput("typed");
complete = ControlOutput("complete");
exit = ControlOutput("exit");
Requirement(text, start);
Requirement(delay, start);
Succession(start, exit);
Succession(start, typed);
Succession(start, complete);
Assignment(start, current); // Start will assign current
}
This is the unit without Assignment

This is the unit with Assignment

If trying to use the port Without connecting the ControlInput that assigns the value you will get a warning.