Replace original Options object

This commit is contained in:
Matt Nadareski
2026-02-07 15:11:46 -05:00
parent a4fb368f7e
commit 56ee536eae
23 changed files with 68 additions and 67 deletions

View File

@@ -28,6 +28,7 @@
- Fix path assignment from UI
- Reduce reach of original Options type
- Move dictionary logic to new Options object
- Replace original Options object
### 3.6.0 (2025-11-28)

View File

@@ -19,7 +19,7 @@ namespace MPF.CLI.Features
/// <summary>
/// User-defined options
/// </summary>
public SegmentedOptions Options { get; protected set; }
public Options Options { get; protected set; }
/// <summary>
/// Currently-selected system
@@ -65,7 +65,7 @@ namespace MPF.CLI.Features
protected BaseFeature(string name, string[] flags, string description, string? detailed = null)
: base(name, flags, description, detailed)
{
Options = new SegmentedOptions();
Options = new Options();
// Internal Program
Options.InternalProgram = InternalProgram.NONE;

View File

@@ -18,7 +18,7 @@ namespace MPF.Check.Features
/// <summary>
/// User-defined options
/// </summary>
public SegmentedOptions Options { get; protected set; }
public Options Options { get; protected set; }
/// <summary>
/// Currently-selected system
@@ -40,7 +40,7 @@ namespace MPF.Check.Features
protected BaseFeature(string name, string[] flags, string description, string? detailed = null)
: base(name, flags, description, detailed)
{
Options = new SegmentedOptions();
Options = new Options();
// Internal Program
Options.InternalProgram = InternalProgram.NONE;

View File

@@ -38,7 +38,7 @@ namespace MPF.Check.Features
Options = OptionsLoader.LoadFromConfig();
if (Options.FirstRun)
{
Options = new SegmentedOptions();
Options = new Options();
// Internal Program
Options.InternalProgram = InternalProgram.NONE;

View File

@@ -123,7 +123,7 @@ namespace MPF.Check.Features
Options = OptionsLoader.LoadFromConfig();
if (Options.FirstRun)
{
Options = new SegmentedOptions();
Options = new Options();
// Internal Program
Options.InternalProgram = InternalProgram.NONE;

View File

@@ -15,7 +15,7 @@ namespace MPF.Frontend.Test
[InlineData("stop D", 'D', false, MediaType.DVD, true)]
public void ParametersValidSegmentedTest(string? parameters, char letter, bool isFloppy, MediaType? mediaType, bool expected)
{
var options = new SegmentedOptions();
var options = new Options();
options.InternalProgram = InternalProgram.DiscImageCreator;
// TODO: This relies on creating real objects for the drive. Can we mock this out instead?

View File

@@ -21,7 +21,7 @@ namespace MPF.Frontend.Test.Tools
[InlineData(MediaType.NintendoWiiUOpticalDisc, 16)]
public void GetDefaultSpeedForMediaTypeSegmentedTest(MediaType? mediaType, int expected)
{
var options = new SegmentedOptions();
var options = new Options();
options.Dumping.DumpSpeeds.PreferredCD = 72;
options.Dumping.DumpSpeeds.PreferredDVD = 24;
options.Dumping.DumpSpeeds.PreferredHDDVD = 24;

View File

@@ -47,9 +47,9 @@ namespace MPF.Frontend
private readonly InternalProgram _internalProgram;
/// <summary>
/// SegmentedOptions object representing user-defined options
/// Options object representing user-defined options
/// </summary>
private readonly SegmentedOptions _options;
private readonly Options _options;
/// <summary>
/// Processor object representing how to process the outputs
@@ -106,14 +106,14 @@ namespace MPF.Frontend
/// <param name="drive"></param>
/// <param name="system"></param>
/// <param name="internalProgram"></param>
public DumpEnvironment(SegmentedOptions options,
public DumpEnvironment(Options options,
string? outputPath,
Drive? drive,
RedumpSystem? system,
InternalProgram? internalProgram)
{
// Set options object
_options = new SegmentedOptions(options);
_options = new Options(options);
// Output paths
OutputPath = FrontendTool.NormalizeOutputPaths(outputPath, false);

View File

@@ -13,7 +13,7 @@ namespace MPF.Frontend
/// <summary>
/// Options that use nested types for setting arrangement
/// </summary>
public class SegmentedOptions
public class Options
{
#region Properties
@@ -84,14 +84,14 @@ namespace MPF.Frontend
/// <summary>
/// Empty constructor for serialization
/// </summary>
public SegmentedOptions() { }
public Options() { }
/// <summary>
/// Constructor taking a dictionary for settings
/// </summary>
/// <param name="source">Dictionary representing settings</param>
/// TODO: Remove when Options is no longer relevant
public SegmentedOptions(Dictionary<string, string?>? source = null)
public Options(Dictionary<string, string?>? source = null)
{
source ??= [];
@@ -191,12 +191,12 @@ namespace MPF.Frontend
}
/// <summary>
/// Constructor that converts from an existing SegmentedOptions object
/// Constructor that converts from an existing Options object
/// </summary>
/// <param name="source">SegmentedOptions object to read from</param>
public SegmentedOptions(SegmentedOptions? source)
/// <param name="source">Options object to read from</param>
public Options(Options? source)
{
source ??= new SegmentedOptions();
source ??= new Options();
FirstRun = source.FirstRun;
CheckForUpdatesOnStartup = source.CheckForUpdatesOnStartup;

View File

@@ -5,8 +5,8 @@ namespace MPF.Frontend
/// <summary>
/// Determines how user information is processed, if at all
/// </summary>
/// <param name="options">SegmentedOptions set that may impact processing</params>
/// <param name="options">Options set that may impact processing</params>
/// <param name="info">Submission info that may be overwritten</param>
/// <returns>True for successful updating, false or null otherwise</returns>
public delegate bool? ProcessUserInfoDelegate(SegmentedOptions? options, ref SubmissionInfo? info);
public delegate bool? ProcessUserInfoDelegate(Options? options, ref SubmissionInfo? info);
}

View File

@@ -14,7 +14,7 @@ namespace MPF.Frontend.Tools
/// <summary>
/// Get the default speed for a given media type from the supplied options
/// </summary>
public static int GetDefaultSpeedForMediaType(MediaType? mediaType, SegmentedOptions options)
public static int GetDefaultSpeedForMediaType(MediaType? mediaType, Options options)
{
#pragma warning disable IDE0072
return mediaType switch

View File

@@ -182,36 +182,36 @@ namespace MPF.Frontend.Tools
/// <summary>
/// Load the current set of options from the application configuration
/// </summary>
public static SegmentedOptions LoadFromConfig()
public static Options LoadFromConfig()
{
// If no options path can be found
if (string.IsNullOrEmpty(ConfigurationPath))
return new SegmentedOptions();
return new Options();
// If the file does not exist
if (!File.Exists(ConfigurationPath) || new FileInfo(ConfigurationPath).Length == 0)
return new SegmentedOptions();
return new Options();
var serializer = JsonSerializer.Create();
var stream = File.Open(ConfigurationPath, FileMode.Open, FileAccess.Read, FileShare.None);
using var reader = new StreamReader(stream);
var settings = serializer.Deserialize(reader, typeof(Dictionary<string, string?>)) as Dictionary<string, string?>;
return new SegmentedOptions(settings);
return new Options(settings);
}
/// <summary>
/// Load the current set of options from the application configuration
/// </summary>
public static SegmentedOptions LoadFromConfigNative()
public static Options LoadFromConfigNative()
{
// If no options path can be found
if (string.IsNullOrEmpty(ConfigurationPath))
return new SegmentedOptions();
return new Options();
// If the file does not exist
if (!File.Exists(ConfigurationPath) || new FileInfo(ConfigurationPath).Length == 0)
return new SegmentedOptions();
return new Options();
var serializer = JsonSerializer.Create();
serializer.DefaultValueHandling = DefaultValueHandling.Ignore;
@@ -222,13 +222,13 @@ namespace MPF.Frontend.Tools
using var sr = new StreamReader(stream);
var reader = new JsonTextReader(sr);
return serializer.Deserialize<SegmentedOptions>(reader) ?? new SegmentedOptions();
return serializer.Deserialize<Options>(reader) ?? new Options();
}
/// <summary>
/// Save the current set of options to the application configuration
/// </summary>
public static void SaveToConfig(SegmentedOptions options)
public static void SaveToConfig(Options options)
{
// If no options path can be found
if (string.IsNullOrEmpty(ConfigurationPath))
@@ -245,7 +245,7 @@ namespace MPF.Frontend.Tools
/// <summary>
/// Save the current set of options to the application configuration
/// </summary>
public static void SaveToConfigNative(SegmentedOptions options)
public static void SaveToConfigNative(Options options)
{
// If no options path can be found
if (string.IsNullOrEmpty(ConfigurationPath))
@@ -256,7 +256,7 @@ namespace MPF.Frontend.Tools
using var sw = new StreamWriter(stream) { AutoFlush = true };
var writer = new JsonTextWriter(sw) { Formatting = Formatting.Indented };
serializer.Serialize(writer, options, typeof(SegmentedOptions));
serializer.Serialize(writer, options, typeof(Options));
}
/// <summary>

View File

@@ -73,11 +73,11 @@ namespace MPF.Frontend.Tools
/// </summary>
/// <param name="basePath">Base output image path</param>
/// <param name="drive">Drive object representing the current drive</param>
/// <param name="options">SegmentedOptions object that determines what to scan</param>
/// <param name="options">Options object that determines what to scan</param>
/// <param name="progress">Optional progress callback</param>
public static async Task<Dictionary<string, List<string>>> RunCombinedProtectionScans(string basePath,
Drive? drive,
SegmentedOptions options,
Options options,
IProgress<ProtectionProgress>? protectionProgress = null)
{
// Setup the output protections dictionary
@@ -137,11 +137,11 @@ namespace MPF.Frontend.Tools
/// Run protection scan on a given path
/// </summary>
/// <param name="path">Path to scan for protection</param>
/// <param name="options">SegmentedOptions object that determines what to scan</param>
/// <param name="options">Options object that determines what to scan</param>
/// <param name="progress">Optional progress callback</param>
/// <returns>Set of all detected copy protections with an optional error string</returns>
public static async Task<Dictionary<string, List<string>>> RunProtectionScanOnPath(string path,
SegmentedOptions options,
Options options,
IProgress<ProtectionProgress>? progress = null)
{
#if NET40
@@ -173,11 +173,11 @@ namespace MPF.Frontend.Tools
/// Run protection scan on a disc image
/// </summary>
/// <param name="image">Image path to scan for protection</param>
/// <param name="options">SegmentedOptions object that determines what to scan</param>
/// <param name="options">Options object that determines what to scan</param>
/// <param name="progress">Optional progress callback</param>
/// <returns>Set of all detected copy protections with an optional error string</returns>
public static async Task<Dictionary<string, List<string>>> RunProtectionScanOnImage(string image,
SegmentedOptions options,
Options options,
IProgress<ProtectionProgress>? progress = null)
{
#if NET40

View File

@@ -37,7 +37,7 @@ namespace MPF.Frontend.Tools
/// <param name="drive">Drive object representing the current drive</param>
/// <param name="system">Currently selected system</param>
/// <param name="mediaType">Currently selected media type</param>
/// <param name="options">SegmentedOptions object representing user-defined options</param>
/// <param name="options">Options object representing user-defined options</param>
/// <param name="processor">Processor object representing how to process the outputs</param>
/// <param name="resultProgress">Optional result progress callback</param>
/// <param name="protectionProgress">Optional protection progress callback</param>
@@ -47,7 +47,7 @@ namespace MPF.Frontend.Tools
Drive? drive,
RedumpSystem? system,
MediaType? mediaType,
SegmentedOptions options,
Options options,
BaseProcessor processor,
IProgress<ResultEventArgs>? resultProgress = null,
IProgress<ProtectionProgress>? protectionProgress = null)
@@ -174,10 +174,10 @@ namespace MPF.Frontend.Tools
/// <summary>
/// Fill in a SubmissionInfo object from Redump, if possible
/// </summary>
/// <param name="options">SegmentedOptions object representing user-defined options</param>
/// <param name="options">Options object representing user-defined options</param>
/// <param name="info">Existing SubmissionInfo object to fill</param>
/// <param name="resultProgress">Optional result progress callback</param>
public static async Task<bool> FillFromRedump(SegmentedOptions options,
public static async Task<bool> FillFromRedump(Options options,
SubmissionInfo info,
IProgress<ResultEventArgs>? resultProgress = null)
{

View File

@@ -22,11 +22,11 @@ namespace MPF.Frontend.ViewModels
/// <summary>
/// Access to the current options
/// </summary>
public SegmentedOptions Options
public Options Options
{
get => _options;
}
private readonly SegmentedOptions _options;
private readonly Options _options;
/// <summary>
/// Indicates if SelectionChanged events can be executed

View File

@@ -16,11 +16,11 @@ namespace MPF.Frontend.ViewModels
/// <summary>
/// Access to the current options
/// </summary>
public SegmentedOptions Options
public Options Options
{
get => _options;
}
private readonly SegmentedOptions _options;
private readonly Options _options;
/// <summary>
/// Indicates if SelectionChanged events can be executed

View File

@@ -20,7 +20,7 @@ namespace MPF.Frontend.ViewModels
/// <summary>
/// Access to the current options
/// </summary>
public SegmentedOptions Options
public Options Options
{
get => _options;
set
@@ -29,7 +29,7 @@ namespace MPF.Frontend.ViewModels
OptionsLoader.SaveToConfig(_options);
}
}
private SegmentedOptions _options;
private Options _options;
/// <summary>
/// Indicates if SelectionChanged events can be executed
@@ -983,14 +983,14 @@ namespace MPF.Frontend.ViewModels
/// </summary>
/// <param name="savedSettings">Indicates if the settings were saved or not</param>
/// <param name="newOptions">Options representing the new, saved values</param>
public void UpdateOptions(bool savedSettings, SegmentedOptions? newOptions)
public void UpdateOptions(bool savedSettings, Options? newOptions)
{
// Get which options to save
var optionsToSave = savedSettings ? newOptions : Options;
// Ensure the first run flag is unset
var continuingOptions = new SegmentedOptions(optionsToSave) { FirstRun = false };
Options = new SegmentedOptions(continuingOptions);
var continuingOptions = new Options(optionsToSave) { FirstRun = false };
Options = new Options(continuingOptions);
// If settings were changed, reinitialize the UI
if (savedSettings)

View File

@@ -12,9 +12,9 @@ namespace MPF.Frontend.ViewModels
#region Fields
/// <summary>
/// Application-level SegmentedOptions object
/// Application-level Options object
/// </summary>
public SegmentedOptions Options { get; private set; }
public Options Options { get; private set; }
/// <summary>
/// SubmissionInfo object to fill and save
@@ -195,7 +195,7 @@ namespace MPF.Frontend.ViewModels
/// <summary>
/// Constructor
/// </summary>
public MediaInformationViewModel(SegmentedOptions options, SubmissionInfo? submissionInfo)
public MediaInformationViewModel(Options options, SubmissionInfo? submissionInfo)
{
Options = options;
SubmissionInfo = submissionInfo?.Clone() as SubmissionInfo ?? new SubmissionInfo();

View File

@@ -32,7 +32,7 @@ namespace MPF.Frontend.ViewModels
/// <summary>
/// Current set of options
/// </summary>
public SegmentedOptions Options { get; }
public Options Options { get; }
/// <summary>
/// Flag for if settings were saved or not
@@ -88,15 +88,15 @@ namespace MPF.Frontend.ViewModels
/// </summary>
public OptionsViewModel()
{
Options = new SegmentedOptions();
Options = new Options();
}
/// <summary>
/// Constructor for in-code
/// </summary>
public OptionsViewModel(SegmentedOptions baseOptions)
public OptionsViewModel(Options baseOptions)
{
Options = new SegmentedOptions(baseOptions);
Options = new Options(baseOptions);
}
#region Population

View File

@@ -128,9 +128,9 @@ namespace MPF.UI.Windows
/// <param name="options">Options set to pass to the information window</param>
/// <param name="submissionInfo">SubmissionInfo object to display and possibly change</param>
/// <returns>Dialog open result</returns>
public bool? ShowMediaInformationWindow(SegmentedOptions? options, ref SubmissionInfo? submissionInfo)
public bool? ShowMediaInformationWindow(Options? options, ref SubmissionInfo? submissionInfo)
{
var mediaInformationWindow = new MediaInformationWindow(options ?? new SegmentedOptions(), submissionInfo)
var mediaInformationWindow = new MediaInformationWindow(options ?? new Options(), submissionInfo)
{
Focusable = true,
Owner = this,

View File

@@ -406,13 +406,13 @@ namespace MPF.UI.Windows
/// <param name="options">Options set to pass to the information window</param>
/// <param name="submissionInfo">SubmissionInfo object to display and possibly change</param>
/// <returns>Dialog open result</returns>
public bool? ShowMediaInformationWindow(SegmentedOptions? options, ref SubmissionInfo? submissionInfo)
public bool? ShowMediaInformationWindow(Options? options, ref SubmissionInfo? submissionInfo)
{
if (options?.Processing?.ShowDiscEjectReminder == true)
CustomMessageBox.Show(this, (string)Application.Current.FindResource("EjectMessageString"),
(string)Application.Current.FindResource("EjectTitleString"), MessageBoxButton.OK, MessageBoxImage.Information);
var mediaInformationWindow = new MediaInformationWindow(options ?? new SegmentedOptions(), submissionInfo)
var mediaInformationWindow = new MediaInformationWindow(options ?? new Options(), submissionInfo)
{
Focusable = true,
Owner = this,

View File

@@ -112,12 +112,12 @@ namespace MPF.UI.Windows
/// <summary>
/// Read-only access to the current media information view model
/// </summary>
public MediaInformationViewModel MediaInformationViewModel => DataContext as MediaInformationViewModel ?? new MediaInformationViewModel(new SegmentedOptions(), new SubmissionInfo());
public MediaInformationViewModel MediaInformationViewModel => DataContext as MediaInformationViewModel ?? new MediaInformationViewModel(new Options(), new SubmissionInfo());
/// <summary>
/// Constructor
/// </summary>
public MediaInformationWindow(SegmentedOptions options, SubmissionInfo? submissionInfo)
public MediaInformationWindow(Options options, SubmissionInfo? submissionInfo)
{
#if NET40_OR_GREATER || NETCOREAPP
InitializeComponent();
@@ -156,7 +156,7 @@ namespace MPF.UI.Windows
/// <summary>
/// Manipulate fields based on the current disc
/// </summary>
private void ManipulateFields(SegmentedOptions options, SubmissionInfo? submissionInfo)
private void ManipulateFields(Options options, SubmissionInfo? submissionInfo)
{
// Enable tabs in all fields, if required
if (options.Processing.MediaInformation.EnableTabsInInputFields)

View File

@@ -37,7 +37,7 @@ namespace MPF.UI.Windows
/// <summary>
/// Constructor
/// </summary>
public OptionsWindow(SegmentedOptions options)
public OptionsWindow(Options options)
{
#if NET40_OR_GREATER || NETCOREAPP
InitializeComponent();