Browse Source

InitialValue support in Launch definition

pull/5/head
Ionite 1 year ago
parent
commit
2ddcbc9797
No known key found for this signature in database
  1. 6
      StabilityMatrix/Helper/DialogFactory.cs
  2. 17
      StabilityMatrix/Models/LaunchOptionDefinition.cs
  3. 23
      StabilityMatrix/Models/Packages/A3WebUI.cs
  4. 17
      StabilityMatrix/Models/Packages/VladAutomatic.cs
  5. 66
      StabilityMatrix/ViewModels/LaunchOptionsDialogViewModel.cs

6
StabilityMatrix/Helper/DialogFactory.cs

@ -25,13 +25,9 @@ public class DialogFactory : IDialogFactory
public LaunchOptionsDialog CreateLaunchOptionsDialog(IEnumerable<LaunchOptionDefinition> definitions, InstalledPackage installedPackage)
{
launchOptionsDialogViewModel.Clear();
// Create cards
launchOptionsDialogViewModel.CardsFromDefinitions(definitions);
// Load user settings
var userLaunchArgs = settingsManager.GetLaunchArgs(installedPackage.Id);
launchOptionsDialogViewModel.LoadFromLaunchArgs(userLaunchArgs);
launchOptionsDialogViewModel.Initialize(definitions, userLaunchArgs);
return new LaunchOptionsDialog(contentDialogService, launchOptionsDialogViewModel);
}

17
StabilityMatrix/Models/LaunchOptionDefinition.cs

