From 5936272ce460ddf89f813a34abd3b557238fb7ba Mon Sep 17 00:00:00 2001 From: AJ Isaacs Date: Mon, 23 Mar 2026 00:08:31 -0400 Subject: [PATCH] refactor: move ProgramVariableManager to Core, add config file support - Move ProgramVariable and ProgramVariableManager from OpenNest.Posts.Cincinnati to OpenNest.Core/CNC (namespace OpenNest.CNC) so they can be used internally in nest programs - Add parameterless constructor to CincinnatiPostProcessor that loads config from a .json file next to the DLL (creates defaults on first run) - Enums serialize as readable strings (e.g., "Inches", "ControllerSide") - Config file: OpenNest.Posts.Cincinnati.json in the Posts/ directory Co-Authored-By: Claude Opus 4.6 (1M context) --- .../CNC}/ProgramVariable.cs | 2 +- .../CNC}/ProgramVariableManager.cs | 2 +- .../CincinnatiPostProcessor.cs | 40 +++++++++++++++++ .../CincinnatiPreambleWriter.cs | 1 + .../CincinnatiPostProcessorTests.cs | 43 +++++++++++++++++++ .../CincinnatiPreambleWriterTests.cs | 1 + .../Cincinnati/ProgramVariableManagerTests.cs | 2 +- 7 files changed, 88 insertions(+), 3 deletions(-) rename {OpenNest.Posts.Cincinnati => OpenNest.Core/CNC}/ProgramVariable.cs (92%) rename {OpenNest.Posts.Cincinnati => OpenNest.Core/CNC}/ProgramVariableManager.cs (97%) diff --git a/OpenNest.Posts.Cincinnati/ProgramVariable.cs b/OpenNest.Core/CNC/ProgramVariable.cs similarity index 92% rename from OpenNest.Posts.Cincinnati/ProgramVariable.cs rename to OpenNest.Core/CNC/ProgramVariable.cs index d92fe5c..ca9c79c 100644 --- a/OpenNest.Posts.Cincinnati/ProgramVariable.cs +++ b/OpenNest.Core/CNC/ProgramVariable.cs @@ -1,4 +1,4 @@ -namespace OpenNest.Posts.Cincinnati +namespace OpenNest.CNC { public sealed class ProgramVariable { diff --git a/OpenNest.Posts.Cincinnati/ProgramVariableManager.cs b/OpenNest.Core/CNC/ProgramVariableManager.cs similarity index 97% rename from OpenNest.Posts.Cincinnati/ProgramVariableManager.cs rename to OpenNest.Core/CNC/ProgramVariableManager.cs index 4dfe0b0..b3d57fb 100644 --- a/OpenNest.Posts.Cincinnati/ProgramVariableManager.cs +++ b/OpenNest.Core/CNC/ProgramVariableManager.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; -namespace OpenNest.Posts.Cincinnati +namespace OpenNest.CNC { public sealed class ProgramVariableManager { diff --git a/OpenNest.Posts.Cincinnati/CincinnatiPostProcessor.cs b/OpenNest.Posts.Cincinnati/CincinnatiPostProcessor.cs index d5e6a82..1f990d7 100644 --- a/OpenNest.Posts.Cincinnati/CincinnatiPostProcessor.cs +++ b/OpenNest.Posts.Cincinnati/CincinnatiPostProcessor.cs @@ -1,23 +1,63 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Reflection; using System.Text; +using System.Text.Json; +using System.Text.Json.Serialization; +using OpenNest.CNC; namespace OpenNest.Posts.Cincinnati { public sealed class CincinnatiPostProcessor : IPostProcessor { + private static readonly JsonSerializerOptions JsonOptions = new() + { + WriteIndented = true, + Converters = { new JsonStringEnumConverter() } + }; + public string Name => "Cincinnati CL-707"; public string Author => "OpenNest"; public string Description => "Cincinnati CL-707/CL-800/CL-900/CL-940/CLX family"; public CincinnatiPostConfig Config { get; } + public CincinnatiPostProcessor() + { + var configPath = GetConfigPath(); + if (File.Exists(configPath)) + { + var json = File.ReadAllText(configPath); + Config = JsonSerializer.Deserialize(json, JsonOptions); + } + else + { + Config = new CincinnatiPostConfig(); + SaveConfig(); + } + } + public CincinnatiPostProcessor(CincinnatiPostConfig config) { Config = config; } + public void SaveConfig() + { + var configPath = GetConfigPath(); + var json = JsonSerializer.Serialize(Config, JsonOptions); + File.WriteAllText(configPath, json); + } + + private static string GetConfigPath() + { + var assemblyPath = typeof(CincinnatiPostProcessor).Assembly.Location; + var dir = Path.GetDirectoryName(assemblyPath); + var name = Path.GetFileNameWithoutExtension(assemblyPath); + return Path.Combine(dir, name + ".json"); + } + public void Post(Nest nest, Stream outputStream) { // 1. Create variable manager and register standard variables diff --git a/OpenNest.Posts.Cincinnati/CincinnatiPreambleWriter.cs b/OpenNest.Posts.Cincinnati/CincinnatiPreambleWriter.cs index edd973b..0e32ccd 100644 --- a/OpenNest.Posts.Cincinnati/CincinnatiPreambleWriter.cs +++ b/OpenNest.Posts.Cincinnati/CincinnatiPreambleWriter.cs @@ -1,6 +1,7 @@ using System; using System.IO; using OpenNest; +using OpenNest.CNC; namespace OpenNest.Posts.Cincinnati; diff --git a/OpenNest.Tests/Cincinnati/CincinnatiPostProcessorTests.cs b/OpenNest.Tests/Cincinnati/CincinnatiPostProcessorTests.cs index 1bf8100..ee5efe5 100644 --- a/OpenNest.Tests/Cincinnati/CincinnatiPostProcessorTests.cs +++ b/OpenNest.Tests/Cincinnati/CincinnatiPostProcessorTests.cs @@ -1,5 +1,7 @@ using System.IO; using System.Text; +using System.Text.Json; +using System.Text.Json.Serialization; using OpenNest.CNC; using OpenNest.Geometry; using OpenNest.Posts.Cincinnati; @@ -96,6 +98,47 @@ public class CincinnatiPostProcessorTests } } + [Fact] + public void Config_RoundTripsAsJson() + { + var config = new CincinnatiPostConfig + { + ConfigurationName = "CL940_CORONA", + DefaultLibraryFile = "MS135N2PANEL.lib", + PostedUnits = Units.Inches, + KerfCompensation = KerfMode.ControllerSide, + UseAntiDive = true + }; + + var opts = new JsonSerializerOptions + { + WriteIndented = true, + Converters = { new JsonStringEnumConverter() } + }; + var json = JsonSerializer.Serialize(config, opts); + var deserialized = JsonSerializer.Deserialize(json, opts); + + Assert.Equal("CL940_CORONA", deserialized.ConfigurationName); + Assert.Equal("MS135N2PANEL.lib", deserialized.DefaultLibraryFile); + Assert.Equal(Units.Inches, deserialized.PostedUnits); + Assert.Equal(KerfMode.ControllerSide, deserialized.KerfCompensation); + Assert.True(deserialized.UseAntiDive); + + // Enums serialize as strings + Assert.Contains("\"Inches\"", json); + Assert.Contains("\"ControllerSide\"", json); + } + + [Fact] + public void ParameterlessConstructor_LoadsOrCreatesConfig() + { + // The parameterless constructor reads from a .json file next to the assembly, + // or creates defaults if none exists. Either way, Config should be non-null. + var post = new CincinnatiPostProcessor(); + Assert.NotNull(post.Config); + Assert.Equal("CL940", post.Config.ConfigurationName); + } + private static Nest CreateTestNest() { var nest = new Nest("TestNest"); diff --git a/OpenNest.Tests/Cincinnati/CincinnatiPreambleWriterTests.cs b/OpenNest.Tests/Cincinnati/CincinnatiPreambleWriterTests.cs index 7481913..3486b2b 100644 --- a/OpenNest.Tests/Cincinnati/CincinnatiPreambleWriterTests.cs +++ b/OpenNest.Tests/Cincinnati/CincinnatiPreambleWriterTests.cs @@ -1,5 +1,6 @@ using System.IO; using System.Text; +using OpenNest.CNC; using OpenNest.Posts.Cincinnati; namespace OpenNest.Tests.Cincinnati; diff --git a/OpenNest.Tests/Cincinnati/ProgramVariableManagerTests.cs b/OpenNest.Tests/Cincinnati/ProgramVariableManagerTests.cs index 33b35d7..cd3c538 100644 --- a/OpenNest.Tests/Cincinnati/ProgramVariableManagerTests.cs +++ b/OpenNest.Tests/Cincinnati/ProgramVariableManagerTests.cs @@ -1,4 +1,4 @@ -using OpenNest.Posts.Cincinnati; +using OpenNest.CNC; namespace OpenNest.Tests.Cincinnati;