Convert Input fully over to properties

This commit is contained in:
Matt Nadareski
2026-04-04 01:28:17 -04:00
parent 9ffa2a5e23
commit 9e721c5c43
11 changed files with 94 additions and 71 deletions

View File

@@ -186,8 +186,12 @@ namespace SabreTools.Data.Extensions
// return feature.Clone() as Feature;
else if (self is Info info)
return info.Clone() as Info;
else if (self is Input input)
return input.Clone() as Input;
else if (self is Instance instance)
return instance.Clone() as Instance;
else if (self is Media media)
return media.Clone() as Media;
else if (self is Original original)
return original.Clone() as Original;
else if (self is RamOption ramOption)
@@ -272,15 +276,6 @@ namespace SabreTools.Data.Extensions
cloneHeader.Url = selfHeader.Url;
cloneHeader.Version = selfHeader.Version;
}
else if (self is Input selfInput && clone is Input cloneInput)
{
cloneInput.Buttons = selfInput.Buttons;
cloneInput.Coins = selfInput.Coins;
cloneInput.ControlAttr = selfInput.ControlAttr;
cloneInput.Players = selfInput.Players;
cloneInput.Service = selfInput.Service;
cloneInput.Tilt = selfInput.Tilt;
}
else if (self is Machine selfMachine && clone is Machine cloneMachine)
{
cloneMachine.Board = selfMachine.Board;
@@ -332,13 +327,6 @@ namespace SabreTools.Data.Extensions
cloneMachine.Url = selfMachine.Url;
cloneMachine.Year = selfMachine.Year;
}
else if (self is Media selfMedia && clone is Media cloneMedia)
{
cloneMedia.MD5 = selfMedia.MD5;
cloneMedia.SHA1 = selfMedia.SHA1;
cloneMedia.SHA256 = selfMedia.SHA256;
cloneMedia.SpamSum = selfMedia.SpamSum;
}
else if (self is Part selfPart && clone is Part clonePart)
{
clonePart.Interface = selfPart.Interface;

View File

@@ -1,10 +1,11 @@
using System;
using System.Xml.Serialization;
using Newtonsoft.Json;
namespace SabreTools.Data.Models.Metadata
{
[JsonObject("input"), XmlRoot("input")]
public class Input : DatItem
public class Input : DatItem, ICloneable, IEquatable<Input>
{
#region Properties
@@ -12,6 +13,8 @@ namespace SabreTools.Data.Models.Metadata
public long? Coins { get; set; }
public Control[]? Control { get; set; }
/// <remarks>Attribute also named Control</remarks>
public string? ControlAttr { get; set; }
@@ -25,13 +28,57 @@ namespace SabreTools.Data.Models.Metadata
#endregion
#region Keys
/// <remarks>Control[]</remarks>
public const string ControlKey = "control";
#endregion
public Input() => ItemType = ItemType.Input;
/// <inheritdoc/>
public object Clone()
{
var obj = new Input();
obj.Buttons = Buttons;
obj.Coins = Coins;
if (Control is not null)
obj.Control = Array.ConvertAll(Control, i => (Control)i.Clone());
obj.ControlAttr = ControlAttr;
obj.Players = Players;
obj.Service = Service;
obj.Tilt = Tilt;
return obj;
}
/// <inheritdoc/>
public bool Equals(Input? other)
{
// Null never matches
if (other is null)
return false;
// Properties
if (Buttons != other.Buttons)
return false;
if (Coins != other.Coins)
return false;
if ((ControlAttr is null) ^ (other.ControlAttr is null))
return false;
else if (ControlAttr is not null && !ControlAttr.Equals(other.ControlAttr, StringComparison.OrdinalIgnoreCase))
return false;
if (Players != other.Players)
return false;
if (Service != other.Service)
return false;
if (Tilt != other.Tilt)
return false;
// Sub-items
// TODO: Figure out how to properly check arrays
return true;
}
}
}

View File

@@ -1,12 +1,12 @@
using System;
using System.Xml.Serialization;
using Newtonsoft.Json;
namespace SabreTools.Data.Models.Metadata
{
// TODO: ICloneable
// TODO: IEquatable
// TODO: IEquatable<Media>
[JsonObject("media"), XmlRoot("media")]
public class Media : DatItem
public class Media : DatItem, ICloneable
{
#region Properties
@@ -23,5 +23,19 @@ namespace SabreTools.Data.Models.Metadata
#endregion
public Media() => ItemType = ItemType.Media;
/// <inheritdoc/>
public object Clone()
{
var obj = new Media();
obj.MD5 = MD5;
obj.Name = Name;
obj.SHA1 = SHA1;
obj.SHA256 = SHA256;
obj.SpamSum = SpamSum;
return obj;
}
}
}

View File

@@ -662,7 +662,7 @@ namespace SabreTools.Metadata.DatFiles.Test
{
Buttons = 12345,
Coins = 12345,
[Data.Models.Metadata.Input.ControlKey] = new Data.Models.Metadata.Control[] { CreateMetadataControl() },
Control = [CreateMetadataControl()],
ControlAttr = "controlattr",
Players = 12345,
Service = true,
@@ -1393,7 +1393,7 @@ namespace SabreTools.Metadata.DatFiles.Test
Assert.True(input.Service);
Assert.True(input.Tilt);
Control[]? controls = input.Read<Control[]>(Data.Models.Metadata.Input.ControlKey);
Control[]? controls = input.Control;
Assert.NotNull(controls);
Control? control = Assert.Single(controls);
ValidateControl(control);

View File

@@ -930,7 +930,7 @@ namespace SabreTools.Metadata.DatFiles.Test
Assert.True(input.Service);
Assert.True(input.Tilt);
Data.Models.Metadata.Control[]? controls = input.ReadArray<Data.Models.Metadata.Control>(Data.Models.Metadata.Input.ControlKey);
Data.Models.Metadata.Control[]? controls = input.Control;
Assert.NotNull(controls);
Data.Models.Metadata.Control? control = Assert.Single(controls);
ValidateMetadataControl(control);

View File

@@ -230,7 +230,7 @@ namespace SabreTools.Metadata.DatFiles.Test
Assert.NotNull(actual);
Assert.True(actual.SequenceEqual([
nameof(Data.Models.Metadata.Input.Players),
Data.Models.Metadata.Input.ControlKey,
nameof(Data.Models.Metadata.Input.Control),
]));
}

View File

@@ -154,8 +154,8 @@ namespace SabreTools.Metadata.DatFiles.Formats
case Input input:
if (input.Players is null)
missingFields.Add(nameof(Data.Models.Metadata.Input.Players));
if (!input.ControlsSpecified)
missingFields.Add(Data.Models.Metadata.Input.ControlKey);
if (!input.ControlSpecified)
missingFields.Add(nameof(Data.Models.Metadata.Input.Control));
break;
case DipSwitch dipswitch:

View File

@@ -25,22 +25,17 @@ namespace SabreTools.Metadata.DatItems.Formats
set => (_internal as Data.Models.Metadata.Input)?.Coins = value;
}
public Control[]? Control { get; set; }
[JsonIgnore]
public bool ControlSpecified => Control is not null && Control.Length > 0;
public string? ControlAttr
{
get => (_internal as Data.Models.Metadata.Input)?.ControlAttr;
set => (_internal as Data.Models.Metadata.Input)?.ControlAttr = value;
}
[JsonIgnore]
public bool ControlsSpecified
{
get
{
var controls = Read<Control[]?>(Data.Models.Metadata.Input.ControlKey);
return controls is not null && controls.Length > 0;
}
}
/// <inheritdoc>/>
public override Data.Models.Metadata.ItemType ItemType
=> Data.Models.Metadata.ItemType.Input;
@@ -72,12 +67,8 @@ namespace SabreTools.Metadata.DatItems.Formats
public Input(Data.Models.Metadata.Input item) : base(item)
{
// Handle subitems
var controls = item.ReadArray<Data.Models.Metadata.Control>(Data.Models.Metadata.Input.ControlKey);
if (controls is not null)
{
Control[] controlItems = Array.ConvertAll(controls, control => new Control(control));
Write<Control[]?>(Data.Models.Metadata.Input.ControlKey, controlItems);
}
if (item.Control is not null)
Control = Array.ConvertAll(item.Control, control => new Control(control));
}
public Input(Data.Models.Metadata.Input item, Machine machine, Source source) : this(item)
@@ -98,12 +89,8 @@ namespace SabreTools.Metadata.DatItems.Formats
{
var inputItem = base.GetInternalClone();
var controls = Read<Control[]?>(Data.Models.Metadata.Input.ControlKey);
if (controls is not null)
{
Data.Models.Metadata.Control[] controlItems = Array.ConvertAll(controls, control => control.GetInternalClone());
inputItem[Data.Models.Metadata.Input.ControlKey] = controlItems;
}
if (Control is not null)
inputItem.Control = Array.ConvertAll(Control, control => control.GetInternalClone());
return inputItem;
}

