feat: add Disable/Enable API to FillStrategyRegistry

Adds methods to permanently disable/enable strategies by name. Disabled
strategies remain registered but are excluded from the default pipeline.
SetEnabled (used for remnant fills) takes precedence over the disabled
set, so explicit overrides still work.

Pipeline test now checks against active strategy count dynamically.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-21 15:19:27 -04:00
parent 00e7866506
commit 93a8981d0a
2 changed files with 34 additions and 5 deletions
@@ -12,6 +12,7 @@ namespace OpenNest.Engine.Strategies
private static readonly List<IFillStrategy> strategies = new(); private static readonly List<IFillStrategy> strategies = new();
private static List<IFillStrategy> sorted; private static List<IFillStrategy> sorted;
private static HashSet<string> enabledFilter; private static HashSet<string> enabledFilter;
private static readonly HashSet<string> disabled = new(StringComparer.OrdinalIgnoreCase);
static FillStrategyRegistry() static FillStrategyRegistry()
{ {
@@ -19,9 +20,36 @@ namespace OpenNest.Engine.Strategies
} }
public static IReadOnlyList<IFillStrategy> Strategies => public static IReadOnlyList<IFillStrategy> Strategies =>
sorted ??= (enabledFilter != null sorted ??= FilterStrategies();
? strategies.Where(s => enabledFilter.Contains(s.Name)).OrderBy(s => s.Order).ToList()
: strategies.OrderBy(s => s.Order).ToList()); private static List<IFillStrategy> FilterStrategies()
{
var source = enabledFilter != null
? strategies.Where(s => enabledFilter.Contains(s.Name))
: strategies.Where(s => !disabled.Contains(s.Name));
return source.OrderBy(s => s.Order).ToList();
}
/// <summary>
/// Permanently disables strategies by name. They remain registered
/// but are excluded from the default pipeline.
/// </summary>
public static void Disable(params string[] names)
{
foreach (var name in names)
disabled.Add(name);
sorted = null;
}
/// <summary>
/// Re-enables a previously disabled strategy.
/// </summary>
public static void Enable(params string[] names)
{
foreach (var name in names)
disabled.Remove(name);
sorted = null;
}
/// <summary> /// <summary>
/// Restricts the active strategies to only those whose names are listed. /// Restricts the active strategies to only those whose names are listed.
@@ -1,3 +1,4 @@
using OpenNest.Engine.Strategies;
using OpenNest.Geometry; using OpenNest.Geometry;
namespace OpenNest.Tests.Strategies; namespace OpenNest.Tests.Strategies;
@@ -24,8 +25,8 @@ public class FillPipelineTests
engine.Fill(item, plate.WorkArea(), null, System.Threading.CancellationToken.None); engine.Fill(item, plate.WorkArea(), null, System.Threading.CancellationToken.None);
Assert.True(engine.PhaseResults.Count >= 6, Assert.True(engine.PhaseResults.Count >= FillStrategyRegistry.Strategies.Count,
$"Expected phase results from all strategies, got {engine.PhaseResults.Count}"); $"Expected phase results from all active strategies, got {engine.PhaseResults.Count}");
} }
[Fact] [Fact]