using System; using System.Collections.Generic; using System.Collections.ObjectModel; namespace MultiWheelC.TrajectoryPlanning.PathSmoothing.Output.Comparison; /// Immutable raw-baseline or Local G2 report entry. public sealed class PathSmoothingComparisonEntry { public PathSmoothingComparisonEntry( SmoothingMethod method, PathSmoothingStatus status, PathQualityMetrics metrics, SmoothingTimingSummary timing, string stableGeometryDigest, string diagnostic) : this(method, false, status, metrics, timing, stableGeometryDigest, diagnostic, Empty(), Empty()) { } private PathSmoothingComparisonEntry( SmoothingMethod? method, bool isRawPathBaseline, PathSmoothingStatus status, PathQualityMetrics metrics, SmoothingTimingSummary timing, string stableGeometryDigest, string diagnostic, IReadOnlyList path, IReadOnlyList segments) { Method = method; IsRawPathBaseline = isRawPathBaseline; Status = status; Metrics = metrics ?? new PathQualityMetrics(); Timing = timing ?? new SmoothingTimingSummary(new double[] { 0d, 0d, 0d, 0d, 0d }, false, "No timing result was supplied."); StableGeometryDigest = stableGeometryDigest ?? string.Empty; Diagnostic = diagnostic ?? string.Empty; Path = CopyReadOnly(path); Segments = CopyReadOnly(segments); } public SmoothingMethod? Method { get; } public bool IsRawPathBaseline { get; } public PathSmoothingStatus Status { get; } public PathQualityMetrics Metrics { get; } public SmoothingTimingSummary Timing { get; } public string StableGeometryDigest { get; } public string Diagnostic { get; } public IReadOnlyList Path { get; } public IReadOnlyList Segments { get; } public bool IsEligibleForRecommendation => !IsRawPathBaseline && IsPublishedLocalG2Status(Status) && Metrics.IsFeasible && Timing.IsDeterministic; internal static bool IsPublishedLocalG2Status(PathSmoothingStatus status) { return status == PathSmoothingStatus.Complete || status == PathSmoothingStatus.PartialImprovement || status == PathSmoothingStatus.NotNeeded || status == PathSmoothingStatus.Unchanged; } internal static PathSmoothingComparisonEntry CreateCandidate( SmoothingMethod method, PathSmoothingStatus status, PathQualityMetrics metrics, SmoothingTimingSummary timing, string stableGeometryDigest, string diagnostic, IReadOnlyList path, IReadOnlyList segments) { return new PathSmoothingComparisonEntry( method, false, status, metrics, timing, stableGeometryDigest, diagnostic, path, segments); } internal static PathSmoothingComparisonEntry CreateRawPathBaseline( PathSmoothingStatus status, PathQualityMetrics metrics, string stableGeometryDigest, string diagnostic, IReadOnlyList path, IReadOnlyList segments) { return new PathSmoothingComparisonEntry( null, true, status, metrics, new SmoothingTimingSummary(new double[] { 0d, 0d, 0d, 0d, 0d }, true, string.Empty), stableGeometryDigest, diagnostic, path, segments); } private static IReadOnlyList Empty() { return new ReadOnlyCollection(new List()); } private static IReadOnlyList CopyReadOnly(IReadOnlyList source) { var copy = new List(source == null ? 0 : source.Count); if (source != null) { for (int index = 0; index < source.Count; index++) copy.Add(source[index]); } return new ReadOnlyCollection(copy); } }