namespace CutList.Core.Nesting.Pipeline { /// /// Mutable context passed through the packing pipeline. /// Contains the working state that pipeline steps modify. /// public class PackingContext { /// /// Creates a new packing context from a request. /// public PackingContext(PackingRequest request) { Request = request ?? throw new ArgumentNullException(nameof(request)); RemainingItems = new List(request.Items); Bins = new List(); OversizedItems = new List(); } /// /// The original immutable request. /// public PackingRequest Request { get; } /// /// Items that have not yet been placed in a bin. /// Pipeline steps remove items from this list as they are packed. /// public List RemainingItems { get; } /// /// Items that are too large to fit in any stock bin. /// public List OversizedItems { get; } /// /// The bins that have been created and filled. /// public List Bins { get; } /// /// Convenience property for stock length from the request. /// public double StockLength => Request.StockLength; /// /// Convenience property for spacing from the request. /// public double Spacing => Request.Spacing; /// /// Convenience property for max bin count from the request. /// public int MaxBinCount => Request.MaxBinCount; /// /// Checks if more bins can be added without exceeding the limit. /// public bool CanAddMoreBins() { if (MaxBinCount == -1) return true; return Bins.Count < MaxBinCount; } /// /// Creates a new bin with the stock length and spacing from the request. /// public Bin CreateBin() { return new Bin(StockLength) { Spacing = Spacing }; } /// /// Builds the final PackResult from the current context state. /// public PackResult ToResult() { var allUnusedItems = new List(); allUnusedItems.AddRange(OversizedItems); allUnusedItems.AddRange(RemainingItems); return new PackResult(Bins, allUnusedItems); } } }