feat: serialize and deserialize hole sub-programs in nest file format

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-09 14:40:13 -04:00
parent 4aed231611
commit df65414a9d
4 changed files with 178 additions and 4 deletions

View File

@@ -71,10 +71,68 @@ namespace OpenNest.IO
var reader = new ProgramReader(memStream);
programs[i] = reader.Read();
// Read sub-programs if present
var subsEntry = zipArchive.GetEntry($"programs/program-{i}-subs");
if (subsEntry != null)
{
using var subsStream = subsEntry.Open();
ReadSubPrograms(programs[i], subsStream);
}
}
return programs;
}
private static void ReadSubPrograms(Program parent, Stream stream)
{
using var reader = new StreamReader(stream);
var currentId = -1;
var lines = new List<string>();
string line;
while ((line = reader.ReadLine()) != null)
{
var trimmed = line.Trim();
if (trimmed.StartsWith(":") && int.TryParse(trimmed.Substring(1), out var id))
{
// Flush previous sub-program
if (currentId >= 0 && lines.Count > 0)
parent.SubPrograms[currentId] = ParseSubProgram(lines);
currentId = id;
lines.Clear();
}
else if (trimmed == "M99")
{
if (currentId >= 0 && lines.Count > 0)
parent.SubPrograms[currentId] = ParseSubProgram(lines);
currentId = -1;
lines.Clear();
}
else
{
lines.Add(trimmed);
}
}
// Wire up SubProgramCall.Program references
foreach (var code in parent.Codes)
{
if (code is SubProgramCall call && parent.SubPrograms.TryGetValue(call.Id, out var sub))
call.Program = sub;
}
}
private static Program ParseSubProgram(List<string> lines)
{
var text = string.Join("\n", lines);
var memStream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(text));
var reader = new ProgramReader(memStream);
return reader.Read();
}
private Dictionary<int, (List<Entity> entities, HashSet<Guid> suppressed)> ReadEntitySets(int count)
{
var result = new Dictionary<int, (List<Entity>, HashSet<Guid>)>();