refactor(engine): select desktop nesting through app-scoped jobs engine
Replace the MainForm/AutoNestForm engine combo bindings and every desktop NestEngineRegistry call: selection now lives in app-scoped EngineSelection addressing jobs engines in NestingEngineRegistry, the combo lists the four built-in strategies (StockLadder stays out per the frozen UI decision), and Engines/ plug-ins load through NestingEngineRegistry.LoadPlugins. Whole-job fill routes through the public PlateFillService with the selected strategy and plate number; interactive group fill (PlateView) and area fill (ActionFillArea) go through PlateFillService with identical accept/cancel preview behavior. Multi-plate and size-search orchestrators receive the explicit strategy. No desktop code reads or writes process-global engine state.
This commit is contained in:
@@ -6,6 +6,8 @@ using System.Threading.Tasks;
|
|||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using OpenNest.Controls;
|
using OpenNest.Controls;
|
||||||
using OpenNest.Engine;
|
using OpenNest.Engine;
|
||||||
|
using OpenNest.Engine.Jobs.Placement;
|
||||||
|
using OpenNest.Forms;
|
||||||
|
|
||||||
namespace OpenNest.Actions
|
namespace OpenNest.Actions
|
||||||
{
|
{
|
||||||
@@ -46,13 +48,15 @@ namespace OpenNest.Actions
|
|||||||
|
|
||||||
private async void FillArea()
|
private async void FillArea()
|
||||||
{
|
{
|
||||||
|
var strategy = EngineSelection.FillStrategy;
|
||||||
if (progress != null && cts != null)
|
if (progress != null && cts != null)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var engine = NestEngineRegistry.Create(plateView.Plate);
|
|
||||||
var parts = await Task.Run(() =>
|
var parts = await Task.Run(() =>
|
||||||
engine.Fill(
|
PlateFillService.FillItem(
|
||||||
|
strategy,
|
||||||
|
plateView.Plate,
|
||||||
new NestItem { Drawing = drawing },
|
new NestItem { Drawing = drawing },
|
||||||
SelectedArea,
|
SelectedArea,
|
||||||
progress,
|
progress,
|
||||||
@@ -69,8 +73,15 @@ namespace OpenNest.Actions
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var engine = NestEngineRegistry.Create(plateView.Plate);
|
var parts = PlateFillService.FillItem(
|
||||||
engine.Fill(new NestItem { Drawing = drawing }, SelectedArea);
|
strategy,
|
||||||
|
plateView.Plate,
|
||||||
|
new NestItem { Drawing = drawing },
|
||||||
|
SelectedArea,
|
||||||
|
null,
|
||||||
|
CancellationToken.None
|
||||||
|
);
|
||||||
|
plateView.Plate.Parts.AddRange(parts);
|
||||||
plateView.Invalidate();
|
plateView.Invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ using OpenNest.Geometry;
|
|||||||
using OpenNest.Math;
|
using OpenNest.Math;
|
||||||
using Timer = System.Timers.Timer;
|
using Timer = System.Timers.Timer;
|
||||||
using OpenNest.Engine;
|
using OpenNest.Engine;
|
||||||
|
using OpenNest.Engine.Jobs.Placement;
|
||||||
|
|
||||||
namespace OpenNest.Controls
|
namespace OpenNest.Controls
|
||||||
{
|
{
|
||||||
@@ -602,11 +603,18 @@ namespace OpenNest.Controls
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var engine = NestEngineRegistry.Create(Plate);
|
var strategy = EngineSelection.FillStrategy;
|
||||||
var spacing = Plate.PartSpacing;
|
var spacing = Plate.PartSpacing;
|
||||||
var parts = await Task.Run(() =>
|
var parts = await Task.Run(() =>
|
||||||
{
|
{
|
||||||
var result = engine.Fill(groupParts, workArea, progress, cts.Token);
|
var result = PlateFillService.FillGroup(
|
||||||
|
strategy,
|
||||||
|
Plate,
|
||||||
|
groupParts,
|
||||||
|
workArea,
|
||||||
|
progress,
|
||||||
|
cts.Token
|
||||||
|
);
|
||||||
Compactor.Settle(result, workArea, spacing);
|
Compactor.Settle(result, workArea, spacing);
|
||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -87,9 +87,9 @@ namespace OpenNest.Forms
|
|||||||
|
|
||||||
private void LoadEngines()
|
private void LoadEngines()
|
||||||
{
|
{
|
||||||
foreach (var engine in NestEngineRegistry.AvailableEngines)
|
foreach (var name in EngineSelection.UiEngineNames)
|
||||||
engineComboBox.Items.Add(engine.Name);
|
engineComboBox.Items.Add(name);
|
||||||
engineComboBox.SelectedItem = NestEngineRegistry.ActiveEngineName;
|
engineComboBox.SelectedItem = EngineSelection.EngineName;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetupPartsGrid()
|
private void SetupPartsGrid()
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using OpenNest.Engine.Jobs;
|
||||||
|
using OpenNest.Engine.Jobs.Placement;
|
||||||
|
|
||||||
|
namespace OpenNest.Forms
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// App-scoped nesting-engine selection — the desktop replacement for the process-global
|
||||||
|
/// NestEngineRegistry.ActiveEngineName. The selected name addresses a whole-job
|
||||||
|
/// INestingEngine resolved through NestingEngineRegistry at call time; single-plate
|
||||||
|
/// interactive fill uses FillStrategy, which maps a built-in engine to its placement
|
||||||
|
/// strategy and falls back to Default for jobs-only engines (StockLadder, plug-ins).
|
||||||
|
/// </summary>
|
||||||
|
public static class EngineSelection
|
||||||
|
{
|
||||||
|
public const string DefaultEngineName = "Default";
|
||||||
|
|
||||||
|
/// <summary>Registered jobs engine deliberately kept out of the desktop combo.</summary>
|
||||||
|
public const string HiddenEngineName = "StockLadder";
|
||||||
|
|
||||||
|
private static string engineName = DefaultEngineName;
|
||||||
|
|
||||||
|
public static string EngineName
|
||||||
|
{
|
||||||
|
get { return engineName; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
engineName = string.IsNullOrWhiteSpace(value)
|
||||||
|
? DefaultEngineName
|
||||||
|
: value.Trim();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Desktop combo contents: registered jobs engines minus StockLadder.</summary>
|
||||||
|
public static IEnumerable<string> UiEngineNames =>
|
||||||
|
NestingEngineRegistry.AvailableEngines
|
||||||
|
.Where(e => !e.Name.Equals(HiddenEngineName, StringComparison.OrdinalIgnoreCase))
|
||||||
|
.Select(e => e.Name)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
/// <summary>Placement strategy for single-plate fill: the selection when it names a
|
||||||
|
/// built-in strategy, otherwise Default.</summary>
|
||||||
|
public static string FillStrategy => IsFillStrategy(engineName) ? engineName : DefaultEngineName;
|
||||||
|
|
||||||
|
public static bool IsFillStrategy(string name) =>
|
||||||
|
!string.IsNullOrWhiteSpace(name)
|
||||||
|
&& PlateFillService.BuiltInStrategies.Any(
|
||||||
|
s => s.Equals(name.Trim(), StringComparison.OrdinalIgnoreCase)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
+28
-11
@@ -17,6 +17,9 @@ using OpenNest.Gpu;
|
|||||||
using OpenNest.IO;
|
using OpenNest.IO;
|
||||||
using OpenNest.Properties;
|
using OpenNest.Properties;
|
||||||
using OpenNest.Engine;
|
using OpenNest.Engine;
|
||||||
|
using OpenNest.Engine.Jobs;
|
||||||
|
using OpenNest.Engine.Jobs.Adapters;
|
||||||
|
using OpenNest.Engine.Jobs.Placement;
|
||||||
|
|
||||||
namespace OpenNest.Forms
|
namespace OpenNest.Forms
|
||||||
{
|
{
|
||||||
@@ -68,16 +71,19 @@ namespace OpenNest.Forms
|
|||||||
//if (GpuEvaluatorFactory.GpuAvailable)
|
//if (GpuEvaluatorFactory.GpuAvailable)
|
||||||
// BestFitCache.CreateSlideComputer = () => GpuEvaluatorFactory.CreateSlideComputer();
|
// BestFitCache.CreateSlideComputer = () => GpuEvaluatorFactory.CreateSlideComputer();
|
||||||
|
|
||||||
|
// Jobs-side plug-in discovery: INestingEngine implementations are registered per
|
||||||
|
// assembly/type with the same per-DLL isolation as before. Binary plug-ins derived
|
||||||
|
// from the legacy NestEngineBase no longer load here after the Phase-4 removal.
|
||||||
var enginesDir = Path.Combine(Application.StartupPath, "Engines");
|
var enginesDir = Path.Combine(Application.StartupPath, "Engines");
|
||||||
NestEngineRegistry.LoadPlugins(enginesDir);
|
NestingEngineRegistry.LoadPlugins(enginesDir);
|
||||||
|
|
||||||
OptionsForm.ApplyDisabledStrategies();
|
OptionsForm.ApplyDisabledStrategies();
|
||||||
ColorSchemeRegistry.ApplyActiveFromSettings();
|
ColorSchemeRegistry.ApplyActiveFromSettings();
|
||||||
|
|
||||||
foreach (var engine in NestEngineRegistry.AvailableEngines)
|
foreach (var name in EngineSelection.UiEngineNames)
|
||||||
engineComboBox.Items.Add(engine.Name);
|
engineComboBox.Items.Add(name);
|
||||||
|
|
||||||
engineComboBox.SelectedItem = NestEngineRegistry.ActiveEngineName;
|
engineComboBox.SelectedItem = EngineSelection.EngineName;
|
||||||
engineComboBox.SelectedIndexChanged += EngineComboBox_SelectedIndexChanged;
|
engineComboBox.SelectedIndexChanged += EngineComboBox_SelectedIndexChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -334,7 +340,7 @@ namespace OpenNest.Forms
|
|||||||
private void EngineComboBox_SelectedIndexChanged(object sender, EventArgs e)
|
private void EngineComboBox_SelectedIndexChanged(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if (engineComboBox.SelectedItem is string name)
|
if (engineComboBox.SelectedItem is string name)
|
||||||
NestEngineRegistry.ActiveEngineName = name;
|
EngineSelection.EngineName = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateLocationMode()
|
private void UpdateLocationMode()
|
||||||
@@ -1009,7 +1015,7 @@ namespace OpenNest.Forms
|
|||||||
|
|
||||||
if (form.EngineName != null)
|
if (form.EngineName != null)
|
||||||
{
|
{
|
||||||
NestEngineRegistry.ActiveEngineName = form.EngineName;
|
EngineSelection.EngineName = form.EngineName;
|
||||||
engineComboBox.SelectedItem = form.EngineName;
|
engineComboBox.SelectedItem = form.EngineName;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1118,6 +1124,7 @@ namespace OpenNest.Forms
|
|||||||
SortOrder = sortOrder,
|
SortOrder = sortOrder,
|
||||||
MinRemnantSize = minRemnantSize,
|
MinRemnantSize = minRemnantSize,
|
||||||
AllowPlateCreation = allowPlateCreation,
|
AllowPlateCreation = allowPlateCreation,
|
||||||
|
Strategy = EngineSelection.FillStrategy,
|
||||||
};
|
};
|
||||||
|
|
||||||
var result = await Task.Run(() =>
|
var result = await Task.Run(() =>
|
||||||
@@ -1199,7 +1206,8 @@ namespace OpenNest.Forms
|
|||||||
salvageRate,
|
salvageRate,
|
||||||
plate,
|
plate,
|
||||||
progress,
|
progress,
|
||||||
token
|
token,
|
||||||
|
EngineSelection.FillStrategy
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -1223,10 +1231,19 @@ namespace OpenNest.Forms
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var engine = NestEngineRegistry.Create(plate);
|
// Same preview flow as before: fill the current plate's remaining demand with the
|
||||||
engine.PlateNumber = plateIndex;
|
// selected strategy, then commit the returned parts. App-scoped selection — the
|
||||||
|
// process-global engine registry is never consulted.
|
||||||
nestParts = await Task.Run(() => engine.Nest(items, progress, token));
|
nestParts = await Task.Run(() =>
|
||||||
|
PlateFillService.Nest(
|
||||||
|
EngineSelection.FillStrategy,
|
||||||
|
plate,
|
||||||
|
items,
|
||||||
|
plateIndex,
|
||||||
|
progress,
|
||||||
|
token
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
activeForm.PlateView.ClearPreviewParts();
|
activeForm.PlateView.ClearPreviewParts();
|
||||||
|
|||||||
Reference in New Issue
Block a user