using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Threading; using MultiWheelC.TrajectoryPlanning.EMPlanner; namespace EMPlannerVerificationHost; internal sealed class FakeQpSolver : IQpSolver { private readonly Queue _results; private readonly List _problems = new List(); private readonly List> _warmStarts = new List>(); public FakeQpSolver(QpSolveResult result) : this(new[] { result }) { } public FakeQpSolver(IEnumerable results) { if (results == null) throw new ArgumentNullException(nameof(results)); _results = new Queue(); foreach (QpSolveResult result in results) _results.Enqueue(result ?? throw new ArgumentException("Fake solver results cannot contain null values.", nameof(results))); if (_results.Count == 0) throw new ArgumentException("At least one fake solver result is required.", nameof(results)); LastWarmStart = Array.Empty(); } public QuadraticProgram? LastProblem { get; private set; } public QpSolverSettings? LastSettings { get; private set; } public IReadOnlyList LastWarmStart { get; private set; } public IReadOnlyList Problems => new ReadOnlyCollection(_problems); public IReadOnlyList> WarmStarts => new ReadOnlyCollection>(_warmStarts); public int SolveCallCount => _problems.Count; public QpSolveResult Solve(QuadraticProgram problem, QpSolverSettings settings, IReadOnlyList warmStart, CancellationToken cancellationToken) { LastProblem = problem ?? throw new ArgumentNullException(nameof(problem)); LastSettings = settings ?? throw new ArgumentNullException(nameof(settings)); var copy = new List(warmStart == null ? 0 : warmStart.Count); if (warmStart != null) { for (int index = 0; index < warmStart.Count; index++) copy.Add(warmStart[index]); } LastWarmStart = new ReadOnlyCollection(copy); _problems.Add(LastProblem); _warmStarts.Add(LastWarmStart); if (_results.Count == 0) throw new InvalidOperationException("Fake solver was called more often than its scripted result sequence."); return _results.Dequeue(); } }