Command Groups and Utilities
Parallel
Runs commands in parallel (sub-sequence). This is not true concurrency, but rather, each part of each command is run in the order that they are in the constructor. (1’s initialise is run, then 2’s initialise, etc, etc.). It finishes when all commands it contains finish.
The s-expression representation of this command is:
The Parallel.addCommands()
method is non-mutating, and returns a new Parallel.
A command can be chained into a Parallel
via the Command.with()
method, this
code snippet is the same as above:
Sequential
Runs commands in sequence. (1 is run until it finishes, then 2, etc, etc.). It finishes when all commands it contains finish.
The s-expression representation of this command is:
The Sequential.addCommands()
method is non-mutating, and returns a new
Sequential.
A command can be chained into a Sequential
via the Command.then()
method,
this code snippet is the same as above:
Race / Deadline
Runs commands the same as Parallel
, but Race
finishes as soon as any command
finishes, and Deadline
finishes when the deadline command finishes. This early
end does not interrupt the rest of the unfinished commands.
Mercurial only has one class for both of these: Race
.
The s-expression representation of this command is:
deadline
is omitted if it is null.
The Race.addCommands()
and Race.setDeadline()
methods are non-mutating, and
return a new Race.
A command can be chained into a Race
via the Command.raceWith()
method,
this code snippet is the same as above:
A command can be chained into a Race
as the deadline via the
Command.asDeadline()
method, this code snippet is the same as above:
Wait
Wait waits its argument in seconds. This example waits 1 second:
The s-expression representation of this command is:
A command can be chained into a Race
with a Wait
as the deadline via the
Command.timeout(duration)
method, these two are equivalent:
IfElse
If else takes a BooleanSupplier
and a command to run if true
and a command
to run if false
. When the command is initialised it runs the supplier and uses
the result to decide if to run trueCommand
or falseCommand
.
This example will always run 1
, because it always returns true.
The s-expression representation of this command is:
StateMachine
StateMachine is a Finite State Machine (FSM) command. It makes it easy to assemble a state machine where each state is a command. It finishes if the command for the current state is finished, and there isn’t a state change underway.
We’ll use this enum for the example:
StateMachine
can work with any state type, read more about RefCell
in Util.
Its important to note that StateMachine.withState()
is non-mutating.
Additionally, you must ensure that the StateMachine
never has a state that
doesn’t exist while scheduled, as this will cause it to throw an error.
The name
that is passed to the withState
callback is a preescaped name that
matches the name of the state.
The s-expression representation of this command is:
StateMachine
displays each state-command pair as (state command)
by default,
however, if state and command have the same name, then it just becomes state
,
which we can see above.
Advancing
Advancing is more of a utility for commands bound to user input.
Advancing moves forwards through the list whenever it is schedule()
d again.
This means that if it is bound to a button or similar, it makes it easy to write
some command toggle or state switcher.
In this manner, it acts a bit like Sequential
but does not advance by itself.
At the same time, it is a bit like a rudimentary StateMachine
.
Advancing wraps around, and can be manually advanced like so:
So if you advance at command ‘2’, then it wraps back to ‘1’.
Additionally, manual advancement needs a warning, manual advancement is a
‘request’ for advancement, rather than immediate advancement. This means that
the advancement needs to be processed by the advancing
command itself before
Advancing.advance()
will have affect again.
The s-expression representation of this command is: