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, };