Files
Craftimizer/Craftimizer/Windows/CraftSolver.cs
T
2023-10-02 22:28:12 -07:00

101 lines
3.0 KiB
C#

using Craftimizer.Simulator;
using Craftimizer.Simulator.Actions;
using Dalamud.Interface.Windowing;
using Dalamud.Logging;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace Craftimizer.Plugin.Windows;
public sealed unsafe partial class Craft : Window, IDisposable
{
private SimulationState? SolverState { get; set; }
private Solver.Solver? SolverTask { get; set; }
private CancellationTokenSource? SolverTaskToken { get; set; }
private ConcurrentQueue<ActionType> SolverActionQueue { get; } = new();
// State is the state of the simulation *after* its corresponding action is executed.
private List<(ActionType Action, string Tooltip, SimulationState State)> SolverActions { get; } = new();
private SimulatorNoRandom SolverSim { get; set; } = null!;
private SimulationState SolverLatestState => SolverActions.Count == 0 ? SolverState!.Value : SolverActions[^1].State;
private void StopSolve()
{
if (SolverTask == null || SolverTaskToken == null)
return;
if (!SolverTask.IsCompleted)
SolverTaskToken.Cancel();
else
{
SolverTaskToken.Dispose();
SolverTask.Dispose();
SolverTask = null;
SolverTaskToken = null;
}
}
private void QueueSolve(SimulationState state)
{
StopSolve();
SolverActionQueue.Clear();
SolverActions.Clear();
SolverState = state;
SolverSim = new(state);
SolverTaskToken = new();
SolverTask = new(Config.SynthHelperSolverConfig, state) { Token = SolverTaskToken.Token };
SolverTask.OnLog += s => PluginLog.Debug(s);
SolverTask.OnNewAction += SolverActionQueue.Enqueue;
SolverTask.Start();
}
private void SolveTick()
{
var newState = GetNextState();
if (SolverState == newState)
return;
if (newState == null)
StopSolve();
else
QueueSolve(newState.Value);
}
private void DequeueSolver()
{
while (SolverActionQueue.TryDequeue(out var poppedAction))
AppendSolverAction(poppedAction);
}
private void AppendSolverAction(ActionType action)
{
var actionBase = action.Base();
if (actionBase is BaseComboAction comboActionBase)
{
AppendSolverAction(comboActionBase.ActionTypeA);
AppendSolverAction(comboActionBase.ActionTypeB);
}
else
{
if (SolverActions.Count >= Config.SynthHelperStepCount)
{
StopSolve();
return;
}
var tooltip = actionBase.GetTooltip(SolverSim, false);
var (_, state) = SolverSim.Execute(SolverLatestState, action);
SolverActions.Add((action, tooltip, state));
if (SolverActions.Count >= Config.SynthHelperStepCount)
StopSolve();
}
}
}