> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dairy.foundation/llms.txt
> Use this file to discover all available pages before exploring further.

# 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.

<CodeGroup>
  ```java Java theme={null}
  new Parallel(
  	new Lambda("1"),
  	new Lambda("2")
  	/*, varargs commands*/
  );
  ```

  ```kt Kotlin theme={null}
  Parallel(
  	Lambda("1"),
  	Lambda("2"),
  	/*varargs commands*/
  )
  ```
</CodeGroup>

The s-expression representation of this command is:

```
(parallel (
	1
	2))
```

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:

<CodeGroup>
  ```java Java theme={null}
  new Lambda("1")
  	.with(
  		new Lambda("2")
  		/*, varag commands*/
  	);
  ```

  ```kt Kotlin theme={null}
  Lambda("1")
  	.with(
  		Lambda("2"),
  		/*varag commands*/
  	)
  ```
</CodeGroup>

# Sequential

Runs commands in sequence. (1 is run until it finishes, then 2, etc, etc.). It
finishes when all commands it contains finish.

<CodeGroup>
  ```java Java theme={null}
  new Sequential(
  	new Lambda("1"),
  	new Lambda("2")
  	/*, varargs commands*/
  );
  ```

  ```kt Kotlin theme={null}
  Sequential(
  	Lambda("1"),
  	Lambda("2"),
  	/*varargs commands*/
  )
  ```
</CodeGroup>

The s-expression representation of this command is:

```
(sequential (
	1
	2))
```

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:

<CodeGroup>
  ```java Java theme={null}
  new Lambda("1")
  	.then(
  		new Lambda("2")
  		/*, varag commands*/
  	);
  ```

  ```kt Kotlin theme={null}
  Lambda("1")
  	.then(
  		Lambda("2"),
  		/*varag commands*/
  	)
  ```
</CodeGroup>

# 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`.

<CodeGroup>
  ```java Java theme={null}
  // race
  new Race(
  	null,
  	new Lambda("1"),
  	new Lambda("2")
  );
  // deadline
  new Race(
  	new Lambda("deadline"),
  	new Lambda("1"),
  	new Lambda("2")
  );
  ```

  ```kt Kotlin theme={null}
  // race
  Race(
  	null,
  	Lambda("1"),
  	Lambda("2")
  )
  // deadline
  Race(
  	Lambda("deadline"),
  	Lambda("1"),
  	Lambda("2")
  )
  ```
</CodeGroup>

The s-expression representation of this command is:

```
(race (
	1
	2))

(race deadline (
	1
	2))
```

`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:

<CodeGroup>
  ```java Java theme={null}
  new Lambda("1")
  	.raceWith(
  		new Lambda("2")
  		/*, varag commands*/
  	);
  ```

  ```kt Kotlin theme={null}
  Lambda("1")
  	.raceWith(
  		Lambda("2"),
  		/*varag commands*/
  	)
  ```
</CodeGroup>

A command can be chained into a `Race` as the deadline via the
`Command.asDeadline()` method, this code snippet is the same as above:

<CodeGroup>
  ```java Java theme={null}
  new Lambda("deadline")
  	.asDeadline(
  		new Lambda("1"),
  		new Lambda("2")
  		/*, varag commands*/
  	);
  ```

  ```kt Kotlin theme={null}
  Lambda("deadline")
  	.asDeadline(
  		Lambda("1"),
  		Lambda("2"),
  		/*varag commands*/
  	)
  ```
</CodeGroup>

# Wait

Wait waits its argument in seconds. This example waits 1 second:

<CodeGroup>
  ```java Java theme={null}
  new Wait(1.0);
  ```

  ```kt Kotlin theme={null}
  Wait(1.0)
  ```
</CodeGroup>

The s-expression representation of this command is:

```
(wait 1.0)
```

A command can be chained into a `Race` with a `Wait` as the deadline via the
`Command.timeout(duration)` method, these two are equivalent:

<CodeGroup>
  ```java Java theme={null}
  new Lambda("1").timeout(1.0);

  new Race(new Wait(1.0), new Lambda("1"));
  ```

  ```kt Kotlin theme={null}
  Lambda("1").timeout(1.0)

  Race(Wait(1.0), Lambda("1"))
  ```
</CodeGroup>

# 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`.

