From 3f3f73a56f65840aa7625145c5f10145d5c9e0c8 Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Sat, 4 Apr 2026 01:46:00 -0400 Subject: [PATCH] Convert Slot fully over to properties --- .../MetadataExtensions.cs | 2 + SabreTools.Data.Models/Metadata/Slot.cs | 42 +++++++++++++++---- .../DatFileTests.FromMetadata.cs | 6 +-- .../DatFileTests.ToMetadata.cs | 2 +- .../DatFile.Splitting.cs | 22 +++++----- SabreTools.Metadata.DatItems/Formats/Slot.cs | 27 ++++-------- .../DictionaryBaseExtensions.cs | 5 +++ .../Listxml.Deserializer.cs | 2 +- .../Listxml.Serializer.cs | 5 +-- 9 files changed, 64 insertions(+), 49 deletions(-) diff --git a/SabreTools.Data.Extensions/MetadataExtensions.cs b/SabreTools.Data.Extensions/MetadataExtensions.cs index a5740844..f5fb30cd 100644 --- a/SabreTools.Data.Extensions/MetadataExtensions.cs +++ b/SabreTools.Data.Extensions/MetadataExtensions.cs @@ -206,6 +206,8 @@ namespace SabreTools.Data.Extensions return serials.Clone() as Serials; else if (self is SharedFeat sharedFeat) return sharedFeat.Clone() as SharedFeat; + else if (self is Slot slot) + return slot.Clone() as Slot; else if (self is SlotOption slotOption) return slotOption.Clone() as SlotOption; else if (self is SoftwareList softwareList) diff --git a/SabreTools.Data.Models/Metadata/Slot.cs b/SabreTools.Data.Models/Metadata/Slot.cs index 5eb79f6a..605d7d42 100644 --- a/SabreTools.Data.Models/Metadata/Slot.cs +++ b/SabreTools.Data.Models/Metadata/Slot.cs @@ -1,25 +1,51 @@ +using System; using System.Xml.Serialization; using Newtonsoft.Json; namespace SabreTools.Data.Models.Metadata { [JsonObject("slot"), XmlRoot("slot")] - public class Slot : DatItem + public class Slot : DatItem, ICloneable, IEquatable { #region Properties public string? Name { get; set; } - #endregion - - #region Keys - - /// SlotOption[] - [NoFilter] - public const string SlotOptionKey = "slotoption"; + public SlotOption[]? SlotOption { get; set; } #endregion public Slot() => ItemType = ItemType.Slot; + + /// + public object Clone() + { + var obj = new Slot(); + + obj.Name = Name; + if (SlotOption is not null) + obj.SlotOption = Array.ConvertAll(SlotOption, i => (SlotOption)i.Clone()); + + return obj; + } + + /// + public bool Equals(Slot? other) + { + // Null never matches + if (other is null) + return false; + + // Properties + if ((Name is null) ^ (other.Name is null)) + return false; + else if (Name is not null && !Name.Equals(other.Name, StringComparison.OrdinalIgnoreCase)) + return false; + + // Sub-items + // 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 e6eb1785..ce8685b3 100644 --- a/SabreTools.Metadata.DatFiles.Test/DatFileTests.FromMetadata.cs +++ b/SabreTools.Metadata.DatFiles.Test/DatFileTests.FromMetadata.cs @@ -515,7 +515,7 @@ namespace SabreTools.Metadata.DatFiles.Test Default = true, DipLocation = [CreateMetadataDipLocation()], DipValue = [CreateMetadataDipValue()], - Entry = new string[] { "entry" }, + Entry = ["entry"], Mask = "mask", Name = "name", Tag = "tag", @@ -913,7 +913,7 @@ namespace SabreTools.Metadata.DatFiles.Test return new Data.Models.Metadata.Slot { Name = "name", - [Data.Models.Metadata.Slot.SlotOptionKey] = new Data.Models.Metadata.SlotOption[] { CreateMetadataSlotOption() }, + SlotOption = [CreateMetadataSlotOption()], }; } @@ -1624,7 +1624,7 @@ namespace SabreTools.Metadata.DatFiles.Test Assert.NotNull(slot); Assert.Equal("name", slot.Name); - SlotOption[]? slotOptions = slot.Read(Data.Models.Metadata.Slot.SlotOptionKey); + SlotOption[]? slotOptions = slot.SlotOption; Assert.NotNull(slotOptions); SlotOption? slotOption = Assert.Single(slotOptions); ValidateSlotOption(slotOption); diff --git a/SabreTools.Metadata.DatFiles.Test/DatFileTests.ToMetadata.cs b/SabreTools.Metadata.DatFiles.Test/DatFileTests.ToMetadata.cs index 16cbd3b4..b8899df2 100644 --- a/SabreTools.Metadata.DatFiles.Test/DatFileTests.ToMetadata.cs +++ b/SabreTools.Metadata.DatFiles.Test/DatFileTests.ToMetadata.cs @@ -1168,7 +1168,7 @@ namespace SabreTools.Metadata.DatFiles.Test Assert.NotNull(slot); Assert.Equal("name", slot.Name); - Data.Models.Metadata.SlotOption[]? slotOptions = slot.ReadArray(Data.Models.Metadata.Slot.SlotOptionKey); + Data.Models.Metadata.SlotOption[]? slotOptions = slot.SlotOption; Assert.NotNull(slotOptions); Data.Models.Metadata.SlotOption? slotOption = Assert.Single(slotOptions); ValidateMetadataSlotOption(slotOption); diff --git a/SabreTools.Metadata.DatFiles/DatFile.Splitting.cs b/SabreTools.Metadata.DatFiles/DatFile.Splitting.cs index 2bd079c9..2f179261 100644 --- a/SabreTools.Metadata.DatFiles/DatFile.Splitting.cs +++ b/SabreTools.Metadata.DatFiles/DatFile.Splitting.cs @@ -677,8 +677,8 @@ namespace SabreTools.Metadata.DatFiles slotOptions.UnionWith(datItems .FindAll(i => i is Slot) .ConvertAll(i => i as Slot) - .FindAll(s => s!.SlotOptionsSpecified) - .SelectMany(s => s!.Read(Data.Models.Metadata.Slot.SlotOptionKey)!) + .FindAll(s => s!.SlotOptionSpecified) + .SelectMany(s => s!.SlotOption!) .Select(so => so.DevName)); // If we're checking device references @@ -742,8 +742,8 @@ namespace SabreTools.Metadata.DatFiles newSlotOptions.UnionWith(slotItems .FindAll(i => i is Slot) - .FindAll(s => (s as Slot)!.SlotOptionsSpecified) - .SelectMany(s => (s as Slot)!.Read(Data.Models.Metadata.Slot.SlotOptionKey)!) + .FindAll(s => (s as Slot)!.SlotOptionSpecified) + .SelectMany(s => (s as Slot)!.SlotOption!) .Select(o => o.DevName!)); // Set new machine information and add to the current machine @@ -774,8 +774,7 @@ namespace SabreTools.Metadata.DatFiles var slotOptionItem = new SlotOption { DevName = slotOption }; slotOptionItem.CopyMachineInformation(copyFrom); - var slotItem = new Slot(); - slotItem.Write(Data.Models.Metadata.Slot.SlotOptionKey, [slotOptionItem]); + var slotItem = new Slot { SlotOption = [slotOptionItem] }; slotItem.CopyMachineInformation(copyFrom); Items.AddItem(slotItem, statsOnly: false); @@ -832,8 +831,8 @@ namespace SabreTools.Metadata.DatFiles List slotOptions = items.Values .Where(i => i is Slot) .Select(i => i as Slot) - .Where(s => s!.SlotOptionsSpecified) - .SelectMany(s => s!.Read(Data.Models.Metadata.Slot.SlotOptionKey)!) + .Where(s => s!.SlotOptionSpecified) + .SelectMany(s => s!.SlotOption!) .Select(so => so.DevName) .Distinct() .ToList(); @@ -910,8 +909,8 @@ namespace SabreTools.Metadata.DatFiles // Add to the list of new slot option names newSlotOptions.UnionWith(slotItems.Values .Where(i => i is Slot) - .Where(s => (s as Slot)!.SlotOptionsSpecified) - .SelectMany(s => (s as Slot)!.Read(Data.Models.Metadata.Slot.SlotOptionKey)!) + .Where(s => (s as Slot)!.SlotOptionSpecified) + .SelectMany(s => (s as Slot)!.SlotOption!) .Select(o => o.DevName!)); // Set new machine information and add to the current machine @@ -942,8 +941,7 @@ namespace SabreTools.Metadata.DatFiles { var slotOptionItem = new SlotOption { DevName = slotOption }; - var slotItem = new Slot(); - slotItem.Write(Data.Models.Metadata.Slot.SlotOptionKey, [slotOptionItem]); + var slotItem = new Slot { SlotOption = [slotOptionItem] }; ItemsDB.AddItem(slotItem, machine.Key, source.Key); } diff --git a/SabreTools.Metadata.DatItems/Formats/Slot.cs b/SabreTools.Metadata.DatItems/Formats/Slot.cs index 57ff8143..9051d991 100644 --- a/SabreTools.Metadata.DatItems/Formats/Slot.cs +++ b/SabreTools.Metadata.DatItems/Formats/Slot.cs @@ -23,15 +23,10 @@ namespace SabreTools.Metadata.DatItems.Formats set => (_internal as Data.Models.Metadata.Slot)?.Name = value; } + public SlotOption[]? SlotOption { get; set; } + [JsonIgnore] - public bool SlotOptionsSpecified - { - get - { - var slotOptions = Read(Data.Models.Metadata.Slot.SlotOptionKey); - return slotOptions is not null && slotOptions.Length > 0; - } - } + public bool SlotOptionSpecified => SlotOption is not null && SlotOption.Length > 0; #endregion @@ -42,12 +37,8 @@ namespace SabreTools.Metadata.DatItems.Formats public Slot(Data.Models.Metadata.Slot item) : base(item) { // Handle subitems - var slotOptions = item.ReadArray(Data.Models.Metadata.Slot.SlotOptionKey); - if (slotOptions is not null) - { - SlotOption[] slotOptionItems = Array.ConvertAll(slotOptions, slotOption => new SlotOption(slotOption)); - Write(Data.Models.Metadata.Slot.SlotOptionKey, slotOptionItems); - } + if (item.SlotOption is not null) + SlotOption = Array.ConvertAll(item.SlotOption, slotOption => new SlotOption(slotOption));; } public Slot(Data.Models.Metadata.Slot item, Machine machine, Source source) : this(item) @@ -68,12 +59,8 @@ namespace SabreTools.Metadata.DatItems.Formats { var slotItem = base.GetInternalClone(); - var slotOptions = Read(Data.Models.Metadata.Slot.SlotOptionKey); - if (slotOptions is not null) - { - Data.Models.Metadata.SlotOption[] slotOptionItems = Array.ConvertAll(slotOptions, slotOption => slotOption.GetInternalClone()); - slotItem[Data.Models.Metadata.Slot.SlotOptionKey] = slotOptionItems; - } + if (SlotOption is not null) + slotItem.SlotOption = Array.ConvertAll(SlotOption, slotOption => slotOption.GetInternalClone()); return slotItem; } diff --git a/SabreTools.Metadata/DictionaryBaseExtensions.cs b/SabreTools.Metadata/DictionaryBaseExtensions.cs index 97fbcfc1..d41e4054 100644 --- a/SabreTools.Metadata/DictionaryBaseExtensions.cs +++ b/SabreTools.Metadata/DictionaryBaseExtensions.cs @@ -393,6 +393,11 @@ namespace SabreTools.Metadata if (!selfSharedFeat.Equals(otherSharedFeat)) return false; } + else if (self is Slot selfSlot && other is Slot otherSlot) + { + if (!selfSlot.Equals(otherSlot)) + return false; + } else if (self is SlotOption selfSlotOption && other is SlotOption otherSlotOption) { if (!selfSlotOption.Equals(otherSlotOption)) diff --git a/SabreTools.Serialization.CrossModel/Listxml.Deserializer.cs b/SabreTools.Serialization.CrossModel/Listxml.Deserializer.cs index 63742f1a..8759cde4 100644 --- a/SabreTools.Serialization.CrossModel/Listxml.Deserializer.cs +++ b/SabreTools.Serialization.CrossModel/Listxml.Deserializer.cs @@ -597,7 +597,7 @@ namespace SabreTools.Serialization.CrossModel Name = item.Name, }; - var slotOptions = item.Read(Data.Models.Metadata.Slot.SlotOptionKey); + var slotOptions = item.SlotOption; if (slotOptions is not null && slotOptions.Length > 0) slot.SlotOption = Array.ConvertAll(slotOptions, ConvertFromInternalModel); diff --git a/SabreTools.Serialization.CrossModel/Listxml.Serializer.cs b/SabreTools.Serialization.CrossModel/Listxml.Serializer.cs index 7631b322..a1518e64 100644 --- a/SabreTools.Serialization.CrossModel/Listxml.Serializer.cs +++ b/SabreTools.Serialization.CrossModel/Listxml.Serializer.cs @@ -622,10 +622,7 @@ namespace SabreTools.Serialization.CrossModel }; if (item.SlotOption is not null && item.SlotOption.Length > 0) - { - slot[Data.Models.Metadata.Slot.SlotOptionKey] - = Array.ConvertAll(item.SlotOption, ConvertToInternalModel); - } + slot.SlotOption = Array.ConvertAll(item.SlotOption, ConvertToInternalModel); return slot; }