Add violin plots for reliability
And move custom imraii stuff to imraii2
This commit is contained in:
@@ -39,6 +39,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="DalamudPackager" Version="2.1.12" />
|
||||
<PackageReference Include="MathNet.Numerics" Version="5.0.0" />
|
||||
<PackageReference Include="Meziantou.Analyzer" Version="2.0.106">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
|
||||
@@ -5,7 +5,7 @@ using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace Craftimizer;
|
||||
namespace Craftimizer.Plugin;
|
||||
|
||||
internal static unsafe class ImGuiExtras
|
||||
{
|
||||
|
||||
+71
-31
@@ -2,12 +2,16 @@ using Craftimizer.Utils;
|
||||
using Dalamud.Interface;
|
||||
using Dalamud.Interface.Utility.Raii;
|
||||
using ImGuiNET;
|
||||
using ImPlotNET;
|
||||
using MathNet.Numerics.Statistics;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@@ -130,37 +134,6 @@ internal static class ImGuiUtils
|
||||
ImGui.PopID();
|
||||
}
|
||||
|
||||
private struct EndUnconditionally : ImRaii.IEndObject, IDisposable
|
||||
{
|
||||
private Action EndAction { get; }
|
||||
|
||||
public bool Success { get; }
|
||||
|
||||
public bool Disposed { get; private set; }
|
||||
|
||||
public EndUnconditionally(Action endAction, bool success)
|
||||
{
|
||||
EndAction = endAction;
|
||||
Success = success;
|
||||
Disposed = false;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (!Disposed)
|
||||
{
|
||||
EndAction();
|
||||
Disposed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static ImRaii.IEndObject GroupPanel(string name, float width, out float internalWidth)
|
||||
{
|
||||
internalWidth = BeginGroupPanel(name, width);
|
||||
return new EndUnconditionally(EndGroupPanel, true);
|
||||
}
|
||||
|
||||
private static Vector2 UnitCircle(float theta)
|
||||
{
|
||||
var (s, c) = MathF.SinCos(theta);
|
||||
@@ -168,6 +141,7 @@ internal static class ImGuiUtils
|
||||
return new Vector2(c, -s);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static float Lerp(float a, float b, float t) =>
|
||||
MathF.FusedMultiplyAdd(b - a, t, a);
|
||||
|
||||
@@ -251,6 +225,72 @@ internal static class ImGuiUtils
|
||||
Arc(MathF.PI / 2, MathF.PI / 2 - MathF.Tau * Math.Clamp(value, 0, 1), radiusInner, radiusOuter, backgroundColor, filledColor);
|
||||
}
|
||||
|
||||
public sealed class ViolinData
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct Point
|
||||
{
|
||||
public float X, Y, Y2;
|
||||
|
||||
public Point(float x, float y, float y2)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
Y2 = y2;
|
||||
}
|
||||
}
|
||||
|
||||
public ReadOnlySpan<Point> Data => (DataArray ?? Array.Empty<Point>()).AsSpan();
|
||||
private Point[]? DataArray { get; set; }
|
||||
public readonly float Min;
|
||||
public readonly float Max;
|
||||
|
||||
public ViolinData(IEnumerable<int> samples, float min, float max, int resolution, double bandwidth)
|
||||
{
|
||||
Min = min;
|
||||
Max = max;
|
||||
bandwidth *= Max - Min;
|
||||
var samplesList = samples.AsParallel().Select(s => (double)s).ToArray();
|
||||
_ = Task.Run(() => {
|
||||
var s = Stopwatch.StartNew();
|
||||
var data = ParallelEnumerable.Range(0, resolution)
|
||||
.Select(n => Lerp(min, max, n / (float)resolution))
|
||||
.Select(n => (n, (float)KernelDensity.EstimateGaussian(n, bandwidth, samplesList)))
|
||||
.Select(n => new Point(n.n, n.Item2, -n.Item2));
|
||||
DataArray = data.ToArray();
|
||||
s.Stop();
|
||||
Log.Debug($"Violin plot processing took {s.Elapsed.TotalMilliseconds:0.00}ms");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public static void ViolinPlot(in ViolinData data, Vector2 size)
|
||||
{
|
||||
using var padding = ImRaii2.PushStyle(ImPlotStyleVar.PlotPadding, Vector2.Zero);
|
||||
using var plotBg = ImRaii2.PushColor(ImPlotCol.PlotBg, Vector4.Zero);
|
||||
using var frameBg = ImRaii2.PushColor(ImPlotCol.FrameBg, Vector4.Zero);
|
||||
using var fill = ImRaii2.PushColor(ImPlotCol.Fill, Vector4.One.WithAlpha(.5f));
|
||||
|
||||
using var plot = ImRaii2.Plot("##violin", size, ImPlotFlags.CanvasOnly);
|
||||
if (plot)
|
||||
{
|
||||
ImPlot.SetupAxes(null, null, ImPlotAxisFlags.NoDecorations, ImPlotAxisFlags.NoDecorations | ImPlotAxisFlags.AutoFit);
|
||||
ImPlot.SetupAxisLimits(ImAxis.X1, data.Min, data.Max, ImPlotCond.Always);
|
||||
ImPlot.SetupFinish();
|
||||
|
||||
if (data.Data is { } points && !points.IsEmpty)
|
||||
{
|
||||
unsafe {
|
||||
var label_id = stackalloc byte[] { (byte)'\0' };
|
||||
fixed (ViolinData.Point* p = points)
|
||||
{
|
||||
ImPlotNative.ImPlot_PlotShaded_FloatPtrFloatPtrFloatPtr(label_id, &p->X, &p->Y, &p->Y2, points.Length, ImPlotShadedFlags.None, 0, sizeof(ViolinData.Point));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class SearchableComboData<T> where T : class
|
||||
{
|
||||
public readonly ImmutableArray<T> items;
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
using Dalamud.Interface.Utility.Raii;
|
||||
using ImPlotNET;
|
||||
using System;
|
||||
using System.Numerics;
|
||||
|
||||
namespace Craftimizer.Plugin;
|
||||
|
||||
public static class ImRaii2
|
||||
{
|
||||
private struct EndUnconditionally : ImRaii.IEndObject, IDisposable
|
||||
{
|
||||
private Action EndAction { get; }
|
||||
|
||||
public bool Success { get; }
|
||||
|
||||
public bool Disposed { get; private set; }
|
||||
|
||||
public EndUnconditionally(Action endAction, bool success)
|
||||
{
|
||||
EndAction = endAction;
|
||||
Success = success;
|
||||
Disposed = false;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (!Disposed)
|
||||
{
|
||||
EndAction();
|
||||
Disposed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private struct EndConditionally : ImRaii.IEndObject, IDisposable
|
||||
{
|
||||
public bool Success { get; }
|
||||
|
||||
public bool Disposed { get; private set; }
|
||||
|
||||
private Action EndAction { get; }
|
||||
|
||||
public EndConditionally(Action endAction, bool success)
|
||||
{
|
||||
EndAction = endAction;
|
||||
Success = success;
|
||||
Disposed = false;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (!Disposed)
|
||||
{
|
||||
if (Success)
|
||||
{
|
||||
EndAction();
|
||||
}
|
||||
|
||||
Disposed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static ImRaii.IEndObject GroupPanel(string name, float width, out float internalWidth)
|
||||
{
|
||||
internalWidth = ImGuiUtils.BeginGroupPanel(name, width);
|
||||
return new EndUnconditionally(ImGuiUtils.EndGroupPanel, true);
|
||||
}
|
||||
|
||||
public static ImRaii.IEndObject Plot(string title_id, Vector2 size, ImPlotFlags flags)
|
||||
{
|
||||
return new EndConditionally(new Action(ImPlot.EndPlot), ImPlot.BeginPlot(title_id, size, flags));
|
||||
}
|
||||
|
||||
public static ImRaii.IEndObject PushStyle(ImPlotStyleVar idx, Vector2 val)
|
||||
{
|
||||
ImPlot.PushStyleVar(idx, val);
|
||||
return new EndUnconditionally(ImPlot.PopStyleVar, true);
|
||||
}
|
||||
|
||||
public static ImRaii.IEndObject PushStyle(ImPlotStyleVar idx, float val)
|
||||
{
|
||||
ImPlot.PushStyleVar(idx, val);
|
||||
return new EndUnconditionally(ImPlot.PopStyleVar, true);
|
||||
}
|
||||
|
||||
public static ImRaii.IEndObject PushColor(ImPlotCol idx, Vector4 col)
|
||||
{
|
||||
ImPlot.PushStyleColor(idx, col);
|
||||
return new EndUnconditionally(ImPlot.PopStyleColor, true);
|
||||
}
|
||||
}
|
||||
@@ -36,7 +36,7 @@ public sealed class MacroClipboard : Window, IDisposable
|
||||
private void DrawMacro(int idx, string macro)
|
||||
{
|
||||
using var id = ImRaii.PushId(idx);
|
||||
using var panel = ImGuiUtils.GroupPanel($"Macro {idx + 1}", -1, out var availWidth);
|
||||
using var panel = ImRaii2.GroupPanel($"Macro {idx + 1}", -1, out var availWidth);
|
||||
|
||||
var cursor = ImGui.GetCursorPos();
|
||||
|
||||
|
||||
@@ -79,31 +79,48 @@ public sealed class MacroEditor : Window, IDisposable
|
||||
|
||||
private readonly record struct SimulationReliablity
|
||||
{
|
||||
public record struct ParamReliability
|
||||
public sealed class ParamReliability
|
||||
{
|
||||
private List<int> DataList { get; }
|
||||
private ImGuiUtils.ViolinData? ViolinData { get; set; }
|
||||
|
||||
public int Max { get; private set; }
|
||||
public int Min { get; private set; }
|
||||
public float Median { get; private set; }
|
||||
public float Average { get; private set; }
|
||||
|
||||
public ParamReliability()
|
||||
{
|
||||
Min = int.MaxValue;
|
||||
DataList = new();
|
||||
}
|
||||
|
||||
public void Add(int value)
|
||||
{
|
||||
Max = Math.Max(Max, value);
|
||||
Min = Math.Min(Min, value);
|
||||
Average += value;
|
||||
DataList.Add(value);
|
||||
}
|
||||
|
||||
public void Finalize(int count)
|
||||
public void FinalizeData()
|
||||
{
|
||||
if (count == 0)
|
||||
Average = Max = Min = 0;
|
||||
else
|
||||
Average /= count;
|
||||
if (DataList.Count == 0)
|
||||
{
|
||||
Average = Median = Max = Min = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
Max = DataList.Max();
|
||||
Min = DataList.Min();
|
||||
if (DataList.Count % 2 == 0)
|
||||
Median = (float)DataList.Order().Skip(DataList.Count / 2 - 1).Take(2).Average();
|
||||
else
|
||||
Median = DataList.Order().ElementAt(DataList.Count / 2);
|
||||
Average = (float)DataList.Average();
|
||||
}
|
||||
|
||||
public ImGuiUtils.ViolinData? GetViolinData(float barMax, int resolution, double bandwidth) =>
|
||||
ViolinData ??=
|
||||
Min != Max ?
|
||||
new(DataList, 0, barMax, resolution, bandwidth) :
|
||||
null;
|
||||
}
|
||||
|
||||
public readonly ParamReliability Progress = new();
|
||||
@@ -132,9 +149,9 @@ public sealed class MacroEditor : Window, IDisposable
|
||||
Quality.Add(state.Quality);
|
||||
Param.Add(getParam(state));
|
||||
}
|
||||
Progress.Finalize(iterCount);
|
||||
Quality.Finalize(iterCount);
|
||||
Param.Finalize(iterCount);
|
||||
Progress.FinalizeData();
|
||||
Quality.FinalizeData();
|
||||
Param.FinalizeData();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,7 +177,8 @@ public sealed class MacroEditor : Window, IDisposable
|
||||
}
|
||||
|
||||
public SimulationReliablity GetReliability(in SimulationState initialState, IEnumerable<ActionType> actionSet, RecipeData recipeData) =>
|
||||
Reliability ??= new(initialState, actionSet, Service.Configuration.ReliabilitySimulationCount, recipeData);
|
||||
Reliability ??=
|
||||
new(initialState, actionSet, Service.Configuration.ReliabilitySimulationCount, recipeData);
|
||||
};
|
||||
|
||||
private List<SimulatedActionStep> Macro { get; set; } = new();
|
||||
@@ -195,7 +213,7 @@ public sealed class MacroEditor : Window, IDisposable
|
||||
private CancellationTokenSource? popupImportUrlTokenSource;
|
||||
private MacroImport.RetrievedMacro? popupImportUrlMacro;
|
||||
|
||||
public MacroEditor(CharacterStats characterStats, RecipeData recipeData, CrafterBuffs buffs, IEnumerable<ActionType> actions, Action<IEnumerable<ActionType>>? setter) : base("Craftimizer Macro Editor", WindowFlags, false)
|
||||
public MacroEditor(CharacterStats characterStats, RecipeData recipeData, CrafterBuffs buffs, IEnumerable<ActionType> actions, Action<IEnumerable<ActionType>>? setter) : base("Craftimizer Macro Editor", WindowFlags)
|
||||
{
|
||||
CharacterStats = characterStats;
|
||||
RecipeData = recipeData;
|
||||
@@ -1000,7 +1018,7 @@ public sealed class MacroEditor : Window, IDisposable
|
||||
continue;
|
||||
|
||||
var actions = category.GetActions();
|
||||
using var panel = ImGuiUtils.GroupPanel(category.GetDisplayName(), -1, out var availSpace);
|
||||
using var panel = ImRaii2.GroupPanel(category.GetDisplayName(), -1, out var availSpace);
|
||||
var itemsPerRow = (int)MathF.Floor((availSpace + spacing) / (imageSize + spacing));
|
||||
var itemCount = actions.Count;
|
||||
var iterCount = (int)(Math.Ceiling((float)itemCount / itemsPerRow) * itemsPerRow);
|
||||
@@ -1076,7 +1094,7 @@ public sealed class MacroEditor : Window, IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
using (var panel = ImGuiUtils.GroupPanel("Buffs", -1, out _))
|
||||
using (var panel = ImRaii2.GroupPanel("Buffs", -1, out _))
|
||||
{
|
||||
using var _font = ImRaii.PushFont(AxisFont.ImFont);
|
||||
|
||||
@@ -1134,7 +1152,7 @@ public sealed class MacroEditor : Window, IDisposable
|
||||
var barSize = totalSize - textSize - spacing;
|
||||
foreach (var bar in bars)
|
||||
{
|
||||
using var panel = ImGuiUtils.GroupPanel(bar.Name, totalSize, out _);
|
||||
using var panel = ImRaii2.GroupPanel(bar.Name, totalSize, out _);
|
||||
if (bar.Condition is { } condition)
|
||||
{
|
||||
using (var g = ImRaii.Group())
|
||||
@@ -1154,47 +1172,27 @@ public sealed class MacroEditor : Window, IDisposable
|
||||
ImGui.SetTooltip(condition.Description(CharacterStats.HasSplendorousBuff));
|
||||
}
|
||||
else
|
||||
{
|
||||
var pos = ImGui.GetCursorPos();
|
||||
using (var color = ImRaii.PushColor(ImGuiCol.PlotHistogram, bar.Color))
|
||||
ImGui.ProgressBar(Math.Clamp(bar.Value / bar.Max, 0, 1), new(barSize, ImGui.GetFrameHeight()), string.Empty);
|
||||
if (ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenOverlapped))
|
||||
{
|
||||
if (bar.Reliability is { } reliability)
|
||||
{
|
||||
// blend rgb colors, assume alpha is always 1
|
||||
static Vector4 BlendColor(Vector4 A, Vector4 B)
|
||||
{
|
||||
return new(
|
||||
A.X * (1 - B.W) + B.X * B.W,
|
||||
A.Y * (1 - B.W) + B.Y * B.W,
|
||||
A.Z * (1 - B.W) + B.Z * B.W,
|
||||
1);
|
||||
}
|
||||
var relBars = new (float Value, Vector4 Color)[]
|
||||
{
|
||||
(bar.Value, bar.Color),
|
||||
(reliability.Average, BlendColor(bar.Color, new(.5f,.5f,.5f,.6f))),
|
||||
(reliability.Min, BlendColor(bar.Color, new(0,0,0,.6f))),
|
||||
(reliability.Max, BlendColor(bar.Color, new(1,1,1,.6f))),
|
||||
}.DistinctBy(v => Math.Clamp(v.Value, 0, bar.Max)).OrderByDescending(v => v.Value);
|
||||
var i = 0;
|
||||
var pos = ImGui.GetCursorPos();
|
||||
foreach (var relBar in relBars)
|
||||
if (reliability.GetViolinData(bar.Max, (int)(barSize / 2), 0.02) is { } violinData)
|
||||
{
|
||||
ImGui.SetCursorPos(pos);
|
||||
{
|
||||
using var frameColor = ImRaii.PushColor(ImGuiCol.FrameBg, Vector4.Zero, i != 0);
|
||||
using var color = ImRaii.PushColor(ImGuiCol.PlotHistogram, relBar.Color);
|
||||
ImGui.ProgressBar(Math.Clamp(relBar.Value / bar.Max, 0, 1), new(barSize, ImGui.GetFrameHeight()), string.Empty);
|
||||
}
|
||||
if (i++ == 0)
|
||||
{
|
||||
ImGuiUtils.ViolinPlot(violinData, new(barSize, ImGui.GetFrameHeight()));
|
||||
if (ImGui.IsItemHovered())
|
||||
ImGui.SetTooltip($"Min: {reliability.Min}\nAvg: {reliability.Average:0.##}\nMax: {reliability.Max}");
|
||||
ImGui.SetTooltip(
|
||||
$"Min: {reliability.Min}\n" +
|
||||
$"Med: {reliability.Median:0.##}\n" +
|
||||
$"Avg: {reliability.Average:0.##}\n" +
|
||||
$"Max: {reliability.Max}");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
using var color = ImRaii.PushColor(ImGuiCol.PlotHistogram, bar.Color);
|
||||
ImGui.ProgressBar(Math.Clamp(bar.Value / bar.Max, 0, 1), new(barSize, ImGui.GetFrameHeight()), string.Empty);
|
||||
}
|
||||
ImGui.SameLine(0, spacing);
|
||||
ImGui.AlignTextToFramePadding();
|
||||
if (bar.Caption is { } caption)
|
||||
@@ -1217,7 +1215,7 @@ public sealed class MacroEditor : Window, IDisposable
|
||||
var imageSize = ImGui.GetFrameHeight() * 2;
|
||||
var lastState = InitialState;
|
||||
|
||||
using var panel = ImGuiUtils.GroupPanel("Macro", -1, out var availSpace);
|
||||
using var panel = ImRaii2.GroupPanel("Macro", -1, out var availSpace);
|
||||
ImGui.Dummy(new(0, imageSize));
|
||||
ImGui.SameLine(0, 0);
|
||||
|
||||
@@ -1412,7 +1410,7 @@ public sealed class MacroEditor : Window, IDisposable
|
||||
{
|
||||
bool submittedText, submittedUrl;
|
||||
|
||||
using (var panel = ImGuiUtils.GroupPanel("##text", -1, out var availWidth))
|
||||
using (var panel = ImRaii2.GroupPanel("##text", -1, out var availWidth))
|
||||
{
|
||||
ImGui.AlignTextToFramePadding();
|
||||
ImGuiUtils.TextCentered("Paste your macro here");
|
||||
@@ -1424,7 +1422,7 @@ public sealed class MacroEditor : Window, IDisposable
|
||||
submittedText = ImGui.Button("Import", new(availWidth, 0));
|
||||
}
|
||||
|
||||
using (var panel = ImGuiUtils.GroupPanel("##url", -1, out var availWidth))
|
||||
using (var panel = ImRaii2.GroupPanel("##url", -1, out var availWidth))
|
||||
{
|
||||
var availOffset = ImGui.GetContentRegionAvail().X - availWidth;
|
||||
|
||||
|
||||
@@ -111,7 +111,7 @@ public sealed class MacroList : Window, IDisposable
|
||||
|
||||
var stateNullable = GetMacroState(macro);
|
||||
|
||||
using var panel = ImGuiUtils.GroupPanel(macro.Name, -1, out var availWidth);
|
||||
using var panel = ImRaii2.GroupPanel(macro.Name, -1, out var availWidth);
|
||||
var stepsAvailWidthOffset = ImGui.GetContentRegionAvail().X - availWidth;
|
||||
var spacing = ImGui.GetStyle().ItemSpacing.Y;
|
||||
var miniRowHeight = (windowHeight - spacing) / 2f;
|
||||
|
||||
@@ -216,7 +216,7 @@ public sealed unsafe class RecipeNote : Window, IDisposable
|
||||
ImGui.Separator();
|
||||
|
||||
var panelWidth = availWidth - ImGui.GetStyle().ItemSpacing.X * 2;
|
||||
using (var panel = ImGuiUtils.GroupPanel("Best Saved Macro", panelWidth, out _))
|
||||
using (var panel = ImRaii2.GroupPanel("Best Saved Macro", panelWidth, out _))
|
||||
{
|
||||
var stepsPanelWidthOffset = ImGui.GetContentRegionAvail().X - panelWidth;
|
||||
if (BestSavedMacro is { } savedMacro)
|
||||
@@ -228,7 +228,7 @@ public sealed unsafe class RecipeNote : Window, IDisposable
|
||||
DrawMacro(null, null, stepsPanelWidthOffset, true);
|
||||
}
|
||||
|
||||
using (var panel = ImGuiUtils.GroupPanel("Suggested Macro", panelWidth, out _))
|
||||
using (var panel = ImRaii2.GroupPanel("Suggested Macro", panelWidth, out _))
|
||||
{
|
||||
var stepsPanelWidthOffset = ImGui.GetContentRegionAvail().X - panelWidth;
|
||||
if (BestSuggestedMacro is { } suggestedMacro)
|
||||
|
||||
@@ -191,7 +191,7 @@ public sealed class Settings : Window, IDisposable
|
||||
ImGui.SetTooltip("Disabled temporarily for testing");
|
||||
|
||||
DrawOption(
|
||||
"Show Only One Macro Stat",
|
||||
"Show Only One Macro Stat in Crafting Log",
|
||||
"Only one stat will be shown for a macro. If a craft will be finished, quality\n" +
|
||||
"is shown. Otherwise, progress is shown. Durability and remaining CP will be\n" +
|
||||
"hidden.",
|
||||
@@ -200,9 +200,21 @@ public sealed class Settings : Window, IDisposable
|
||||
ref isDirty
|
||||
);
|
||||
|
||||
DrawOption(
|
||||
"Reliability Trial Count",
|
||||
"When testing for reliability of a macro in the editor, this many trials will be\n" +
|
||||
"run. You should set this value to at least 100 to get a reliable spread of data.\n" +
|
||||
"If it's too low, you may not find an outlier, and the average might be skewed.",
|
||||
Config.ReliabilitySimulationCount,
|
||||
5,
|
||||
5000,
|
||||
v => Config.ReliabilitySimulationCount = v,
|
||||
ref isDirty
|
||||
);
|
||||
|
||||
ImGuiHelpers.ScaledDummy(5);
|
||||
|
||||
using (var panel = ImGuiUtils.GroupPanel("Copying Settings", -1, out _))
|
||||
using (var panel = ImRaii2.GroupPanel("Copying Settings", -1, out _))
|
||||
{
|
||||
DrawOption(
|
||||
"Macro Copy Method",
|
||||
@@ -380,7 +392,7 @@ public sealed class Settings : Window, IDisposable
|
||||
|
||||
var config = configRef;
|
||||
|
||||
using (var panel = ImGuiUtils.GroupPanel("General", -1, out _))
|
||||
using (var panel = ImRaii2.GroupPanel("General", -1, out _))
|
||||
{
|
||||
if (ImGui.Button("Reset to Default", OptionButtonSize))
|
||||
{
|
||||
@@ -501,7 +513,7 @@ public sealed class Settings : Window, IDisposable
|
||||
);
|
||||
}
|
||||
|
||||
using (var panel = ImGuiUtils.GroupPanel("Advanced", -1, out _))
|
||||
using (var panel = ImRaii2.GroupPanel("Advanced", -1, out _))
|
||||
{
|
||||
DrawOption(
|
||||
"Score Storage Threshold",
|
||||
@@ -538,7 +550,7 @@ public sealed class Settings : Window, IDisposable
|
||||
);
|
||||
}
|
||||
|
||||
using (var panel = ImGuiUtils.GroupPanel("Score Weights (Advanced)", -1, out _))
|
||||
using (var panel = ImRaii2.GroupPanel("Score Weights (Advanced)", -1, out _))
|
||||
{
|
||||
ImGui.TextWrapped("All values should add up to 1. Otherwise, the Score Storage Threshold should be changed.");
|
||||
ImGuiHelpers.ScaledDummy(10);
|
||||
|
||||
@@ -8,6 +8,12 @@
|
||||
"resolved": "2.1.12",
|
||||
"contentHash": "Sc0PVxvgg4NQjcI8n10/VfUQBAS4O+Fw2pZrAqBdRMbthYGeogzu5+xmIGCGmsEZ/ukMOBuAqiNiB5qA3MRalg=="
|
||||
},
|
||||
"MathNet.Numerics": {
|
||||
"type": "Direct",
|
||||
"requested": "[5.0.0, )",
|
||||
"resolved": "5.0.0",
|
||||
"contentHash": "pg1W2VwaEQMAiTpGK840hZgzavnqjlCMTVSbtVCXVyT+7AX4mc1o89SPv4TBlAjhgCOo9c1Y+jZ5m3ti2YgGgA=="
|
||||
},
|
||||
"Meziantou.Analyzer": {
|
||||
"type": "Direct",
|
||||
"requested": "[2.0.106, )",
|
||||
|
||||
Reference in New Issue
Block a user