View File

@@ -238,17 +238,7 @@ namespace SabreTools.Metadata
}
else if (self is Input selfInput && other is Input otherInput)
{
if (selfInput.Buttons != otherInput.Buttons)
return false;
if (selfInput.Coins != otherInput.Coins)
return false;
if (selfInput.ControlAttr != otherInput.ControlAttr)
return false;
if (selfInput.Players != otherInput.Players)
return false;
if (selfInput.Service != otherInput.Service)
return false;
if (selfInput.Tilt != otherInput.Tilt)
if (!selfInput.Equals(otherInput))
return false;
}
else if (self is Instance selfInstance && other is Instance otherInstance)

View File

@@ -504,7 +504,7 @@ namespace SabreTools.Serialization.CrossModel
Coins = item.Coins,
};
var controls = item.Read<Data.Models.Metadata.Control[]>(Data.Models.Metadata.Input.ControlKey);
var controls = item.Control;
if (controls is not null && controls.Length > 0)
input.Control = Array.ConvertAll(controls, ConvertFromInternalModel);

View File

@@ -528,10 +528,7 @@ namespace SabreTools.Serialization.CrossModel
};
if (item.Control is not null && item.Control.Length > 0)
{
input[Data.Models.Metadata.Input.ControlKey]
= Array.ConvertAll(item.Control, ConvertToInternalModel);
}
input.Control = Array.ConvertAll(item.Control, ConvertToInternalModel);
return input;
}