VitalRouter provides the CommandOrdering enum to control how asynchronous handlers behave when multiple commands are published. This is critical for managing concurrency, such as ensuring dialogue or cutscenes play in a specific order without overlapping.
Available Ordering Modes
| Ordering | Behavior | Typical Use Case |
|---|
Parallel (default) | Run all handlers concurrently. | Independent reactions (e.g., multiple UI elements reacting to one event). |
Sequential | Queue commands and run them one at a time in the order they were received. | Dialogue, cutscenes, tutorials. |
Drop | Ignore new incoming commands while a handler is currently running. | Debouncing buttons or preventing double-firing of actions. |
Switch | Cancel the currently running handler and immediately start the new one. | "Latest wins" scenarios like re-targeting or search-as-you-type. |
Implementation Example: Sequential Cutscenes
To ensure a sequence of commands (like walking, speaking, and waiting) executes in order, apply CommandOrdering.Sequential to the presenter class using the [Routes] attribute.
public readonly record struct WalkCommand(Vector3 To) : ICommand;
public readonly record struct SpeakCommand(string Text) : ICommand;
public readonly record struct WaitCommand(float Seconds) : ICommand;
// `Sequential`: each command waits for the previous handler to finish.
[Routes(CommandOrdering.Sequential)]
public partial class CutscenePresenter : MonoBehaviour
{
[Route]
async UniTask On(WalkCommand cmd) => await character.WalkToAsync(cmd.To);
[Route]
async UniTask On(SpeakCommand cmd) => await dialogueView.ShowAsync(cmd.Text);
[Route]
async UniTask On(WaitCommand cmd) => await UniTask.Delay(TimeSpan.FromSeconds(cmd.Seconds));
}
// Usage:
router.PublishAsync(new WalkCommand(stage.Center));
router.PublishAsync(new SpeakCommand("Hello there!"));
router.PublishAsync(new WaitCommand(0.5f));
router.PublishAsync(new SpeakCommand("Welcome to our little town."));