using System; using System.Collections.Generic; using System.Linq; using OpenNest.Engine; using OpenNest.Engine.Jobs; using OpenNest.Engine.Jobs.Adapters; using OpenNest.Geometry; namespace OpenNest.Forms { /// /// Desktop progress adapter for every whole-job engine. Building, validation and binding /// belong to the shared NestPipeline. /// internal static class JobEngineNest { /// /// Forwards job progress to a NestProgress sink. An engine's optional LegacyProgress detail /// (live preview parts) passes through; otherwise the stage and committed counts become a /// description. Committed counts are authoritative only after PlateCommitted. /// public static IProgress CreateProgress( string engineName, IProgress progress ) => new ProgressAdapter(engineName, progress, null); /// /// As , and also sends each /// best-plan-so-far report's sheets to . /// public static IProgress CreateProgress( string engineName, IProgress progress, IProgress> plans ) => new ProgressAdapter(engineName, progress, plans); public static string Describe(string engineName, NestJobProgress value) => value.Stage switch { NestJobStage.PlateCommitted => $"{engineName}: committed plate {value.CommittedPlates} ({value.CommittedParts} parts placed)", NestJobStage.PlanImproved => $"{engineName}: found a better plan ({value.Plan?.Plates.Count ?? 0} sheets)", _ => $"{engineName}: evaluating plate {WorkingPlate(value)} on stock {value.StockId}", }; /// One-based plate under evaluation; nesters that do not know it report -1. private static int WorkingPlate(NestJobProgress value) => value.PlateIndex >= 0 ? value.PlateIndex + 1 : value.CommittedPlates + 1; private sealed class ProgressAdapter( string engineName, IProgress progress, IProgress> plans ) : IProgress { public void Report(NestJobProgress value) { if (value == null) return; // A plan sink shows plans as sheets; the plate row keeps tracking the search. if (value.Stage == NestJobStage.PlanImproved && plans != null) { if (value.PlanSheets != null) plans.Report(value.PlanSheets); return; } if (value.LegacyProgress != null) { progress.Report(value.LegacyProgress); return; } progress.Report( new NestProgress { Phase = NestPhase.Custom, PlateNumber = value.Stage == NestJobStage.PlateCommitted ? value.CommittedPlates : WorkingPlate(value), Description = Describe(engineName, value), } ); } } } }