diff --git a/OpenNest.Engine/AccumulatingProgress.cs b/OpenNest.Engine/AccumulatingProgress.cs new file mode 100644 index 0000000..7b84803 --- /dev/null +++ b/OpenNest.Engine/AccumulatingProgress.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; + +namespace OpenNest +{ + /// + /// Wraps an IProgress to prepend previously placed parts to each report, + /// so the UI shows the full picture during incremental fills. + /// + internal class AccumulatingProgress : IProgress + { + private readonly IProgress inner; + private readonly List previousParts; + + public AccumulatingProgress(IProgress inner, List previousParts) + { + this.inner = inner; + this.previousParts = previousParts; + } + + public void Report(NestProgress value) + { + if (value.BestParts != null && previousParts.Count > 0) + { + var combined = new List(previousParts.Count + value.BestParts.Count); + combined.AddRange(previousParts); + combined.AddRange(value.BestParts); + value.BestParts = combined; + value.BestPartCount = combined.Count; + } + + inner.Report(value); + } + } +} diff --git a/OpenNest.Tests/AccumulatingProgressTests.cs b/OpenNest.Tests/AccumulatingProgressTests.cs new file mode 100644 index 0000000..2df42c5 --- /dev/null +++ b/OpenNest.Tests/AccumulatingProgressTests.cs @@ -0,0 +1,51 @@ +namespace OpenNest.Tests; + +public class AccumulatingProgressTests +{ + private class CapturingProgress : IProgress + { + public NestProgress Last { get; private set; } + public void Report(NestProgress value) => Last = value; + } + + [Fact] + public void Report_PrependsPreviousParts() + { + var inner = new CapturingProgress(); + var previous = new List { TestHelpers.MakePartAt(0, 0, 10) }; + var accumulating = new AccumulatingProgress(inner, previous); + + var newParts = new List { TestHelpers.MakePartAt(20, 0, 10) }; + accumulating.Report(new NestProgress { BestParts = newParts, BestPartCount = 1 }); + + Assert.NotNull(inner.Last); + Assert.Equal(2, inner.Last.BestParts.Count); + Assert.Equal(2, inner.Last.BestPartCount); + } + + [Fact] + public void Report_NoPreviousParts_PassesThrough() + { + var inner = new CapturingProgress(); + var accumulating = new AccumulatingProgress(inner, new List()); + + var newParts = new List { TestHelpers.MakePartAt(0, 0, 10) }; + accumulating.Report(new NestProgress { BestParts = newParts, BestPartCount = 1 }); + + Assert.NotNull(inner.Last); + Assert.Single(inner.Last.BestParts); + } + + [Fact] + public void Report_NullBestParts_PassesThrough() + { + var inner = new CapturingProgress(); + var previous = new List { TestHelpers.MakePartAt(0, 0, 10) }; + var accumulating = new AccumulatingProgress(inner, previous); + + accumulating.Report(new NestProgress { BestParts = null }); + + Assert.NotNull(inner.Last); + Assert.Null(inner.Last.BestParts); + } +}