diff --git a/SabreTools.Data.Extensions/MetadataExtensions.cs b/SabreTools.Data.Extensions/MetadataExtensions.cs
index c94edef1..980fc1cb 100644
--- a/SabreTools.Data.Extensions/MetadataExtensions.cs
+++ b/SabreTools.Data.Extensions/MetadataExtensions.cs
@@ -73,6 +73,8 @@ namespace SabreTools.Data.Extensions
return input.Clone() as Input;
else if (self is Instance instance)
return instance.Clone() as Instance;
+ else if (self is Machine machine)
+ return machine.Clone() as Machine;
else if (self is Media media)
return media.Clone() as Media;
else if (self is Original original)
@@ -150,68 +152,6 @@ namespace SabreTools.Data.Extensions
cloneHeader.Url = selfHeader.Url;
cloneHeader.Version = selfHeader.Version;
}
- else if (self is Machine selfMachine && clone is Machine cloneMachine)
- {
- cloneMachine.Board = selfMachine.Board;
- cloneMachine.Buttons = selfMachine.Buttons;
- cloneMachine.CloneOf = selfMachine.CloneOf;
- cloneMachine.CloneOfId = selfMachine.CloneOfId;
- cloneMachine.Company = selfMachine.Company;
- cloneMachine.Control = selfMachine.Control;
- cloneMachine.Country = selfMachine.Country;
- cloneMachine.CRC = selfMachine.CRC;
- cloneMachine.Description = selfMachine.Description;
- cloneMachine.Developer = selfMachine.Developer;
- cloneMachine.DirName = selfMachine.DirName;
- cloneMachine.DisplayCount = selfMachine.DisplayCount;
- cloneMachine.DisplayType = selfMachine.DisplayType;
- cloneMachine.DuplicateID = selfMachine.DuplicateID;
- cloneMachine.Emulator = selfMachine.Emulator;
- cloneMachine.Enabled = selfMachine.Enabled;
- cloneMachine.Extra = selfMachine.Extra;
- cloneMachine.Favorite = selfMachine.Favorite;
- cloneMachine.GenMSXID = selfMachine.GenMSXID;
- cloneMachine.Genre = selfMachine.Genre;
- cloneMachine.Hash = selfMachine.Hash;
- cloneMachine.History = selfMachine.History;
- cloneMachine.Id = selfMachine.Id;
- cloneMachine.Im1CRC = selfMachine.Im1CRC;
- cloneMachine.Im2CRC = selfMachine.Im2CRC;
- cloneMachine.ImageNumber = selfMachine.ImageNumber;
- cloneMachine.IsBios = selfMachine.IsBios;
- cloneMachine.IsDevice = selfMachine.IsDevice;
- cloneMachine.IsMechanical = selfMachine.IsMechanical;
- cloneMachine.Language = selfMachine.Language;
- cloneMachine.Location = selfMachine.Location;
- cloneMachine.Manufacturer = selfMachine.Manufacturer;
- cloneMachine.Name = selfMachine.Name;
- cloneMachine.Notes = selfMachine.Notes;
- cloneMachine.PlayedCount = selfMachine.PlayedCount;
- cloneMachine.PlayedTime = selfMachine.PlayedTime;
- cloneMachine.Players = selfMachine.Players;
- cloneMachine.Publisher = selfMachine.Publisher;
- cloneMachine.Ratings = selfMachine.Ratings;
- cloneMachine.RebuildTo = selfMachine.RebuildTo;
- cloneMachine.RelatedTo = selfMachine.RelatedTo;
- cloneMachine.ReleaseNumber = selfMachine.ReleaseNumber;
- cloneMachine.RomOf = selfMachine.RomOf;
- cloneMachine.Rotation = selfMachine.Rotation;
- cloneMachine.Runnable = selfMachine.Runnable;
- cloneMachine.SampleOf = selfMachine.SampleOf;
- cloneMachine.SaveType = selfMachine.SaveType;
- cloneMachine.Score = selfMachine.Score;
- cloneMachine.Source = selfMachine.Source;
- cloneMachine.SourceFile = selfMachine.SourceFile;
- cloneMachine.SourceRom = selfMachine.SourceRom;
- cloneMachine.Status = selfMachine.Status;
- cloneMachine.Subgenre = selfMachine.Subgenre;
- cloneMachine.Supported = selfMachine.Supported;
- cloneMachine.System = selfMachine.System;
- cloneMachine.Tags = selfMachine.Tags;
- cloneMachine.TitleID = selfMachine.TitleID;
- cloneMachine.Url = selfMachine.Url;
- cloneMachine.Year = selfMachine.Year;
- }
// Loop through and clone per type
foreach (string key in self.Keys)
diff --git a/SabreTools.Data.Models/Metadata/Machine.cs b/SabreTools.Data.Models/Metadata/Machine.cs
index 72c78f16..6c4a3ecd 100644
--- a/SabreTools.Data.Models/Metadata/Machine.cs
+++ b/SabreTools.Data.Models/Metadata/Machine.cs
@@ -1,9 +1,11 @@
+using System;
+
namespace SabreTools.Data.Models.Metadata
{
///
/// Format-agnostic representation of game, machine, and set data
///
- public class Machine : DictionaryBase
+ public class Machine : DictionaryBase, ICloneable, IEquatable
{
#region Properties
@@ -17,12 +19,16 @@ namespace SabreTools.Data.Models.Metadata
public string? Buttons { get; set; }
+ public string[]? Category { get; set; }
+
public Chip[]? Chip { get; set; }
public string? CloneOf { get; set; }
public string? CloneOfId { get; set; }
+ public string[]? Comment { get; set; }
+
public string? Company { get; set; }
public Configuration[]? Configuration { get; set; }
@@ -186,14 +192,439 @@ namespace SabreTools.Data.Models.Metadata
#endregion
- #region Keys
+ ///
+ public object Clone()
+ {
+ var obj = new Machine();
- /// string, string[]
- public const string CategoryKey = "category";
+ if (Adjuster is not null)
+ obj.Adjuster = Array.ConvertAll(Adjuster, i => (Adjuster)i.Clone());
+ if (Archive is not null)
+ obj.Archive = Array.ConvertAll(Archive, i => (Archive)i.Clone());
+ if (BiosSet is not null)
+ obj.BiosSet = Array.ConvertAll(BiosSet, i => (BiosSet)i.Clone());
+ obj.Board = Board;
+ obj.Buttons = Buttons;
+ if (Category is not null)
+ obj.Category = Array.ConvertAll(Category, i => i);
+ if (Chip is not null)
+ obj.Chip = Array.ConvertAll(Chip, i => (Chip)i.Clone());
+ obj.CloneOf = CloneOf;
+ obj.CloneOfId = CloneOfId;
+ if (Comment is not null)
+ obj.Comment = Array.ConvertAll(Comment, i => i);
+ obj.Company = Company;
+ if (Configuration is not null)
+ obj.Configuration = Array.ConvertAll(Configuration, i => (Configuration)i.Clone());
+ obj.Control = Control;
+ obj.CRC = CRC;
+ obj.Country = Country;
+ obj.Description = Description;
+ obj.Developer = Developer;
+ if (Device is not null)
+ obj.Device = Array.ConvertAll(Device, i => (Device)i.Clone());
+ if (DeviceRef is not null)
+ obj.DeviceRef = Array.ConvertAll(DeviceRef, i => (DeviceRef)i.Clone());
+ if (DipSwitch is not null)
+ obj.DipSwitch = Array.ConvertAll(DipSwitch, i => (DipSwitch)i.Clone());
+ obj.DirName = DirName;
+ if (Disk is not null)
+ obj.Disk = Array.ConvertAll(Disk, i => (Disk)i.Clone());
+ if (Display is not null)
+ obj.Display = Array.ConvertAll(Display, i => (Display)i.Clone());
+ obj.DisplayCount = DisplayCount;
+ obj.DisplayType = DisplayType;
+ if (Driver is not null)
+ obj.Driver = (Driver)Driver.Clone();
+ if (Dump is not null)
+ obj.Dump = Array.ConvertAll(Dump, i => (Dump)i.Clone());
+ obj.DuplicateID = DuplicateID;
+ obj.Emulator = Emulator;
+ obj.Enabled = Enabled;
+ obj.Extra = Extra;
+ obj.Favorite = Favorite;
+ if (Feature is not null)
+ obj.Feature = Array.ConvertAll(Feature, i => (Feature)i.Clone());
+ obj.GenMSXID = GenMSXID;
+ obj.Genre = Genre;
+ obj.Hash = Hash;
+ obj.History = History;
+ obj.Id = Id;
+ obj.Im1CRC = Im1CRC;
+ obj.Im2CRC = Im2CRC;
+ obj.ImageNumber = ImageNumber;
+ if (Info is not null)
+ obj.Info = Array.ConvertAll(Info, i => (Info)i.Clone());
+ if (Input is not null)
+ obj.Input = (Input)Input.Clone();
+ obj.IsBios = IsBios;
+ obj.IsDevice = IsDevice;
+ obj.IsMechanical = IsMechanical;
+ obj.Language = Language;
+ obj.Location = Location;
+ obj.Manufacturer = Manufacturer;
+ if (Media is not null)
+ obj.Media = Array.ConvertAll(Media, i => (Media)i.Clone());
+ obj.Name = Name;
+ obj.Notes = Notes;
+ if (Part is not null)
+ obj.Part = Array.ConvertAll(Part, i => (Part)i.Clone());
+ obj.PlayedCount = PlayedCount;
+ obj.PlayedTime = PlayedTime;
+ obj.Players = Players;
+ if (Port is not null)
+ obj.Port = Array.ConvertAll(Port, i => (Port)i.Clone());
+ obj.Publisher = Publisher;
+ if (RamOption is not null)
+ obj.RamOption = Array.ConvertAll(RamOption, i => (RamOption)i.Clone());
+ obj.Ratings = Ratings;
+ obj.RebuildTo = RebuildTo;
+ obj.RelatedTo = RelatedTo;
+ if (Release is not null)
+ obj.Release = Array.ConvertAll(Release, i => (Release)i.Clone());
+ obj.ReleaseNumber = ReleaseNumber;
+ if (Rom is not null)
+ obj.Rom = Array.ConvertAll(Rom, i => (Rom)i.Clone());
+ obj.RomOf = RomOf;
+ obj.Rotation = Rotation;
+ obj.Runnable = Runnable;
+ if (Sample is not null)
+ obj.Sample = Array.ConvertAll(Sample, i => (Sample)i.Clone());
+ obj.SampleOf = SampleOf;
+ obj.SaveType = SaveType;
+ obj.Score = Score;
+ if (SharedFeat is not null)
+ obj.SharedFeat = Array.ConvertAll(SharedFeat, i => (SharedFeat)i.Clone());
+ if (Slot is not null)
+ obj.Slot = Array.ConvertAll(Slot, i => (Slot)i.Clone());
+ if (SoftwareList is not null)
+ obj.SoftwareList = Array.ConvertAll(SoftwareList, i => (SoftwareList)i.Clone());
+ if (Sound is not null)
+ obj.Sound = (Sound)Sound.Clone();
+ obj.Source = Source;
+ obj.SourceFile = SourceFile;
+ obj.SourceRom = SourceRom;
+ obj.Status = Status;
+ obj.Subgenre = Subgenre;
+ obj.Supported = Supported;
+ obj.System = System;
+ obj.Tags = Tags;
+ obj.TitleID = TitleID;
+ obj.Url = Url;
+ if (Video is not null)
+ obj.Video = Array.ConvertAll(Video, i => (Video)i.Clone());
+ obj.Year = Year;
- /// string, string[]
- public const string CommentKey = "comment";
+ return obj;
+ }
- #endregion
+ ///
+ public bool Equals(Machine? other)
+ {
+ // Null never matches
+ if (other is null)
+ return false;
+
+ // Properties
+ if ((Board is null) ^ (other.Board is null))
+ return false;
+ else if (Board is not null && !Board.Equals(other.Board, StringComparison.OrdinalIgnoreCase))
+ return false;
+
+ if ((Buttons is null) ^ (other.Buttons is null))
+ return false;
+ else if (Buttons is not null && !Buttons.Equals(other.Buttons, StringComparison.OrdinalIgnoreCase))
+ return false;
+
+ if ((CloneOf is null) ^ (other.CloneOf is null))
+ return false;
+ else if (CloneOf is not null && !CloneOf.Equals(other.CloneOf, StringComparison.OrdinalIgnoreCase))
+ return false;
+
+ if ((CloneOfId is null) ^ (other.CloneOfId is null))
+ return false;
+ else if (CloneOfId is not null && !CloneOfId.Equals(other.CloneOfId, StringComparison.OrdinalIgnoreCase))
+ return false;
+
+ if ((Company is null) ^ (other.Company is null))
+ return false;
+ else if (Company is not null && !Company.Equals(other.Company, StringComparison.OrdinalIgnoreCase))
+ return false;
+
+ if ((Control is null) ^ (other.Control is null))
+ return false;
+ else if (Control is not null && !Control.Equals(other.Control, StringComparison.OrdinalIgnoreCase))
+ return false;
+
+ if ((CRC is null) ^ (other.CRC is null))
+ return false;
+ else if (CRC is not null && !CRC.Equals(other.CRC, StringComparison.OrdinalIgnoreCase))
+ return false;
+
+ if ((Country is null) ^ (other.Country is null))
+ return false;
+ else if (Country is not null && !Country.Equals(other.Country, StringComparison.OrdinalIgnoreCase))
+ return false;
+
+ if ((Description is null) ^ (other.Description is null))
+ return false;
+ else if (Description is not null && !Description.Equals(other.Description, StringComparison.OrdinalIgnoreCase))
+ return false;
+
+ if ((Developer is null) ^ (other.Developer is null))
+ return false;
+ else if (Developer is not null && !Developer.Equals(other.Developer, StringComparison.OrdinalIgnoreCase))
+ return false;
+
+ if ((DirName is null) ^ (other.DirName is null))
+ return false;
+ else if (DirName is not null && !DirName.Equals(other.DirName, StringComparison.OrdinalIgnoreCase))
+ return false;
+
+ if ((DisplayCount is null) ^ (other.DisplayCount is null))
+ return false;
+ else if (DisplayCount is not null && !DisplayCount.Equals(other.DisplayCount, StringComparison.OrdinalIgnoreCase))
+ return false;
+
+ if ((DisplayType is null) ^ (other.DisplayType is null))
+ return false;
+ else if (DisplayType is not null && !DisplayType.Equals(other.DisplayType, StringComparison.OrdinalIgnoreCase))
+ return false;
+
+ if ((DuplicateID is null) ^ (other.DuplicateID is null))
+ return false;
+ else if (DuplicateID is not null && !DuplicateID.Equals(other.DuplicateID, StringComparison.OrdinalIgnoreCase))
+ return false;
+
+ if ((Emulator is null) ^ (other.Emulator is null))
+ return false;
+ else if (Emulator is not null && !Emulator.Equals(other.Emulator, StringComparison.OrdinalIgnoreCase))
+ return false;
+
+ if ((Enabled is null) ^ (other.Enabled is null))
+ return false;
+ else if (Enabled is not null && !Enabled.Equals(other.Enabled, StringComparison.OrdinalIgnoreCase))
+ return false;
+
+ if ((Extra is null) ^ (other.Extra is null))
+ return false;
+ else if (Extra is not null && !Extra.Equals(other.Extra, StringComparison.OrdinalIgnoreCase))
+ return false;
+
+ if ((Favorite is null) ^ (other.Favorite is null))
+ return false;
+ else if (Favorite is not null && !Favorite.Equals(other.Favorite, StringComparison.OrdinalIgnoreCase))
+ return false;
+
+ if ((GenMSXID is null) ^ (other.GenMSXID is null))
+ return false;
+ else if (GenMSXID is not null && !GenMSXID.Equals(other.GenMSXID, StringComparison.OrdinalIgnoreCase))
+ return false;
+
+ if ((Genre is null) ^ (other.Genre is null))
+ return false;
+ else if (Genre is not null && !Genre.Equals(other.Genre, StringComparison.OrdinalIgnoreCase))
+ return false;
+
+ if ((Hash is null) ^ (other.Hash is null))
+ return false;
+ else if (Hash is not null && !Hash.Equals(other.Hash, StringComparison.OrdinalIgnoreCase))
+ return false;
+
+ if ((History is null) ^ (other.History is null))
+ return false;
+ else if (History is not null && !History.Equals(other.History, StringComparison.OrdinalIgnoreCase))
+ return false;
+
+ if ((Id is null) ^ (other.Id is null))
+ return false;
+ else if (Id is not null && !Id.Equals(other.Id, StringComparison.OrdinalIgnoreCase))
+ return false;
+
+ if ((Im1CRC is null) ^ (other.Im1CRC is null))
+ return false;
+ else if (Im1CRC is not null && !Im1CRC.Equals(other.Im1CRC, StringComparison.OrdinalIgnoreCase))
+ return false;
+
+ if ((Im2CRC is null) ^ (other.Im2CRC is null))
+ return false;
+ else if (Im2CRC is not null && !Im2CRC.Equals(other.Im2CRC, StringComparison.OrdinalIgnoreCase))
+ return false;
+
+ if ((ImageNumber is null) ^ (other.ImageNumber is null))
+ return false;
+ else if (ImageNumber is not null && !ImageNumber.Equals(other.ImageNumber, StringComparison.OrdinalIgnoreCase))
+ return false;
+
+ if (IsBios != other.IsBios)
+ return false;
+
+ if (IsDevice != other.IsDevice)
+ return false;
+
+ if (IsMechanical != other.IsMechanical)
+ return false;
+
+ if ((Language is null) ^ (other.Language is null))
+ return false;
+ else if (Language is not null && !Language.Equals(other.Language, StringComparison.OrdinalIgnoreCase))
+ return false;
+
+ if ((Location is null) ^ (other.Location is null))
+ return false;
+ else if (Location is not null && !Location.Equals(other.Location, StringComparison.OrdinalIgnoreCase))
+ return false;
+
+ if ((Manufacturer is null) ^ (other.Manufacturer is null))
+ return false;
+ else if (Manufacturer is not null && !Manufacturer.Equals(other.Manufacturer, StringComparison.OrdinalIgnoreCase))
+ return false;
+
+ if ((Notes is null) ^ (other.Notes is null))
+ return false;
+ else if (Notes is not null && !Notes.Equals(other.Notes, StringComparison.OrdinalIgnoreCase))
+ return false;
+
+ if ((PlayedCount is null) ^ (other.PlayedCount is null))
+ return false;
+ else if (PlayedCount is not null && !PlayedCount.Equals(other.PlayedCount, StringComparison.OrdinalIgnoreCase))
+ return false;
+
+ if ((PlayedTime is null) ^ (other.PlayedTime is null))
+ return false;
+ else if (PlayedTime is not null && !PlayedTime.Equals(other.PlayedTime, StringComparison.OrdinalIgnoreCase))
+ return false;
+
+ if ((Players is null) ^ (other.Players is null))
+ return false;
+ else if (Players is not null && !Players.Equals(other.Players, StringComparison.OrdinalIgnoreCase))
+ return false;
+
+ if ((Publisher is null) ^ (other.Publisher is null))
+ return false;
+ else if (Publisher is not null && !Publisher.Equals(other.Publisher, StringComparison.OrdinalIgnoreCase))
+ return false;
+
+ if ((Ratings is null) ^ (other.Ratings is null))
+ return false;
+ else if (Ratings is not null && !Ratings.Equals(other.Ratings, StringComparison.OrdinalIgnoreCase))
+ return false;
+
+ if ((RebuildTo is null) ^ (other.RebuildTo is null))
+ return false;
+ else if (RebuildTo is not null && !RebuildTo.Equals(other.RebuildTo, StringComparison.OrdinalIgnoreCase))
+ return false;
+
+ if ((RelatedTo is null) ^ (other.RelatedTo is null))
+ return false;
+ else if (RelatedTo is not null && !RelatedTo.Equals(other.RelatedTo, StringComparison.OrdinalIgnoreCase))
+ return false;
+
+ if ((ReleaseNumber is null) ^ (other.ReleaseNumber is null))
+ return false;
+ else if (ReleaseNumber is not null && !ReleaseNumber.Equals(other.ReleaseNumber, StringComparison.OrdinalIgnoreCase))
+ return false;
+
+ if ((RomOf is null) ^ (other.RomOf is null))
+ return false;
+ else if (RomOf is not null && !RomOf.Equals(other.RomOf, StringComparison.OrdinalIgnoreCase))
+ return false;
+
+ if ((Rotation is null) ^ (other.Rotation is null))
+ return false;
+ else if (Rotation is not null && !Rotation.Equals(other.Rotation, StringComparison.OrdinalIgnoreCase))
+ return false;
+
+ if (Runnable != other.Runnable)
+ return false;
+
+ if ((SampleOf is null) ^ (other.SampleOf is null))
+ return false;
+ else if (SampleOf is not null && !SampleOf.Equals(other.SampleOf, StringComparison.OrdinalIgnoreCase))
+ return false;
+
+ if ((SaveType is null) ^ (other.SaveType is null))
+ return false;
+ else if (SaveType is not null && !SaveType.Equals(other.SaveType, StringComparison.OrdinalIgnoreCase))
+ return false;
+
+ if ((Score is null) ^ (other.Score is null))
+ return false;
+ else if (Score is not null && !Score.Equals(other.Score, StringComparison.OrdinalIgnoreCase))
+ return false;
+
+ if ((Source is null) ^ (other.Source is null))
+ return false;
+ else if (Source is not null && !Source.Equals(other.Source, StringComparison.OrdinalIgnoreCase))
+ return false;
+
+ if ((SourceFile is null) ^ (other.SourceFile is null))
+ return false;
+ else if (SourceFile is not null && !SourceFile.Equals(other.SourceFile, StringComparison.OrdinalIgnoreCase))
+ return false;
+
+ if ((SourceRom is null) ^ (other.SourceRom is null))
+ return false;
+ else if (SourceRom is not null && !SourceRom.Equals(other.SourceRom, StringComparison.OrdinalIgnoreCase))
+ return false;
+
+ if ((Status is null) ^ (other.Status is null))
+ return false;
+ else if (Status is not null && !Status.Equals(other.Status, StringComparison.OrdinalIgnoreCase))
+ return false;
+
+ if ((Subgenre is null) ^ (other.Subgenre is null))
+ return false;
+ else if (Subgenre is not null && !Subgenre.Equals(other.Subgenre, StringComparison.OrdinalIgnoreCase))
+ return false;
+
+ if (Supported != other.Supported)
+ return false;
+
+ if ((System is null) ^ (other.System is null))
+ return false;
+ else if (System is not null && !System.Equals(other.System, StringComparison.OrdinalIgnoreCase))
+ return false;
+
+ if ((Tags is null) ^ (other.Tags is null))
+ return false;
+ else if (Tags is not null && !Tags.Equals(other.Tags, StringComparison.OrdinalIgnoreCase))
+ return false;
+
+ if ((TitleID is null) ^ (other.TitleID is null))
+ return false;
+ else if (TitleID is not null && !TitleID.Equals(other.TitleID, StringComparison.OrdinalIgnoreCase))
+ return false;
+
+ if ((Url is null) ^ (other.Url is null))
+ return false;
+ else if (Url is not null && !Url.Equals(other.Url, StringComparison.OrdinalIgnoreCase))
+ return false;
+
+ if ((Year is null) ^ (other.Year is null))
+ return false;
+ else if (Year is not null && !Year.Equals(other.Year, StringComparison.OrdinalIgnoreCase))
+ return false;
+
+ // Sub-items
+ if ((Driver is null) ^ (other.Driver is null))
+ return false;
+ else if (Driver is not null && other.Driver is not null && Driver.Equals(other.Driver))
+ return false;
+
+ if ((Input is null) ^ (other.Input is null))
+ return false;
+ else if (Input is not null && other.Input is not null && Input.Equals(other.Input))
+ return false;
+
+ if ((Sound is null) ^ (other.Sound is null))
+ return false;
+ else if (Sound is not null && other.Sound is not null && Sound.Equals(other.Sound))
+ return false;
+
+ // TODO: Figure out how to properly check arrays
+
+ return true;
+ }
}
}
diff --git a/SabreTools.Metadata.DatFiles.Test/DatFileTests.FromMetadata.cs b/SabreTools.Metadata.DatFiles.Test/DatFileTests.FromMetadata.cs
index a8d6e6fa..78ba90bc 100644
--- a/SabreTools.Metadata.DatFiles.Test/DatFileTests.FromMetadata.cs
+++ b/SabreTools.Metadata.DatFiles.Test/DatFileTests.FromMetadata.cs
@@ -255,11 +255,11 @@ namespace SabreTools.Metadata.DatFiles.Test
BiosSet = [CreateMetadataBiosSet()],
Board = "board",
Buttons = "buttons",
- [Data.Models.Metadata.Machine.CategoryKey] = "category",
+ Category = ["category"],
Chip = [CreateMetadataChip()],
CloneOf = "cloneof",
CloneOfId = "cloneofid",
- [Data.Models.Metadata.Machine.CommentKey] = "comment",
+ Comment = ["comment"],
Company = "company",
Configuration = [CreateMetadataConfiguration()],
Control = "control",
@@ -1057,10 +1057,8 @@ namespace SabreTools.Metadata.DatFiles.Test
{
Assert.Equal("board", machine.Board);
Assert.Equal("buttons", machine.Buttons);
- Assert.Equal("category", machine.ReadString(Data.Models.Metadata.Machine.CategoryKey));
Assert.Equal("cloneof", machine.CloneOf);
Assert.Equal("cloneofid", machine.CloneOfId);
- Assert.Equal("comment", machine.ReadString(Data.Models.Metadata.Machine.CommentKey));
Assert.Equal("company", machine.Company);
Assert.Equal("control", machine.Control);
Assert.Equal("country", machine.Country);
@@ -1114,6 +1112,16 @@ namespace SabreTools.Metadata.DatFiles.Test
Assert.Equal("tags", machine.Tags);
Assert.Equal("titleid", machine.TitleID);
Assert.Equal("year", machine.Year);
+
+ string[]? categories = machine.Category;
+ Assert.NotNull(categories);
+ string? category = Assert.Single(categories);
+ Assert.Equal("category", category);
+
+ string[]? comments = machine.Comment;
+ Assert.NotNull(comments);
+ string? comment = Assert.Single(comments);
+ Assert.Equal("comment", comment);
}
#pragma warning restore IDE0051
diff --git a/SabreTools.Metadata.DatFiles.Test/DatFileTests.ToMetadata.cs b/SabreTools.Metadata.DatFiles.Test/DatFileTests.ToMetadata.cs
index c7fc5e49..5b9af6fe 100644
--- a/SabreTools.Metadata.DatFiles.Test/DatFileTests.ToMetadata.cs
+++ b/SabreTools.Metadata.DatFiles.Test/DatFileTests.ToMetadata.cs
@@ -401,10 +401,8 @@ namespace SabreTools.Metadata.DatFiles.Test
{
Assert.Equal("board", machine.Board);
Assert.Equal("buttons", machine.Buttons);
- Assert.Equal("category", machine.ReadString(Data.Models.Metadata.Machine.CategoryKey));
Assert.Equal("cloneof", machine.CloneOf);
Assert.Equal("cloneofid", machine.CloneOfId);
- Assert.Equal("comment", machine.ReadString(Data.Models.Metadata.Machine.CommentKey));
Assert.Equal("company", machine.Company);
Assert.Equal("control", machine.Control);
Assert.Equal("country", machine.Country);
@@ -474,11 +472,21 @@ namespace SabreTools.Metadata.DatFiles.Test
Data.Models.Metadata.BiosSet biosSet = Assert.Single(biosSets);
ValidateMetadataBiosSet(biosSet);
+ string[]? categories = machine.Category;
+ Assert.NotNull(categories);
+ string? category = Assert.Single(categories);
+ Assert.Equal("category", category);
+
Data.Models.Metadata.Chip[]? chips = machine.Chip;
Assert.NotNull(chips);
Data.Models.Metadata.Chip chip = Assert.Single(chips);
ValidateMetadataChip(chip);
+ string[]? comments = machine.Comment;
+ Assert.NotNull(comments);
+ string? comment = Assert.Single(comments);
+ Assert.Equal("comment", comment);
+
Data.Models.Metadata.Configuration[]? configurations = machine.Configuration;
Assert.NotNull(configurations);
Data.Models.Metadata.Configuration configuration = Assert.Single(configurations);
diff --git a/SabreTools.Metadata.DatFiles.Test/DatFileTests.cs b/SabreTools.Metadata.DatFiles.Test/DatFileTests.cs
index 235002b2..954dd0b8 100644
--- a/SabreTools.Metadata.DatFiles.Test/DatFileTests.cs
+++ b/SabreTools.Metadata.DatFiles.Test/DatFileTests.cs
@@ -1361,11 +1361,11 @@ namespace SabreTools.Metadata.DatFiles.Test
Machine machine = new Machine
{
- Name = "machine",
+ Category = ["category"],
Manufacturer = "manufacturer",
- Publisher = "publisher"
+ Name = "machine",
+ Publisher = "publisher",
};
- machine.Write(Data.Models.Metadata.Machine.CategoryKey, "category");
DatItem item = new Rom
{
@@ -1398,11 +1398,11 @@ namespace SabreTools.Metadata.DatFiles.Test
Machine machine = new Machine
{
- Name = "machine",
+ Category = ["category"],
Manufacturer = "manufacturer",
+ Name = "machine",
Publisher = "publisher"
};
- machine.Write(Data.Models.Metadata.Machine.CategoryKey, "category");
DatItem item = new Disk
{
@@ -1423,11 +1423,11 @@ namespace SabreTools.Metadata.DatFiles.Test
Machine machine = new Machine
{
- Name = "machine",
+ Category = ["category"],
Manufacturer = "manufacturer",
+ Name = "machine",
Publisher = "publisher"
};
- machine.Write(Data.Models.Metadata.Machine.CategoryKey, "category");
DatItem item = new DatItems.Formats.File
{
@@ -1452,11 +1452,11 @@ namespace SabreTools.Metadata.DatFiles.Test
Machine machine = new Machine
{
- Name = "machine",
+ Category = ["category"],
Manufacturer = "manufacturer",
+ Name = "machine",
Publisher = "publisher"
};
- machine.Write(Data.Models.Metadata.Machine.CategoryKey, "category");
DatItem item = new Media
{
@@ -1479,11 +1479,11 @@ namespace SabreTools.Metadata.DatFiles.Test
Machine machine = new Machine
{
- Name = "machine",
+ Category = ["category"],
Manufacturer = "manufacturer",
+ Name = "machine",
Publisher = "publisher"
};
- machine.Write(Data.Models.Metadata.Machine.CategoryKey, "category");
DatItem item = new Rom
{
diff --git a/SabreTools.Metadata.DatFiles/DatFile.FromMetadata.cs b/SabreTools.Metadata.DatFiles/DatFile.FromMetadata.cs
index cd06ac80..a9781137 100644
--- a/SabreTools.Metadata.DatFiles/DatFile.FromMetadata.cs
+++ b/SabreTools.Metadata.DatFiles/DatFile.FromMetadata.cs
@@ -225,7 +225,7 @@ namespace SabreTools.Metadata.DatFiles
FilterRunner? filterRunner)
{
// If the machine is invalid, we can't do anything
- if (item is null || item.Count == 0)
+ if (item is null)
return;
// If the machine doesn't pass the filter
diff --git a/SabreTools.Metadata.DatFiles/DatFile.cs b/SabreTools.Metadata.DatFiles/DatFile.cs
index c3db7efd..b91b025f 100644
--- a/SabreTools.Metadata.DatFiles/DatFile.cs
+++ b/SabreTools.Metadata.DatFiles/DatFile.cs
@@ -576,7 +576,7 @@ namespace SabreTools.Metadata.DatFiles
game = machine?.Name ?? string.Empty,
manufacturer = machine?.Manufacturer ?? string.Empty,
publisher = machine?.Publisher ?? string.Empty,
- category = machine?.ReadString(Data.Models.Metadata.Machine.CategoryKey) ?? string.Empty,
+ category = machine?.Category is null ? string.Empty : string.Join(", ", machine.Category),
name = item.GetName() ?? type.AsStringValue() ?? string.Empty,
crc16 = string.Empty,
crc = string.Empty,
diff --git a/SabreTools.Metadata.DatItems/Machine.cs b/SabreTools.Metadata.DatItems/Machine.cs
index 8d27e8c5..8ec8b66d 100644
--- a/SabreTools.Metadata.DatItems/Machine.cs
+++ b/SabreTools.Metadata.DatItems/Machine.cs
@@ -27,6 +27,12 @@ namespace SabreTools.Metadata.DatItems
set => _internal.Buttons = value;
}
+ public string[]? Category
+ {
+ get => _internal.Category;
+ set => _internal.Category = value;
+ }
+
public string? CloneOf
{
get => _internal.CloneOf;
@@ -39,6 +45,12 @@ namespace SabreTools.Metadata.DatItems
set => _internal.CloneOfId = value;
}
+ public string[]? Comment
+ {
+ get => _internal.Comment;
+ set => _internal.Comment = value;
+ }
+
public string? Company
{
get => _internal.Company;
@@ -380,7 +392,36 @@ namespace SabreTools.Metadata.DatItems
public Machine(Data.Models.Metadata.Machine machine)
{
- _internal = machine.DeepClone() as Data.Models.Metadata.Machine ?? [];
+ _internal = machine.Clone() as Data.Models.Metadata.Machine ?? [];
+
+ // Clear all lists
+ _internal.Adjuster = null;
+ _internal.Archive = null;
+ _internal.BiosSet = null;
+ _internal.Chip = null;
+ _internal.Configuration = null;
+ _internal.Device = null;
+ _internal.DeviceRef = null;
+ _internal.DipSwitch = null;
+ _internal.Disk = null;
+ _internal.Display = null;
+ _internal.Driver = null;
+ _internal.Dump = null;
+ _internal.Feature = null;
+ _internal.Info = null;
+ _internal.Input = null;
+ _internal.Media = null;
+ _internal.Part = null;
+ _internal.Port = null;
+ _internal.RamOption = null;
+ _internal.Release = null;
+ _internal.Rom = null;
+ _internal.Sample = null;
+ _internal.SharedFeat = null;
+ _internal.Slot = null;
+ _internal.SoftwareList = null;
+ _internal.Sound = null;
+ _internal.Video = null;
// Process flag values
if (Im1CRC is not null)
diff --git a/SabreTools.Metadata.Filter/FilterObject.cs b/SabreTools.Metadata.Filter/FilterObject.cs
index 349344aa..0bd83177 100644
--- a/SabreTools.Metadata.Filter/FilterObject.cs
+++ b/SabreTools.Metadata.Filter/FilterObject.cs
@@ -907,12 +907,18 @@ namespace SabreTools.Metadata.Filter
case Machine item when fieldName == "buttons":
checkValue = item.Buttons;
return true;
+ case Machine item when fieldName == "category":
+ checkValue = item.Category is null ? null : string.Join(", ", item.Category);
+ return true;
case Machine item when fieldName == "cloneof":
checkValue = item.CloneOf;
return true;
case Machine item when fieldName == "cloneofid":
checkValue = item.CloneOfId;
return true;
+ case Machine item when fieldName == "comment":
+ checkValue = item.Comment is null ? null : string.Join(", ", item.Comment);
+ return true;
case Machine item when fieldName == "company":
checkValue = item.Company;
return true;
diff --git a/SabreTools.Metadata/DictionaryBaseExtensions.cs b/SabreTools.Metadata/DictionaryBaseExtensions.cs
index caf91860..6c9941a2 100644
--- a/SabreTools.Metadata/DictionaryBaseExtensions.cs
+++ b/SabreTools.Metadata/DictionaryBaseExtensions.cs
@@ -48,6 +48,7 @@ namespace SabreTools.Metadata
(Info selfInfo, Info otherInfo) => selfInfo.Equals(otherInfo),
(Input selfInput, Input otherInput) => selfInput.Equals(otherInput),
(Instance selfInstance, Instance otherInstance) => selfInstance.Equals(otherInstance),
+ (Machine machineSelf, Machine machineOther) => EqualsImpl(machineSelf, machineOther),
(Media mediaSelf, Media mediaOther) => EqualsImpl(mediaSelf, mediaOther),
(Original selfOriginal, Original otherOriginal) => selfOriginal.Equals(otherOriginal),
(Part selfPart, Part otherPart) => selfPart.Equals(otherPart),
@@ -115,6 +116,8 @@ namespace SabreTools.Metadata
return selfInput.Equals(otherInput);
else if (self is Instance selfInstance && other is Instance otherInstance)
return selfInstance.Equals(otherInstance);
+ else if (self is Machine machineSelf && other is Machine machineOther)
+ return EqualsImpl(machineSelf, machineOther);
else if (self is Media mediaSelf && other is Media mediaOther)
return EqualsImpl(mediaSelf, mediaOther);
else if (self is Original selfOriginal && other is Original otherOriginal)
@@ -240,125 +243,6 @@ namespace SabreTools.Metadata
if (selfHeader.Version != otherHeader.Version)
return false;
}
- else if (self is Machine selfMachine && other is Machine otherMachine)
- {
- if (selfMachine.Board != otherMachine.Board)
- return false;
- if (selfMachine.Buttons != otherMachine.Buttons)
- return false;
- if (selfMachine.CloneOf != otherMachine.CloneOf)
- return false;
- if (selfMachine.CloneOfId != otherMachine.CloneOfId)
- return false;
- if (selfMachine.Company != otherMachine.Company)
- return false;
- if (selfMachine.Control != otherMachine.Control)
- return false;
- if (selfMachine.CRC != otherMachine.CRC)
- return false;
- if (selfMachine.Country != otherMachine.Country)
- return false;
- if (selfMachine.Description != otherMachine.Description)
- return false;
- if (selfMachine.Developer != otherMachine.Developer)
- return false;
- if (selfMachine.DirName != otherMachine.DirName)
- return false;
- if (selfMachine.DisplayCount != otherMachine.DisplayCount)
- return false;
- if (selfMachine.DisplayType != otherMachine.DisplayType)
- return false;
- if (selfMachine.DuplicateID != otherMachine.DuplicateID)
- return false;
- if (selfMachine.Emulator != otherMachine.Emulator)
- return false;
- if (selfMachine.Enabled != otherMachine.Enabled)
- return false;
- if (selfMachine.Extra != otherMachine.Extra)
- return false;
- if (selfMachine.Favorite != otherMachine.Favorite)
- return false;
- if (selfMachine.GenMSXID != otherMachine.GenMSXID)
- return false;
- if (selfMachine.Genre != otherMachine.Genre)
- return false;
- if (selfMachine.Hash != otherMachine.Hash)
- return false;
- if (selfMachine.History != otherMachine.History)
- return false;
- if (selfMachine.Id != otherMachine.Id)
- return false;
- if (selfMachine.Im1CRC != otherMachine.Im1CRC)
- return false;
- if (selfMachine.Im2CRC != otherMachine.Im2CRC)
- return false;
- if (selfMachine.ImageNumber != otherMachine.ImageNumber)
- return false;
- if (selfMachine.IsBios != otherMachine.IsBios)
- return false;
- if (selfMachine.IsDevice != otherMachine.IsDevice)
- return false;
- if (selfMachine.IsMechanical != otherMachine.IsMechanical)
- return false;
- if (selfMachine.Language != otherMachine.Language)
- return false;
- if (selfMachine.Location != otherMachine.Location)
- return false;
- if (selfMachine.Manufacturer != otherMachine.Manufacturer)
- return false;
- if (selfMachine.Notes != otherMachine.Notes)
- return false;
- if (selfMachine.PlayedCount != otherMachine.PlayedCount)
- return false;
- if (selfMachine.PlayedTime != otherMachine.PlayedTime)
- return false;
- if (selfMachine.Players != otherMachine.Players)
- return false;
- if (selfMachine.Publisher != otherMachine.Publisher)
- return false;
- if (selfMachine.Ratings != otherMachine.Ratings)
- return false;
- if (selfMachine.RebuildTo != otherMachine.RebuildTo)
- return false;
- if (selfMachine.RelatedTo != otherMachine.RelatedTo)
- return false;
- if (selfMachine.ReleaseNumber != otherMachine.ReleaseNumber)
- return false;
- if (selfMachine.RomOf != otherMachine.RomOf)
- return false;
- if (selfMachine.Rotation != otherMachine.Rotation)
- return false;
- if (selfMachine.Runnable != otherMachine.Runnable)
- return false;
- if (selfMachine.SampleOf != otherMachine.SampleOf)
- return false;
- if (selfMachine.SaveType != otherMachine.SaveType)
- return false;
- if (selfMachine.Score != otherMachine.Score)
- return false;
- if (selfMachine.Source != otherMachine.Source)
- return false;
- if (selfMachine.SourceFile != otherMachine.SourceFile)
- return false;
- if (selfMachine.SourceRom != otherMachine.SourceRom)
- return false;
- if (selfMachine.Status != otherMachine.Status)
- return false;
- if (selfMachine.Subgenre != otherMachine.Subgenre)
- return false;
- if (selfMachine.Supported != otherMachine.Supported)
- return false;
- if (selfMachine.System != otherMachine.System)
- return false;
- if (selfMachine.Tags != otherMachine.Tags)
- return false;
- if (selfMachine.TitleID != otherMachine.TitleID)
- return false;
- if (selfMachine.Url != otherMachine.Url)
- return false;
- if (selfMachine.Year != otherMachine.Year)
- return false;
- }
// Check all pairs to see if they're equal
foreach (var kvp in self)
diff --git a/SabreTools.Serialization.CrossModel/AttractMode.Deserializer.cs b/SabreTools.Serialization.CrossModel/AttractMode.Deserializer.cs
index 1c8f0dd4..c944385a 100644
--- a/SabreTools.Serialization.CrossModel/AttractMode.Deserializer.cs
+++ b/SabreTools.Serialization.CrossModel/AttractMode.Deserializer.cs
@@ -63,7 +63,7 @@ namespace SabreTools.Serialization.CrossModel
CloneOf = parent.CloneOf,
Year = parent.Year,
Manufacturer = parent.Manufacturer,
- Category = parent.ReadString(Data.Models.Metadata.Machine.CategoryKey),
+ Category = parent.Category is null ? null : string.Join(", ", parent.Category),
Players = parent.Players,
Rotation = parent.Rotation,
Control = parent.Control,
diff --git a/SabreTools.Serialization.CrossModel/AttractMode.Serializer.cs b/SabreTools.Serialization.CrossModel/AttractMode.Serializer.cs
index 94e7fad3..d6552156 100644
--- a/SabreTools.Serialization.CrossModel/AttractMode.Serializer.cs
+++ b/SabreTools.Serialization.CrossModel/AttractMode.Serializer.cs
@@ -52,7 +52,7 @@ namespace SabreTools.Serialization.CrossModel
CloneOf = item.CloneOf,
Year = item.Year,
Manufacturer = item.Manufacturer,
- [Data.Models.Metadata.Machine.CategoryKey] = item.Category,
+ Category = item.Category is null ? null : [item.Category],
Players = item.Players,
Rotation = item.Rotation,
Control = item.Control,
diff --git a/SabreTools.Serialization.CrossModel/ClrMamePro.Deserializer.cs b/SabreTools.Serialization.CrossModel/ClrMamePro.Deserializer.cs
index 61a4538f..baad81f6 100644
--- a/SabreTools.Serialization.CrossModel/ClrMamePro.Deserializer.cs
+++ b/SabreTools.Serialization.CrossModel/ClrMamePro.Deserializer.cs
@@ -74,7 +74,7 @@ namespace SabreTools.Serialization.CrossModel
// gameBase.DriverStatus = item.ReadString(Data.Models.Metadata.Machine.DriverKey); // TODO: Needs metadata mapping
gameBase.Year = item.Year;
gameBase.Manufacturer = item.Manufacturer;
- gameBase.Category = item.ReadString(Data.Models.Metadata.Machine.CategoryKey);
+ gameBase.Category = item.Category is null ? null : string.Join(", ", item.Category);
gameBase.CloneOf = item.CloneOf;
gameBase.RomOf = item.RomOf;
gameBase.SampleOf = item.SampleOf;
diff --git a/SabreTools.Serialization.CrossModel/ClrMamePro.Serializer.cs b/SabreTools.Serialization.CrossModel/ClrMamePro.Serializer.cs
index 450c50e2..e86a4523 100644
--- a/SabreTools.Serialization.CrossModel/ClrMamePro.Serializer.cs
+++ b/SabreTools.Serialization.CrossModel/ClrMamePro.Serializer.cs
@@ -69,7 +69,7 @@ namespace SabreTools.Serialization.CrossModel
// Driver = item.DriverStatus, // TODO: Needs metadata mapping
Year = item.Year,
Manufacturer = item.Manufacturer,
- [Data.Models.Metadata.Machine.CategoryKey] = item.Category,
+ Category = item.Category is null ? null : [item.Category],
CloneOf = item.CloneOf,
RomOf = item.RomOf,
SampleOf = item.SampleOf,
diff --git a/SabreTools.Serialization.CrossModel/Logiqx.Deserializer.cs b/SabreTools.Serialization.CrossModel/Logiqx.Deserializer.cs
index aeea4996..bd08976b 100644
--- a/SabreTools.Serialization.CrossModel/Logiqx.Deserializer.cs
+++ b/SabreTools.Serialization.CrossModel/Logiqx.Deserializer.cs
@@ -122,12 +122,12 @@ namespace SabreTools.Serialization.CrossModel
gameBase.Id = item.Id;
gameBase.CloneOfId = item.CloneOfId;
gameBase.Runnable = item.Runnable;
- gameBase.Comment = item.ReadStringArray(Data.Models.Metadata.Machine.CommentKey);
+ gameBase.Comment = item.Comment;
gameBase.Description = item.Description;
gameBase.Year = item.Year;
gameBase.Manufacturer = item.Manufacturer;
gameBase.Publisher = item.Publisher;
- gameBase.Category = item.ReadStringArray(Data.Models.Metadata.Machine.CategoryKey);
+ gameBase.Category = item.Category;
if (item.TitleID is not null
|| item.Developer is not null
diff --git a/SabreTools.Serialization.CrossModel/Logiqx.Serializer.cs b/SabreTools.Serialization.CrossModel/Logiqx.Serializer.cs
index 45e4f08d..171d0ad3 100644
--- a/SabreTools.Serialization.CrossModel/Logiqx.Serializer.cs
+++ b/SabreTools.Serialization.CrossModel/Logiqx.Serializer.cs
@@ -127,10 +127,10 @@ namespace SabreTools.Serialization.CrossModel
var machine = new Data.Models.Metadata.Machine
{
Board = item.Board,
- [Data.Models.Metadata.Machine.CategoryKey] = item.Category,
+ Category = item.Category,
CloneOf = item.CloneOf ?? item.Trurip?.CloneOf,
CloneOfId = item.CloneOfId,
- [Data.Models.Metadata.Machine.CommentKey] = item.Comment,
+ Comment = item.Comment,
CRC = item.Trurip?.CRC,
Description = item.Description,
Developer = item.Trurip?.Developer,
diff --git a/SabreTools.Serialization.CrossModel/OfflineList.Deserializer.cs b/SabreTools.Serialization.CrossModel/OfflineList.Deserializer.cs
index b5d88416..02efd5fe 100644
--- a/SabreTools.Serialization.CrossModel/OfflineList.Deserializer.cs
+++ b/SabreTools.Serialization.CrossModel/OfflineList.Deserializer.cs
@@ -92,7 +92,7 @@ namespace SabreTools.Serialization.CrossModel
Language = item.Language,
Im1CRC = item.Im1CRC,
Im2CRC = item.Im2CRC,
- Comment = item.ReadString(Data.Models.Metadata.Machine.CommentKey),
+ Comment = item.Comment is null ? null : string.Join(", ", item.Comment),
DuplicateID = item.DuplicateID,
};
diff --git a/SabreTools.Serialization.CrossModel/OfflineList.Serializer.cs b/SabreTools.Serialization.CrossModel/OfflineList.Serializer.cs
index d808522d..ac4e12da 100644
--- a/SabreTools.Serialization.CrossModel/OfflineList.Serializer.cs
+++ b/SabreTools.Serialization.CrossModel/OfflineList.Serializer.cs
@@ -75,7 +75,7 @@ namespace SabreTools.Serialization.CrossModel
Language = item.Language,
Im1CRC = item.Im1CRC,
Im2CRC = item.Im2CRC,
- [Data.Models.Metadata.Machine.CommentKey] = item.Comment,
+ Comment = item.Comment is null ? null : [item.Comment],
DuplicateID = item.DuplicateID,
};