diff --git a/Craftimizer/Windows/MacroEditor.cs b/Craftimizer/Windows/MacroEditor.cs index b5fb4f4..5ba0205 100644 --- a/Craftimizer/Windows/MacroEditor.cs +++ b/Craftimizer/Windows/MacroEditor.cs @@ -180,7 +180,7 @@ public sealed class MacroEditor : Window, IDisposable Reliability ??= new(initialState, actionSet, Service.Configuration.ReliabilitySimulationCount, recipeData); }; - + private List Macro { get; set; } = new(); private SimulationState InitialState { get; set; } private SimulationState State => Macro.Count > 0 ? Macro[^1].State : InitialState; @@ -191,6 +191,8 @@ public sealed class MacroEditor : Window, IDisposable private CancellationTokenSource? SolverTokenSource { get; set; } private Exception? SolverException { get; set; } private int? SolverStartStepCount { get; set; } + private object? SolverQueueLock { get; set; } + private List? SolverQueuedSteps { get; set; } private bool SolverRunning => SolverTokenSource != null; private IDalamudTextureWrap ExpertBadge { get; } @@ -255,6 +257,11 @@ public sealed class MacroEditor : Window, IDisposable SolverTokenSource?.Cancel(); } + public override void Update() + { + TryFlushSolvedSteps(); + } + public override void Draw() { var modifiedInput = false; @@ -1577,6 +1584,16 @@ public sealed class MacroEditor : Window, IDisposable SolverTokenSource?.Cancel(); SolverTokenSource = new(); SolverException = null; + if (SolverQueueLock is { }) + { + lock (SolverQueueLock) + { + SolverQueuedSteps!.Clear(); + SolverQueueLock = null; + } + } + SolverQueueLock = new(); + SolverQueuedSteps ??= new(); RevertPreviousMacro(); @@ -1622,7 +1639,7 @@ public sealed class MacroEditor : Window, IDisposable var solver = new Solver.Solver(config, state) { Token = token }; solver.OnLog += Log.Debug; - solver.OnNewAction += a => AddStep(a, isSolver: true); + solver.OnNewAction += QueueSolverStep; solver.Start(); _ = solver.GetTask().GetAwaiter().GetResult(); @@ -1655,11 +1672,11 @@ public sealed class MacroEditor : Window, IDisposable private static Sim CreateSim(in SimulationState state) => Service.Configuration.ConditionRandomness ? new Sim() { State = state } : new SimNoRandom() { State = state }; - private void AddStep(ActionType action, int index = -1, bool isSolver = false) + private void AddStep(ActionType action, int index = -1) { if (index < -1 || index >= Macro.Count) throw new ArgumentOutOfRangeException(nameof(index)); - if (!isSolver && SolverRunning) + if (SolverRunning) throw new InvalidOperationException("Cannot add steps while solver is running"); if (!SolverRunning) SolverStartStepCount = null; @@ -1680,6 +1697,38 @@ public sealed class MacroEditor : Window, IDisposable } } + private void QueueSolverStep(ActionType action) + { + if (!SolverRunning) + throw new InvalidOperationException("Cannot queue steps while solver isn't running"); + lock (SolverQueueLock!) + { + var lastState = SolverQueuedSteps!.Count > 0 ? SolverQueuedSteps[^1].State : State; + SolverQueuedSteps.Add(new(action, CreateSim(), lastState, out _)); + } + } + + private void TryFlushSolvedSteps() + { + if (SolverQueueLock == null) + return; + + lock (SolverQueueLock!) + { + if (SolverQueuedSteps!.Count > 0) + { + Macro.AddRange(SolverQueuedSteps); + SolverQueuedSteps.Clear(); + } + + if (!SolverRunning) + { + SolverQueuedSteps.Clear(); + SolverQueueLock = null; + } + } + } + private void RemoveStep(int index) { if (index < 0 || index >= Macro.Count)