@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Text.Json.Serialization;
namespace StabilityMatrix.Models;
@ -7,7 +8,7 @@ namespace StabilityMatrix.Models;
/// </summary>
public class LaunchOptionDefinition
{
public string Name { get; set; }
public string Name { get; init; }
/// <summary>
/// Type of the option. "bool", "int", or "string"
@ -15,12 +16,19 @@ public class LaunchOptionDefinition
/// - "int" and "string" should supply a single flag in the Options list (e.g. ["--width"], ["--api"])
/// </summary>
public LaunchOptionType Type { get; init; } = LaunchOptionType.Bool;
public string? Description { get; set; }
public string? Description { get; init; }
/// <summary>
/// Constant default value for the option.
/// Server-side default for the option. (Ignored for launch and saving if value matches)
/// Use `InitialValue` to provide a default that is set as the user value and used for launch.
/// </summary>
public object? DefaultValue { get; set; }
public object? DefaultValue { get; init; }
/// <summary>
/// Initial value for the option if no set value is available, set as the user value on save.
/// Use `DefaultValue` to provide a server-side default that is ignored for launch and saving.
/// </summary>
public object? InitialValue { get; set; }
// Minimum number of selected options
public int? MinSelectedOptions { get; set; }
@ -32,6 +40,7 @@ public class LaunchOptionDefinition
/// </summary>
public List<string> Options { get; set; }
[JsonIgnore]
public static LaunchOptionDefinition Extras => new()
{
Name = "Extra Launch Arguments",

23
StabilityMatrix/Models/Packages/A3WebUI.cs

@ -23,12 +23,6 @@ public class A3WebUI : BaseGitPackage
public override List<LaunchOptionDefinition> LaunchOptions => new()
{
new()
{
Name = "API",
DefaultValue = true,
Options = new() {"--api"}
},
new()
{
Name = "Host",
@ -46,12 +40,25 @@ public class A3WebUI : BaseGitPackage
new()
{
Name = "VRAM",
Options = new() {"--lowvram", "--medvram"}
InitialValue = HardwareHelper.IterGpuInfo().Select(gpu => gpu.MemoryLevel).Max() switch
{
Level.Low => "--lowvram",
Level.Medium => "--medvram",
_ => null
},
Options = new() { "--lowvram", "--medvram" }
},
new()
{
Name = "Xformers",
Options = new() {"--xformers"}
InitialValue = HardwareHelper.HasNvidiaGpu(),
Options = new() { "--xformers" }
},
new()
{
Name = "API",
DefaultValue = true,
Options = new() {"--api"}
},
LaunchOptionDefinition.Extras
};

17
StabilityMatrix/Models/Packages/VladAutomatic.cs

@ -22,21 +22,28 @@ public class VladAutomatic : BaseGitPackage
public override List<LaunchOptionDefinition> LaunchOptions => new()
{
new()
{
Name = "API",
Options = new() { "--api" }
},
new()
{
Name = "VRAM",
InitialValue = HardwareHelper.IterGpuInfo().Select(gpu => gpu.MemoryLevel).Max() switch
{
Level.Low => "--lowvram",
Level.Medium => "--medvram",
_ => null
},
Options = new() { "--lowvram", "--medvram" }
},
new()
{
Name = "Xformers",
InitialValue = HardwareHelper.HasNvidiaGpu() ? "--xformers" : null,
Options = new() { "--xformers" }
},
new()
{
Name = "API",
Options = new() { "--api" }
},
LaunchOptionDefinition.Extras
};

66
StabilityMatrix/ViewModels/LaunchOptionsDialogViewModel.cs

@ -5,6 +5,7 @@ using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using CommunityToolkit.Mvvm.ComponentModel;
using NLog;
using StabilityMatrix.Helper.Cache;
using StabilityMatrix.Models;
@ -12,6 +13,7 @@ namespace StabilityMatrix.ViewModels;
public partial class LaunchOptionsDialogViewModel : ObservableObject
{
public static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public ObservableCollection<LaunchOptionCard> Cards { get; set; } = new();
[ObservableProperty]
@ -67,23 +69,52 @@ public partial class LaunchOptionsDialogViewModel : ObservableObject
}
return launchArgs;
}
/// <summary>
/// Create cards using definitions
/// </summary>
public void CardsFromDefinitions(IEnumerable<LaunchOptionDefinition> definitions)
public void Initialize(IEnumerable<LaunchOptionDefinition> definitions, IEnumerable<LaunchOption> launchArgs)
{
Clear();
// During card creation, store dict of options with initial values
var initialOptions = new Dictionary<string, object>();
// Create cards
foreach (var definition in definitions)
{
// Check that non-bool types have exactly one option
if (definition.Type != LaunchOptionType.Bool && definition.Options.Count != 1)
{
throw new InvalidOperationException(
$"Definition: '{definition.Name}' has {definition.Options.Count} options," +
$" it must have exactly 1 option for non-bool types");
}
// Store initial values
if (definition.InitialValue != null)
{
// For bool types, initial value can be string (single/multiple options) or bool (single option)
if (definition.Type == LaunchOptionType.Bool)
{
// For single option, check bool
if (definition.Options.Count == 1 && definition.InitialValue is bool boolValue)
{
initialOptions[definition.Options.First()] = boolValue;
}
// For single/multiple options (string only)
var option = definition.Options.FirstOrDefault(opt => opt.Equals(definition.InitialValue));
if (option == null)
{
throw new InvalidOperationException(
$"Definition '{definition.Name}' has InitialValue of '{definition.InitialValue}', but it was not found in options:" +
$" '{string.Join(",", definition.Options)}'");
}
initialOptions[option] = true;
}
else
{
// Otherwise store initial value for first option
initialOptions[definition.Options.First()] = definition.InitialValue;
}
}
Cards.Add(new LaunchOptionCard(definition));
}
}
/// <summary>
/// Import the current cards options from a list of strings
/// </summary>
public void LoadFromLaunchArgs(IEnumerable<LaunchOption> launchArgs)
{
// Load launch args
var launchArgsDict = launchArgs.ToDictionary(launchArg => launchArg.Name);
foreach (var card in Cards)
{
@ -91,6 +122,17 @@ public partial class LaunchOptionsDialogViewModel : ObservableObject
{
var userOption = launchArgsDict.GetValueOrDefault(option.Name);
var userValue = userOption?.OptionValue?.ToString();
// If no user value, check for initial value
if (userValue == null)
{
var initialValue = initialOptions.GetValueOrDefault(option.Name);
if (initialValue != null)
{
userValue = initialValue.ToString();
Logger.Info("Using initial value '{InitialValue}' for option '{OptionName}'",
initialValue, option.Name);
}
}
option.SetValueFromString(userValue);
}
}

Loading…
Cancel
Save