Files
OpenNest/OpenNest.Engine/Strategies/PairsFillStrategy.cs
AJ Isaacs ef15421915 refactor: standardize fill strategy progress reporting via FillContext
Strategies and fillers previously called NestEngineBase.ReportProgress
directly, each constructing ProgressReport structs with phase, plate
number, and work area manually. Some strategies (RectBestFit) reported
nothing at all. This made progress updates inconsistent and flakey.

Add FillContext.ReportProgress(parts, description) as the single
standard method for intermediate progress. RunPipeline sets ActivePhase
before each strategy, and the context handles common fields. Lower-level
fillers (PairFiller, FillExtents, StripeFiller) now accept an
Action<List<Part>, string> callback instead of raw IProgress, removing
their coupling to NestEngineBase and ProgressReport.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 23:21:48 -04:00

46 lines
1.4 KiB
C#

using OpenNest.Engine.Fill;
using System.Collections.Generic;
using System.Threading;
namespace OpenNest.Engine.Strategies
{
public class PairsFillStrategy : IFillStrategy
{
private static readonly AsyncLocal<bool> active = new();
public string Name => "Pairs";
public NestPhase Phase => NestPhase.Pairs;
public int Order => 100;
public List<Part> Fill(FillContext context)
{
// Prevent recursive PairFiller — remnant fills within PairFiller
// create a new engine that runs the full pipeline, which would
// invoke PairsFillStrategy again, causing deep recursion.
if (active.Value)
return null;
if (context.PartType == PartType.Circle)
return null;
active.Value = true;
try
{
var comparer = context.Policy?.Comparer;
var dedup = GridDedup.GetOrCreate(context.SharedState);
var filler = new PairFiller(context.Plate, comparer, dedup);
var result = filler.Fill(context.Item, context.WorkArea,
context.Token, context.ReportProgress);
context.SharedState["BestFits"] = result.BestFits;
return result.Parts;
}
finally
{
active.Value = false;
}
}
}
}