novolis-commands / getting-started.md
Getting started
Interrupt-aware command queues
dotnetcommandsnovolis
Install
dotnet add package Novolis.Commands.Abstractions --version 1.0.0
dotnet add package Novolis.Commands.Engine --version 1.0.0
dotnet add package Novolis.Commands.Queueing --version 1.0.0
dotnet add package Novolis.Commands.DependencyInjection --version 1.0.0Register commands
services.AddSingleton<ICommandContextResolver<MyContext>, MyContextResolver>();
services.AddNovolisCommands<MyContext>(
registry =>
{
registry.Add("helm.set-speed", "helm", ["warp"],
CommandArgumentDefinition.Integer("warp", required: true));
registry.Add("helm.set-heading", "helm", ["heading", "set course"], "heading3d");
},
configureEngine: options =>
{
options.ArgumentParsers.Register("heading3d", new MyHeadingArgumentParser());
});
services.AddSingleton<ICommandProcessor<MyContext>, MyProcessor>();
services.AddNovolisCommandRunner<MyContext>();Implement ICommandContextResolver<TContext> with context aliases (e.g. pilot → helm). Orders must start with a station prefix or alias.
Custom argument parser (3D heading example)
public sealed class MyHeadingArgumentParser : ICommandArgumentParser
{
public bool TryParse(
CommandDefinition definition,
IReadOnlyList<string> argumentTokens,
out IReadOnlyDictionary<string, object?> arguments,
out ParseFailure? failure)
{
// Parse MARK/BY, comma decimals, etc.
}
}Parse and enqueue
var result = await engine.ParseCommandAsync("helm heading 270", context);
if (result.Success)
await queue.EnqueueAsync(result.Command!);
else if (result.Suggestions.Count > 0)
// show result.Suggestions to the playerRun the queue
var runner = sp.GetRequiredService<CommandQueueRunner<MyContext>>();
await runner.RunAsync(context, cancellationToken);See design.md for parse vs processor boundaries and migration-v02-to-v10.md when upgrading from preview.