Auto: focas-f2b — multi-path/multi-channel CNC

Adds optional `@N` path suffix to FocasAddress (PARAM:1815@2, R100@3.0,
MACRO:500@2, DIAG:280@2/1) with PathId defaulting to 1 for back-compat.
Per-device PathCount is discovered via cnc_rdpathnum at first connect and
cached on DeviceState; reads with PathId>PathCount return BadOutOfRange.
The driver issues cnc_setpath before each non-default-path read and
tracks LastSetPath so repeat reads on the same path skip the wire call.

Closes #264
This commit is contained in:
Joseph Doherty
2026-04-25 19:42:58 -04:00
parent 3b82f4f5fb
commit 2f3eeecd17
7 changed files with 478 additions and 17 deletions

View File

@@ -61,6 +61,25 @@ internal class FakeFocasClient : IFocasClient
public virtual Task<bool> ProbeAsync(CancellationToken ct) => Task.FromResult(ProbeResult);
/// <summary>
/// Configurable path count surfaced via <see cref="GetPathCountAsync"/> — defaults to
/// 1 (single-path controller). Tests asserting multi-path behaviour set this to 2..N
/// so the driver's PathId validation + cnc_setpath dispatch can be exercised
/// without a live CNC (issue #264).
/// </summary>
public int PathCount { get; set; } = 1;
/// <summary>Ordered log of <c>cnc_setpath</c> calls observed on this fake session.</summary>
public List<int> SetPathLog { get; } = new();
public virtual Task<int> GetPathCountAsync(CancellationToken ct) => Task.FromResult(PathCount);
public virtual Task SetPathAsync(int pathId, CancellationToken ct)
{
SetPathLog.Add(pathId);
return Task.CompletedTask;
}
public virtual void Dispose()
{
DisposeCount++;