<CodeGroup>
  ```java Java theme={null}
  new IfElse(
  	() -> true,
  	new Lambda("1"),
  	new Lambda("2")
  );
  ```

  ```kt Kotlin theme={null}
  IfElse(
  	{ true },
  	Lambda("1"),
  	Lambda("2")
  )
  ```
</CodeGroup>

This example will always run `1`, because it always returns true.

The s-expression representation of this command is:

```
(? true 1 2)
```

# 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:

<CodeGroup>
  ```java Java theme={null}
  enum States {
  	START,
  	MIDDLE,
  	END;
  }
  ```

  ```kt Kotlin theme={null}
  enum class States {
  	START,
  	MIDDLE,
  	END;
  }
  ```
</CodeGroup>

<CodeGroup>
  ```java Java theme={null}
  StateMachine<States> selectionCommand = new StateMachine<>(States.START)
  	// withState is a non-mutating method
  	// it takes a state,
  	// and a function that takes in a RefCell to the state along with an
  	// escaped name that matches the name of the state
  	.withState(States.START, (RefCell<States> state, String name) ->
  		// we can use our own name, or use the name from the lambda to use the name of the state
  		new Lambda("demo")
  			// to change the state, we can enter a new state in the cell
  			// if the new state isn't different, then nothing will happen
  			// but if you set the state to something different, then back to the
  			// previous state, then the current command will be cancelled and restarted
  			.addEnd((interrupted) -> state.accept(States.MIDDLE))
  	)
  	.withState(States.MIDDLE, (state, name) ->
  		new Lambda(name)
  			.addEnd(interrupted -> {
  				if (interrupted) {
  					state.accept(States.END);
  				}
  				else {
  					state.accept(States.START);
  				}
  			})
  	)
  	.withState(States.END, (state, name) -> new Lambda(name));

  // we can also set the state externally
  selectionCommand.setState(States.START);
  ```

  ```kt Kotlin theme={null}
  val selectionCommand: StateMachine<States> = StateMachine(States.START)
  	// withState is a non-mutating method
  	// it takes a state,
  	// and a function that takes in a RefCell to the state along with an
  	// escaped name that matches the name of the state
  	.withState(States.START) { state: RefCell<States>, name: String ->
  		// we can use our own name, or use the name from the lambda to use the name of the state
  		Lambda("demo")
  			// to change the state, we can enter a new state in the cell
  			// if the new state isn't different, then nothing will happen
  			// but if you set the state to something different, then back to the
  			// previous state, then the current command will be cancelled and restarted
  			.addEnd { interrupted ->
  				state.accept(States.MIDDLE)
  			}
  	}
  	.withState(States.MIDDLE) { state: RefCell<States>, name: String ->
  		Lambda(name)
  			.addEnd { interrupted ->
  				if (interrupted) {
  					state.accept(States.END)
  				} else {
  					state.accept(States.START)
  				}
  			}
  	}
  	.withState(States.END) { state: RefCell<States>, name: String ->
  		Lambda(name)
  	}

  // we can also set the state externally
  selectionCommand.state = States.START
  ```
</CodeGroup>

`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:

```
(state-machine START (
	(START demo)
	MIDDLE
	END))
```

`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`.

<CodeGroup>
  ```java Java theme={null}
  Advancing advancing = new Advancing(
  	new Lambda("1"),
  	new Lambda("2")
  	/*, varag commands*/
  );
  ```

  ```kt Kotlin theme={null}
  val advancing = Advancing(
  	Lambda("1"),
  	Lambda("2"),
  	/*varag commands*/
  )
  ```
</CodeGroup>

Advancing wraps around, and can be manually advanced like so:

<CodeGroup>
  ```java Java theme={null}
  advancing.advance();
  ```

  ```kt Kotlin theme={null}
  advancing.advance()
  ```
</CodeGroup>

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:

```
(advancing (
	1
	2))
```
