using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace MultiWheelC.TrajectoryPlanning.CoarsePath;
///
/// 一次粗路径规划的最终不可变结果。
/// 只有 为 时才携带非空路径与方向分段;其他状态始终返回空只读集合。
///
public sealed class PlanningResult
{
private static readonly IReadOnlyList EmptyPath = new ReadOnlyCollection(new List());
private static readonly IReadOnlyList EmptySegments = new ReadOnlyCollection(new List());
private PlanningResult(PlanningStatus status, PlanningDiagnostics diagnostics, IReadOnlyList path, IReadOnlyList segments)
{
Status = status;
Diagnostics = diagnostics ?? new PlanningDiagnostics(terminationReason: "未提供诊断信息。");
Path = path;
Segments = segments;
}
/// 规划最终状态;只有 可以发布路径。
public PlanningStatus Status { get; }
/// 节点、耗时、路径长度、净空和终止原因统计;始终非空。
public PlanningDiagnostics Diagnostics { get; }
/// 成功时的稠密粗路径;失败时为不可修改的空集合。
public IReadOnlyList Path { get; }
/// 成功时覆盖 的包含式方向分段;失败时为不可修改的空集合。
public IReadOnlyList Segments { get; }
///
/// 创建成功结果。
/// 参数:path 与 segments 必须均为非空;diagnostics 为本次规划的统计快照。参数不符合要求时抛出 ,防止以成功状态发布不完整路径。
///
public static PlanningResult Success(IReadOnlyList path, IReadOnlyList segments, PlanningDiagnostics diagnostics)
{
if (path == null || path.Count == 0)
throw new ArgumentException("Successful planning results require a non-empty path.", nameof(path));
if (segments == null || segments.Count == 0)
throw new ArgumentException("Successful planning results require non-empty segments.", nameof(segments));
return new PlanningResult(PlanningStatus.Success, diagnostics, CopyReadOnly(path), CopyReadOnly(segments));
}
///
/// 创建失败、取消或资源受限结果。
/// 参数:status 不能为 ;diagnostics 会原样保留。返回结果的路径与分段始终为空只读集合。
///
public static PlanningResult Failure(PlanningStatus status, PlanningDiagnostics diagnostics)
{
if (status == PlanningStatus.Success)
throw new ArgumentException("Use Success to create a successful planning result.", nameof(status));
return new PlanningResult(status, diagnostics, EmptyPath, EmptySegments);
}
private static IReadOnlyList CopyReadOnly(IReadOnlyList source)
{
var copy = new List(source.Count);
for (int index = 0; index < source.Count; index++)
copy.Add(source[index]);
return new ReadOnlyCollection(copy);
}
}