From c8c10659b1d633381a2e2a66f94a2b81c380046b Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Fri, 6 Dec 2024 23:16:09 -0500 Subject: [PATCH] Reduce unnecessary round-trip conversions --- SabreTools.Core/Filter/FilterRunner.cs | 2 +- SabreTools.Core/Tools/Utilities.cs | 2 +- SabreTools.DatFiles/DatFile.FromMetadata.cs | 20 +- SabreTools.DatFiles/DatFile.Removal.cs | 4 +- SabreTools.DatFiles/DatFile.ToMetadata.cs | 59 +- SabreTools.DatFiles/DatFile.cs | 140 +--- SabreTools.DatFiles/Formats/AttractMode.cs | 2 +- SabreTools.DatFiles/Formats/ClrMamePro.cs | 2 +- SabreTools.DatFiles/Formats/DosCenter.cs | 2 +- SabreTools.DatFiles/Formats/EverdriveSmdb.cs | 2 +- SabreTools.DatFiles/Formats/Hashfile.cs | 2 +- SabreTools.DatFiles/Formats/Listrom.cs | 2 +- SabreTools.DatFiles/Formats/Listxml.cs | 2 +- SabreTools.DatFiles/Formats/Logiqx.cs | 2 +- SabreTools.DatFiles/Formats/Missfile.cs | 39 +- SabreTools.DatFiles/Formats/OfflineList.cs | 2 +- SabreTools.DatFiles/Formats/OpenMSX.cs | 2 +- SabreTools.DatFiles/Formats/RomCenter.cs | 2 +- SabreTools.DatFiles/Formats/SabreJSON.cs | 88 +-- SabreTools.DatFiles/Formats/SabreXML.cs | 70 +- SabreTools.DatFiles/Formats/SeparatedValue.cs | 2 +- SabreTools.DatFiles/Formats/SoftwareList.cs | 2 +- SabreTools.DatFiles/ItemDictionary.cs | 38 +- SabreTools.DatFiles/ItemDictionaryDB.cs | 603 +++++++++--------- SabreTools.DatItems/DatItem.cs | 62 +- SabreTools.DatTools/Cleaner.cs | 22 +- SabreTools.DatTools/DatFileTool.cs | 104 +-- SabreTools.DatTools/ExtraIni.cs | 8 +- SabreTools.DatTools/Rebuilder.cs | 4 +- SabreTools.DatTools/Splitter.cs | 40 +- SabreTools.DatTools/Verification.cs | 13 +- SabreTools.DatTools/Writer.cs | 6 +- .../Archives/SevenZipArchive.cs | 4 +- SabreTools.FileTypes/Archives/ZipArchive.cs | 8 +- 34 files changed, 597 insertions(+), 765 deletions(-) diff --git a/SabreTools.Core/Filter/FilterRunner.cs b/SabreTools.Core/Filter/FilterRunner.cs index b091ec4c..b730d77b 100644 --- a/SabreTools.Core/Filter/FilterRunner.cs +++ b/SabreTools.Core/Filter/FilterRunner.cs @@ -22,7 +22,7 @@ namespace SabreTools.Core.Filter public FilterRunner(string[] filterStrings) { - var filters = new List(); + List filters = []; foreach (string filterString in filterStrings) { try diff --git a/SabreTools.Core/Tools/Utilities.cs b/SabreTools.Core/Tools/Utilities.cs index 0aa835ea..297dba94 100644 --- a/SabreTools.Core/Tools/Utilities.cs +++ b/SabreTools.Core/Tools/Utilities.cs @@ -25,7 +25,7 @@ namespace SabreTools.Core.Tools return false; // Otherwise, they need to match exactly - return Enumerable.SequenceEqual(firstHash, secondHash); + return firstHash.SequenceEqual(secondHash); } /// diff --git a/SabreTools.DatFiles/DatFile.FromMetadata.cs b/SabreTools.DatFiles/DatFile.FromMetadata.cs index e93ae2a7..66a24be1 100644 --- a/SabreTools.DatFiles/DatFile.FromMetadata.cs +++ b/SabreTools.DatFiles/DatFile.FromMetadata.cs @@ -537,7 +537,7 @@ namespace SabreTools.DatFiles var confLocations = ReadItemArray(item, Models.Metadata.Configuration.ConfLocationKey); if (confLocations != null) { - var subLocations = new List(); + List subLocations = []; foreach (var location in confLocations) { var subItem = new DatItems.Formats.ConfLocation(location); @@ -555,7 +555,7 @@ namespace SabreTools.DatFiles var confSettings = ReadItemArray(item, Models.Metadata.Configuration.ConfSettingKey); if (confSettings != null) { - var subValues = new List(); + List subValues = []; foreach (var setting in confSettings) { var subItem = new DatItems.Formats.ConfSetting(setting); @@ -626,7 +626,7 @@ namespace SabreTools.DatFiles var extensions = ReadItemArray(item, Models.Metadata.Device.ExtensionKey); if (extensions != null) { - var subExtensions = new List(); + List subExtensions = []; foreach (var extension in extensions) { var subItem = new DatItems.Formats.Extension(extension); @@ -709,7 +709,7 @@ namespace SabreTools.DatFiles var dipLocations = ReadItemArray(item, Models.Metadata.DipSwitch.DipLocationKey); if (dipLocations != null) { - var subLocations = new List(); + List subLocations = []; foreach (var location in dipLocations) { var subItem = new DatItems.Formats.DipLocation(location); @@ -727,7 +727,7 @@ namespace SabreTools.DatFiles var dipValues = ReadItemArray(item, Models.Metadata.DipSwitch.DipValueKey); if (dipValues != null) { - var subValues = new List(); + List subValues = []; foreach (var value in dipValues) { var subItem = new DatItems.Formats.DipValue(value); @@ -1093,7 +1093,7 @@ namespace SabreTools.DatFiles var controls = ReadItemArray(item, Models.Metadata.Input.ControlKey); if (controls != null) { - var subControls = new List(); + List subControls = []; foreach (var control in controls) { var subItem = new DatItems.Formats.Control(control); @@ -1319,7 +1319,7 @@ namespace SabreTools.DatFiles var dipLocations = ReadItemArray(dipSwitch, Models.Metadata.DipSwitch.DipLocationKey); if (dipLocations != null) { - var subLocations = new List(); + List subLocations = []; foreach (var location in dipLocations) { var subItem = new DatItems.Formats.DipLocation(location); @@ -1337,7 +1337,7 @@ namespace SabreTools.DatFiles var dipValues = ReadItemArray(dipSwitch, Models.Metadata.DipSwitch.DipValueKey); if (dipValues != null) { - var subValues = new List(); + List subValues = []; foreach (var value in dipValues) { var subItem = new DatItems.Formats.DipValue(value); @@ -1420,7 +1420,7 @@ namespace SabreTools.DatFiles var analogs = ReadItemArray(item, Models.Metadata.Port.AnalogKey); if (analogs != null) { - var subAnalogs = new List(); + List subAnalogs = []; foreach (var analog in analogs) { var subItem = new DatItems.Formats.Analog(analog); @@ -1636,7 +1636,7 @@ namespace SabreTools.DatFiles var slotOptions = ReadItemArray(item, Models.Metadata.Slot.SlotOptionKey); if (slotOptions != null) { - var subOptions = new List(); + List subOptions = []; foreach (var slotOption in slotOptions) { var subItem = new DatItems.Formats.SlotOption(slotOption); diff --git a/SabreTools.DatFiles/DatFile.Removal.cs b/SabreTools.DatFiles/DatFile.Removal.cs index b501e146..c34f2b90 100644 --- a/SabreTools.DatFiles/DatFile.Removal.cs +++ b/SabreTools.DatFiles/DatFile.Removal.cs @@ -82,9 +82,9 @@ namespace SabreTools.DatFiles continue; #endif - for (int j = 0; j < items.Length; j++) + foreach (var item in items.Values) { - RemoveFields(items[j].Item2, machineFieldNames, itemFieldNames); + RemoveFields(item, machineFieldNames, itemFieldNames); } #if NET40_OR_GREATER || NETCOREAPP }); diff --git a/SabreTools.DatFiles/DatFile.ToMetadata.cs b/SabreTools.DatFiles/DatFile.ToMetadata.cs index 6521d285..58f79f53 100644 --- a/SabreTools.DatFiles/DatFile.ToMetadata.cs +++ b/SabreTools.DatFiles/DatFile.ToMetadata.cs @@ -100,7 +100,7 @@ namespace SabreTools.DatFiles private Models.Metadata.Machine[]? ConvertMachines(bool ignoreblanks = false) { // Create a machine list to hold all outputs - var machines = new List(); + List machines = []; // Loop through the sorted items and create games for them foreach (string key in Items.SortedKeys) @@ -374,7 +374,7 @@ namespace SabreTools.DatFiles { // Get existing data areas as a list var dataAreasArr = partItems[partName].Read(Models.Metadata.Part.DataAreaKey) ?? []; - var dataAreas = new List(dataAreasArr); + List dataAreas = [.. dataAreasArr]; // Find the existing disk area to append to, otherwise create a new disk area int dataAreaIndex = dataAreas.FindIndex(da => da.ReadString(Models.Metadata.DataArea.NameKey) == dataAreaName); @@ -397,7 +397,7 @@ namespace SabreTools.DatFiles // Get existing roms as a list var romsArr = aggregateDataArea.Read(Models.Metadata.DataArea.RomKey) ?? []; - var roms = new List(romsArr); + List roms = [.. romsArr]; // Add the rom to the data area roms.Add(romItem); @@ -431,7 +431,7 @@ namespace SabreTools.DatFiles { // Get existing disk areas as a list var diskAreasArr = partItems[partName].Read(Models.Metadata.Part.DiskAreaKey) ?? []; - var diskAreas = new List(diskAreasArr); + List diskAreas = [.. diskAreasArr]; // Find the existing disk area to append to, otherwise create a new disk area int diskAreaIndex = diskAreas.FindIndex(da => da.ReadString(Models.Metadata.DiskArea.NameKey) == diskAreaName); @@ -451,7 +451,7 @@ namespace SabreTools.DatFiles // Get existing disks as a list var disksArr = aggregateDiskArea.Read(Models.Metadata.DiskArea.DiskKey) ?? []; - var disks = new List(disksArr); + List disks = [.. disksArr]; // Add the disk to the data area disks.Add(diskItem); @@ -475,7 +475,7 @@ namespace SabreTools.DatFiles { // Get existing dipswitches as a list var dipSwitchesArr = partItems[partName].Read(Models.Metadata.Part.DipSwitchKey) ?? []; - var dipSwitches = new List(dipSwitchesArr); + List dipSwitches = [.. dipSwitchesArr]; // Clear any empty fields ClearEmptyKeys(dipSwitchItem); @@ -492,7 +492,7 @@ namespace SabreTools.DatFiles { // Get existing features as a list var featuresArr = partItems[partName].Read(Models.Metadata.Part.FeatureKey) ?? []; - var features = new List(featuresArr); + List features = [.. featuresArr]; // Clear any empty fields ClearEmptyKeys(featureItem); @@ -523,17 +523,17 @@ namespace SabreTools.DatFiles private Models.Metadata.Machine[]? ConvertMachinesDB(bool ignoreblanks = false) { // Create a machine list to hold all outputs - var machines = new List(); + List machines = []; // Loop through the sorted items and create games for them foreach (string key in ItemsDB.SortedKeys) { var items = ItemsDB.GetItemsForBucket(key, filter: true); - if (items == null || items.Length == 0) + if (items == null || items.Count == 0) continue; // Create a machine to hold everything - var machine = ItemsDB.GetMachineForItem(items[0].Item1).Item2!.GetInternalClone(); + var machine = ItemsDB.GetMachineForItem(items.First().Key).Value!.GetInternalClone(); // Handle Trurip object, if it exists if (machine.ContainsKey(Models.Metadata.Machine.TruripKey)) @@ -557,19 +557,16 @@ namespace SabreTools.DatFiles Dictionary diskAreaMappings = []; // Loop through and convert the items to respective lists - for (int index = 0; index < items.Length; index++) + foreach (var kvp in items) { - // Get the item - var item = items[index]; - // Check for a "null" item - item = ProcessNullifiedItem(item); + var item = ProcessNullifiedItem(kvp); // Skip if we're ignoring the item - if (ShouldIgnore(item, ignoreblanks)) + if (ShouldIgnore(item.Value, ignoreblanks)) continue; - switch (item.Item2) + switch (item.Value) { case DatItems.Formats.Adjuster adjuster: var adjusterItem = ProcessItem(adjuster); @@ -797,7 +794,7 @@ namespace SabreTools.DatFiles { // Get existing data areas as a list var dataAreasArr = partItems[partName].Read(Models.Metadata.Part.DataAreaKey) ?? []; - var dataAreas = new List(dataAreasArr); + List dataAreas = [.. dataAreasArr]; // Find the existing disk area to append to, otherwise create a new disk area int dataAreaIndex = dataAreas.FindIndex(da => da.ReadString(Models.Metadata.DataArea.NameKey) == dataAreaName); @@ -820,7 +817,7 @@ namespace SabreTools.DatFiles // Get existing roms as a list var romsArr = aggregateDataArea.Read(Models.Metadata.DataArea.RomKey) ?? []; - var roms = new List(romsArr); + List roms = [.. romsArr]; // Add the rom to the data area roms.Add(romItem); @@ -854,7 +851,7 @@ namespace SabreTools.DatFiles { // Get existing disk areas as a list var diskAreasArr = partItems[partName].Read(Models.Metadata.Part.DiskAreaKey) ?? []; - var diskAreas = new List(diskAreasArr); + List diskAreas = [.. diskAreasArr]; // Find the existing disk area to append to, otherwise create a new disk area int diskAreaIndex = diskAreas.FindIndex(da => da.ReadString(Models.Metadata.DiskArea.NameKey) == diskAreaName); @@ -874,7 +871,7 @@ namespace SabreTools.DatFiles // Get existing disks as a list var disksArr = aggregateDiskArea.Read(Models.Metadata.DiskArea.DiskKey) ?? []; - var disks = new List(disksArr); + List disks = [.. disksArr]; // Add the disk to the data area disks.Add(diskItem); @@ -898,7 +895,7 @@ namespace SabreTools.DatFiles { // Get existing dipswitches as a list var dipSwitchesArr = partItems[partName].Read(Models.Metadata.Part.DipSwitchKey) ?? []; - var dipSwitches = new List(dipSwitchesArr); + List dipSwitches = [.. dipSwitchesArr]; // Clear any empty fields ClearEmptyKeys(dipSwitchItem); @@ -915,7 +912,7 @@ namespace SabreTools.DatFiles { // Get existing features as a list var featuresArr = partItems[partName].Read(Models.Metadata.Part.FeatureKey) ?? []; - var features = new List(featuresArr); + List features = [.. featuresArr]; // Clear any empty fields ClearEmptyKeys(featureItem); @@ -970,7 +967,7 @@ namespace SabreTools.DatFiles var confLocations = item.GetFieldValue(Models.Metadata.Configuration.ConfLocationKey); if (confLocations != null) { - var confLocationItems = new List(); + List confLocationItems = []; foreach (var confLocation in confLocations) { var confLocationItem = confLocation.GetInternalClone(); @@ -983,7 +980,7 @@ namespace SabreTools.DatFiles var confSettings = item.GetFieldValue(Models.Metadata.Configuration.ConfSettingKey); if (confSettings != null) { - var confSettingItems = new List(); + List confSettingItems = []; foreach (var confSetting in confSettings) { var confSettingItem = confSetting.GetInternalClone(); @@ -1011,7 +1008,7 @@ namespace SabreTools.DatFiles var extensions = item.GetFieldValue(Models.Metadata.Device.ExtensionKey); if (extensions != null) { - var extensionItems = new List(); + List extensionItems = []; foreach (var extension in extensions) { var extensionItem = extension.GetInternalClone(); @@ -1040,7 +1037,7 @@ namespace SabreTools.DatFiles var dipLocations = item.GetFieldValue(Models.Metadata.DipSwitch.DipLocationKey); if (dipLocations != null) { - var dipLocationItems = new List(); + List dipLocationItems = []; foreach (var dipLocation in dipLocations) { var extensionItem = dipLocation.GetInternalClone(); @@ -1053,7 +1050,7 @@ namespace SabreTools.DatFiles var dipValues = item.GetFieldValue(Models.Metadata.DipSwitch.DipValueKey); if (dipValues != null) { - var dipValueItems = new List(); + List dipValueItems = []; foreach (var dipValue in dipValues) { var extensionItem = dipValue.GetInternalClone(); @@ -1104,7 +1101,7 @@ namespace SabreTools.DatFiles var controls = item.GetFieldValue(Models.Metadata.Input.ControlKey); if (controls != null) { - var controlItems = new List(); + List controlItems = []; foreach (var control in controls) { var controlItem = control.GetInternalClone(); @@ -1128,7 +1125,7 @@ namespace SabreTools.DatFiles var analogs = item.GetFieldValue(Models.Metadata.Port.AnalogKey); if (analogs != null) { - var analogItems = new List(); + List analogItems = []; foreach (var analog in analogs) { var extensionItem = analog.GetInternalClone(); @@ -1252,7 +1249,7 @@ namespace SabreTools.DatFiles var slotOptions = item.GetFieldValue(Models.Metadata.Slot.SlotOptionKey); if (slotOptions != null) { - var slotOptionItems = new List(); + List slotOptionItems = []; foreach (var slotOption in slotOptions) { var extensionItem = slotOption.GetInternalClone(); diff --git a/SabreTools.DatFiles/DatFile.cs b/SabreTools.DatFiles/DatFile.cs index 9dd58ff9..6c0e781f 100644 --- a/SabreTools.DatFiles/DatFile.cs +++ b/SabreTools.DatFiles/DatFile.cs @@ -342,21 +342,21 @@ namespace SabreTools.DatFiles /// DatItem to create a prefix/postfix for /// True for prefix, false for postfix /// Sanitized string representing the postfix or prefix - protected string CreatePrefixPostfixDB((long, DatItem) item, bool prefix) + protected string CreatePrefixPostfixDB(KeyValuePair item, bool prefix) { // Get machine for the item - var machine = ItemsDB.GetMachineForItem(item.Item1); - if (machine.Item2 == null) + var machine = ItemsDB.GetMachineForItem(item.Key); + if (machine.Value == null) return string.Empty; // Initialize strings - string? type = item.Item2.GetStringFieldValue(Models.Metadata.DatItem.TypeKey); + string? type = item.Value.GetStringFieldValue(Models.Metadata.DatItem.TypeKey); string fix, - game = machine.Item2.GetStringFieldValue(Models.Metadata.Machine.NameKey) ?? string.Empty, - manufacturer = machine.Item2.GetStringFieldValue(Models.Metadata.Machine.ManufacturerKey) ?? string.Empty, - publisher = machine.Item2.GetStringFieldValue(Models.Metadata.Machine.PublisherKey) ?? string.Empty, - category = machine.Item2.GetStringFieldValue(Models.Metadata.Machine.CategoryKey) ?? string.Empty, - name = item.Item2.GetName() ?? type.AsEnumValue().AsStringValue() ?? string.Empty, + game = machine.Value.GetStringFieldValue(Models.Metadata.Machine.NameKey) ?? string.Empty, + manufacturer = machine.Value.GetStringFieldValue(Models.Metadata.Machine.ManufacturerKey) ?? string.Empty, + publisher = machine.Value.GetStringFieldValue(Models.Metadata.Machine.PublisherKey) ?? string.Empty, + category = machine.Value.GetStringFieldValue(Models.Metadata.Machine.CategoryKey) ?? string.Empty, + name = item.Value.GetName() ?? type.AsEnumValue().AsStringValue() ?? string.Empty, crc = string.Empty, md5 = string.Empty, sha1 = string.Empty, @@ -384,19 +384,19 @@ namespace SabreTools.DatFiles } // Ensure we have the proper values for replacement - if (item.Item2 is Disk disk) + if (item.Value is Disk disk) { md5 = disk.GetStringFieldValue(Models.Metadata.Disk.MD5Key) ?? string.Empty; sha1 = disk.GetStringFieldValue(Models.Metadata.Disk.SHA1Key) ?? string.Empty; } - else if (item.Item2 is Media media) + else if (item.Value is Media media) { md5 = media.GetStringFieldValue(Models.Metadata.Media.MD5Key) ?? string.Empty; sha1 = media.GetStringFieldValue(Models.Metadata.Media.SHA1Key) ?? string.Empty; sha256 = media.GetStringFieldValue(Models.Metadata.Media.SHA256Key) ?? string.Empty; spamsum = media.GetStringFieldValue(Models.Metadata.Media.SpamSumKey) ?? string.Empty; } - else if (item.Item2 is Rom rom) + else if (item.Value is Rom rom) { crc = rom.GetStringFieldValue(Models.Metadata.Rom.CRCKey) ?? string.Empty; md5 = rom.GetStringFieldValue(Models.Metadata.Rom.MD5Key) ?? string.Empty; @@ -539,7 +539,7 @@ namespace SabreTools.DatFiles /// DatItem to update /// True if the Quotes flag should be ignored, false otherwise /// True if the UseRomName should be always on (default), false otherwise - protected void ProcessItemNameDB((long, DatItem) item, bool forceRemoveQuotes, bool forceRomName = true) + protected void ProcessItemNameDB(KeyValuePair item, bool forceRemoveQuotes, bool forceRomName = true) { // Backup relevant values and set new ones accordingly bool? quotesBackup = Header.GetBoolFieldValue(DatHeader.QuotesKey); @@ -550,12 +550,12 @@ namespace SabreTools.DatFiles Header.SetFieldValue(DatHeader.UseRomNameKey, true); // Get machine for the item - var machine = ItemsDB.GetMachineForItem(item.Item1); + var machine = ItemsDB.GetMachineForItem(item.Key); // Get the name to update string? name = (Header.GetBoolFieldValue(DatHeader.UseRomNameKey) == true - ? item.Item2.GetName() - : machine.Item2!.GetStringFieldValue(Models.Metadata.Machine.NameKey)) ?? string.Empty; + ? item.Value.GetName() + : machine.Value!.GetStringFieldValue(Models.Metadata.Machine.NameKey)) ?? string.Empty; // Create the proper Prefix and Postfix string pre = CreatePrefixPostfixDB(item, true); @@ -565,34 +565,34 @@ namespace SabreTools.DatFiles var outputDepot = Header.GetFieldValue(DatHeader.OutputDepotKey); if (outputDepot?.IsActive == true) { - if (item.Item2 is Disk disk) + if (item.Value is Disk disk) { // We can only write out if there's a SHA-1 string? sha1 = disk.GetStringFieldValue(Models.Metadata.Disk.SHA1Key); if (!string.IsNullOrEmpty(sha1)) { name = Utilities.GetDepotPath(sha1, outputDepot.Depth)?.Replace('\\', '/'); - item.Item2.SetName($"{pre}{name}{post}"); + item.Value.SetName($"{pre}{name}{post}"); } } - else if (item.Item2 is Media media) + else if (item.Value is Media media) { // We can only write out if there's a SHA-1 string? sha1 = media.GetStringFieldValue(Models.Metadata.Media.SHA1Key); if (!string.IsNullOrEmpty(sha1)) { name = Utilities.GetDepotPath(sha1, outputDepot.Depth)?.Replace('\\', '/'); - item.Item2.SetName($"{pre}{name}{post}"); + item.Value.SetName($"{pre}{name}{post}"); } } - else if (item.Item2 is Rom rom) + else if (item.Value is Rom rom) { // We can only write out if there's a SHA-1 string? sha1 = rom.GetStringFieldValue(Models.Metadata.Rom.SHA1Key); if (!string.IsNullOrEmpty(sha1)) { name = Utilities.GetDepotPath(sha1, outputDepot.Depth)?.Replace('\\', '/'); - item.Item2.SetName($"{pre}{name}{post}"); + item.Value.SetName($"{pre}{name}{post}"); } } @@ -619,14 +619,14 @@ namespace SabreTools.DatFiles name += addExtension; if (Header.GetBoolFieldValue(DatHeader.UseRomNameKey) == true && Header.GetBoolFieldValue(DatHeader.GameNameKey) == true) - name = Path.Combine(machine.Item2!.GetStringFieldValue(Models.Metadata.Machine.NameKey) ?? string.Empty, name); + name = Path.Combine(machine.Value!.GetStringFieldValue(Models.Metadata.Machine.NameKey) ?? string.Empty, name); // Now assign back the formatted name name = $"{pre}{name}{post}"; if (Header.GetBoolFieldValue(DatHeader.UseRomNameKey) == true) - item.Item2.SetName(name); - else if (machine.Item2 != null) - machine.Item2.SetFieldValue(Models.Metadata.Machine.NameKey, name); + item.Value.SetName(name); + else if (machine.Value != null) + machine.Value.SetFieldValue(Models.Metadata.Machine.NameKey, name); // Restore all relevant values if (forceRemoveQuotes) @@ -684,15 +684,15 @@ namespace SabreTools.DatFiles /// /// DatItem to check for "null" status /// Cleaned DatItem - protected (long, DatItem) ProcessNullifiedItem((long, DatItem) item) + protected KeyValuePair ProcessNullifiedItem(KeyValuePair item) { // If we don't have a Rom, we can ignore it - if (item.Item2 is not Rom rom) + if (item.Value is not Rom rom) return item; // Get machine for the item - var machine = ItemsDB.GetMachineForItem(item.Item1); - var machineObj = machine.Item2; + var machine = ItemsDB.GetMachineForItem(item.Key); + var machineObj = machine.Value; if (machineObj == null) return item; @@ -720,7 +720,7 @@ namespace SabreTools.DatFiles rom.GetStringFieldValue(Models.Metadata.Rom.SpamSumKey) == "null" ? ZeroHash.SpamSumStr : null); } - return (item.Item1, rom); + return new KeyValuePair(item.Key, rom); } /// @@ -766,15 +766,15 @@ namespace SabreTools.DatFiles /// DatItems to check /// True if the machine contains at least one writable item, false otherwise /// Empty machines are kept with this - protected bool ContainsWritable((long, DatItem)[]? datItems) + protected bool ContainsWritable(Dictionary? datItems) { // Empty machines are considered writable - if (datItems == null || datItems.Length == 0) + if (datItems == null || datItems.Count == 0) return true; - foreach ((long, DatItem) datItem in datItems) + foreach (var datItem in datItems) { - ItemType itemType = datItem.Item2.GetStringFieldValue(Models.Metadata.DatItem.TypeKey).AsEnumValue(); + ItemType itemType = datItem.Value.GetStringFieldValue(Models.Metadata.DatItem.TypeKey).AsEnumValue(); if (Array.Exists(GetSupportedTypes(), t => t == itemType)) return true; } @@ -852,76 +852,6 @@ namespace SabreTools.DatFiles return false; } - /// - /// Get if an item should be ignored on write - /// - /// DatItem to check - /// True if blank roms should be skipped on output, false otherwise - /// True if the item should be skipped on write, false otherwise - protected bool ShouldIgnore((long, DatItem?) datItem, bool ignoreBlanks) - { - // If this is invoked with a null DatItem, we ignore - if (datItem.Item1 < 0 || datItem.Item2 == null) - { - logger?.Verbose($"Item was skipped because it was null"); - return true; - } - - // If the item is supposed to be removed, we ignore - if (datItem.Item2.GetBoolFieldValue(DatItem.RemoveKey) == true) - { - string itemString = JsonConvert.SerializeObject(datItem, Formatting.None); - logger?.Verbose($"Item '{itemString}' was skipped because it was marked for removal"); - return true; - } - - // If we have the Blank dat item, we ignore - if (datItem.Item2 is Blank) - { - string itemString = JsonConvert.SerializeObject(datItem, Formatting.None); - logger?.Verbose($"Item '{itemString}' was skipped because it was of type 'Blank'"); - return true; - } - - // If we're ignoring blanks and we have a Rom - if (ignoreBlanks && datItem.Item2 is Rom rom) - { - // If we have a 0-size or blank rom, then we ignore - long? size = rom.GetInt64FieldValue(Models.Metadata.Rom.SizeKey); - if (size == 0 || size == null) - { - string itemString = JsonConvert.SerializeObject(datItem, Formatting.None); - logger?.Verbose($"Item '{itemString}' was skipped because it had an invalid size"); - return true; - } - } - - // If we have an item type not in the list of supported values - string datFormat = Header?.GetFieldValue(DatHeader.DatFormatKey).ToString() ?? "Unknown Format"; - ItemType itemType = datItem.Item2.GetStringFieldValue(Models.Metadata.DatItem.TypeKey).AsEnumValue(); - if (!Array.Exists(GetSupportedTypes(), t => t == itemType)) - { - string itemString = JsonConvert.SerializeObject(datItem, Formatting.None); - logger?.Verbose($"Item '{itemString}' was skipped because it was not supported in {datFormat}"); - return true; - } - - // If we have an item with missing required fields - List? missingFields = GetMissingRequiredFields(datItem.Item2); - if (missingFields != null && missingFields.Count != 0) - { - string itemString = JsonConvert.SerializeObject(datItem, Formatting.None); -#if NET20 || NET35 - logger?.Verbose($"Item '{itemString}' was skipped because it was missing required fields for {datFormat}: {string.Join(", ", [.. missingFields])}"); -#else - logger?.Verbose($"Item '{itemString}' was skipped because it was missing required fields for {datFormat}: {string.Join(", ", missingFields)}"); -#endif - return true; - } - - return false; - } - #endregion } } diff --git a/SabreTools.DatFiles/Formats/AttractMode.cs b/SabreTools.DatFiles/Formats/AttractMode.cs index 3e5648eb..8121697d 100644 --- a/SabreTools.DatFiles/Formats/AttractMode.cs +++ b/SabreTools.DatFiles/Formats/AttractMode.cs @@ -28,7 +28,7 @@ namespace SabreTools.DatFiles.Formats /// protected override List? GetMissingRequiredFields(DatItem datItem) { - var missingFields = new List(); + List missingFields = []; // Check item name if (string.IsNullOrEmpty(datItem.GetName())) diff --git a/SabreTools.DatFiles/Formats/ClrMamePro.cs b/SabreTools.DatFiles/Formats/ClrMamePro.cs index 8ae2aabf..99af5c8f 100644 --- a/SabreTools.DatFiles/Formats/ClrMamePro.cs +++ b/SabreTools.DatFiles/Formats/ClrMamePro.cs @@ -73,7 +73,7 @@ namespace SabreTools.DatFiles.Formats /// protected override List? GetMissingRequiredFields(DatItem datItem) { - var missingFields = new List(); + List missingFields = []; switch (datItem) { case Release release: diff --git a/SabreTools.DatFiles/Formats/DosCenter.cs b/SabreTools.DatFiles/Formats/DosCenter.cs index eb3ba1cb..3922c002 100644 --- a/SabreTools.DatFiles/Formats/DosCenter.cs +++ b/SabreTools.DatFiles/Formats/DosCenter.cs @@ -29,7 +29,7 @@ namespace SabreTools.DatFiles.Formats /// protected override List? GetMissingRequiredFields(DatItem datItem) { - var missingFields = new List(); + List missingFields = []; // Check item name if (string.IsNullOrEmpty(datItem.GetName())) diff --git a/SabreTools.DatFiles/Formats/EverdriveSmdb.cs b/SabreTools.DatFiles/Formats/EverdriveSmdb.cs index bb6ad796..82dfbd83 100644 --- a/SabreTools.DatFiles/Formats/EverdriveSmdb.cs +++ b/SabreTools.DatFiles/Formats/EverdriveSmdb.cs @@ -29,7 +29,7 @@ namespace SabreTools.DatFiles.Formats /// protected override List? GetMissingRequiredFields(DatItem datItem) { - var missingFields = new List(); + List missingFields = []; // Check item name if (string.IsNullOrEmpty(datItem.GetName())) diff --git a/SabreTools.DatFiles/Formats/Hashfile.cs b/SabreTools.DatFiles/Formats/Hashfile.cs index 8f1ad987..394a7160 100644 --- a/SabreTools.DatFiles/Formats/Hashfile.cs +++ b/SabreTools.DatFiles/Formats/Hashfile.cs @@ -55,7 +55,7 @@ namespace SabreTools.DatFiles.Formats /// protected override List? GetMissingRequiredFields(DatItem datItem) { - var missingFields = new List(); + List missingFields = []; // Check item name if (string.IsNullOrEmpty(datItem.GetName())) diff --git a/SabreTools.DatFiles/Formats/Listrom.cs b/SabreTools.DatFiles/Formats/Listrom.cs index 0cd1e80e..26d1c424 100644 --- a/SabreTools.DatFiles/Formats/Listrom.cs +++ b/SabreTools.DatFiles/Formats/Listrom.cs @@ -30,7 +30,7 @@ namespace SabreTools.DatFiles.Formats /// protected override List? GetMissingRequiredFields(DatItem datItem) { - var missingFields = new List(); + List missingFields = []; // Check item name if (string.IsNullOrEmpty(datItem.GetName())) diff --git a/SabreTools.DatFiles/Formats/Listxml.cs b/SabreTools.DatFiles/Formats/Listxml.cs index 6aa8c6d3..0a702720 100644 --- a/SabreTools.DatFiles/Formats/Listxml.cs +++ b/SabreTools.DatFiles/Formats/Listxml.cs @@ -244,7 +244,7 @@ namespace SabreTools.DatFiles.Formats /// protected override List? GetMissingRequiredFields(DatItem datItem) { - var missingFields = new List(); + List missingFields = []; switch (datItem) { case BiosSet biosset: diff --git a/SabreTools.DatFiles/Formats/Logiqx.cs b/SabreTools.DatFiles/Formats/Logiqx.cs index deb67968..35f23c23 100644 --- a/SabreTools.DatFiles/Formats/Logiqx.cs +++ b/SabreTools.DatFiles/Formats/Logiqx.cs @@ -248,7 +248,7 @@ namespace SabreTools.DatFiles.Formats /// protected override List? GetMissingRequiredFields(DatItem datItem) { - var missingFields = new List(); + List missingFields = []; switch (datItem) { case Release release: diff --git a/SabreTools.DatFiles/Formats/Missfile.cs b/SabreTools.DatFiles/Formats/Missfile.cs index fa12d855..73df03d2 100644 --- a/SabreTools.DatFiles/Formats/Missfile.cs +++ b/SabreTools.DatFiles/Formats/Missfile.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Linq; using System.Text; using SabreTools.DatItems; @@ -118,28 +119,30 @@ namespace SabreTools.DatFiles.Formats foreach (string key in ItemsDB.SortedKeys) { // If this machine doesn't contain any writable items, skip - var items = ItemsDB.GetItemsForBucket(key, filter: true); - if (items == null || !ContainsWritable(items)) + var itemsDict = ItemsDB.GetItemsForBucket(key, filter: true); + if (itemsDict == null || !ContainsWritable(itemsDict)) continue; // Resolve the names in the block - items = [.. DatItem.ResolveNamesDB([.. items])]; + var items = DatItem.ResolveNamesDB([.. itemsDict]); - for (int index = 0; index < items.Length; index++) + foreach (var kvp in items) { // Check for a "null" item - var datItem = items[index]; - datItem = ProcessNullifiedItem(datItem); + var datItem = ProcessNullifiedItem(kvp); // Get the machine for the item - var machine = ItemsDB.GetMachineForItem(datItem.Item1); + var machine = ItemsDB.GetMachineForItem(datItem.Key); // Write out the item if we're using machine names or we're not ignoring - if (!Header.GetBoolFieldValue(DatHeader.UseRomNameKey) == true || !ShouldIgnore(datItem, ignoreblanks)) + if (!Header.GetBoolFieldValue(DatHeader.UseRomNameKey) == true + || !ShouldIgnore(datItem.Value, ignoreblanks)) + { WriteDatItemDB(sw, datItem, lastgame); + } // Set the new data to compare against - lastgame = machine.Item2!.GetStringFieldValue(Models.Metadata.Machine.NameKey); + lastgame = machine.Value!.GetStringFieldValue(Models.Metadata.Machine.NameKey); } } @@ -182,19 +185,25 @@ namespace SabreTools.DatFiles.Formats /// StreamWriter to output to /// DatItem object to be output /// The name of the last game to be output - private void WriteDatItemDB(StreamWriter sw, (long, DatItem) datItem, string? lastgame) + private void WriteDatItemDB(StreamWriter sw, KeyValuePair datItem, string? lastgame) { // Get the machine for the item - var machine = ItemsDB.GetMachineForItem(datItem.Item1); + var machine = ItemsDB.GetMachineForItem(datItem.Key); // Process the item name ProcessItemNameDB(datItem, false, forceRomName: false); // Romba mode automatically uses item name - if (Header.GetFieldValue(DatHeader.OutputDepotKey)?.IsActive == true || Header.GetBoolFieldValue(DatHeader.UseRomNameKey) == true) - sw.Write($"{datItem.Item2.GetName() ?? string.Empty}\n"); - else if (!Header.GetBoolFieldValue(DatHeader.UseRomNameKey) == true && machine.Item2!.GetStringFieldValue(Models.Metadata.Machine.NameKey) != lastgame) - sw.Write($"{machine.Item2!.GetStringFieldValue(Models.Metadata.Machine.NameKey) ?? string.Empty}\n"); + if (Header.GetFieldValue(DatHeader.OutputDepotKey)?.IsActive == true + || Header.GetBoolFieldValue(DatHeader.UseRomNameKey) == true) + { + sw.Write($"{datItem.Value.GetName() ?? string.Empty}\n"); + } + else if (!Header.GetBoolFieldValue(DatHeader.UseRomNameKey) == true + && machine.Value!.GetStringFieldValue(Models.Metadata.Machine.NameKey) != lastgame) + { + sw.Write($"{machine.Value!.GetStringFieldValue(Models.Metadata.Machine.NameKey) ?? string.Empty}\n"); + } sw.Flush(); } diff --git a/SabreTools.DatFiles/Formats/OfflineList.cs b/SabreTools.DatFiles/Formats/OfflineList.cs index 74a56c65..a6b2f58b 100644 --- a/SabreTools.DatFiles/Formats/OfflineList.cs +++ b/SabreTools.DatFiles/Formats/OfflineList.cs @@ -29,7 +29,7 @@ namespace SabreTools.DatFiles.Formats /// protected override List? GetMissingRequiredFields(DatItem datItem) { - var missingFields = new List(); + List missingFields = []; switch (datItem) { diff --git a/SabreTools.DatFiles/Formats/OpenMSX.cs b/SabreTools.DatFiles/Formats/OpenMSX.cs index 97ffde6b..2a583cd5 100644 --- a/SabreTools.DatFiles/Formats/OpenMSX.cs +++ b/SabreTools.DatFiles/Formats/OpenMSX.cs @@ -60,7 +60,7 @@ The softwaredb.xml file contains information about rom mapper types /// protected override List? GetMissingRequiredFields(DatItem datItem) { - var missingFields = new List(); + List missingFields = []; // Check item name if (string.IsNullOrEmpty(datItem.GetName())) diff --git a/SabreTools.DatFiles/Formats/RomCenter.cs b/SabreTools.DatFiles/Formats/RomCenter.cs index c51ae363..afd823e4 100644 --- a/SabreTools.DatFiles/Formats/RomCenter.cs +++ b/SabreTools.DatFiles/Formats/RomCenter.cs @@ -29,7 +29,7 @@ namespace SabreTools.DatFiles.Formats /// protected override List? GetMissingRequiredFields(DatItem datItem) { - var missingFields = new List(); + List missingFields = []; // Check item name if (string.IsNullOrEmpty(datItem.GetName())) diff --git a/SabreTools.DatFiles/Formats/SabreJSON.cs b/SabreTools.DatFiles/Formats/SabreJSON.cs index a5699e63..bb615438 100644 --- a/SabreTools.DatFiles/Formats/SabreJSON.cs +++ b/SabreTools.DatFiles/Formats/SabreJSON.cs @@ -406,11 +406,11 @@ namespace SabreTools.DatFiles.Formats // If we have a different game and we're not at the start of the list, output the end of last item if (lastgame != null && !string.Equals(lastgame, datItem.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.NameKey), StringComparison.OrdinalIgnoreCase)) - SabreJSON.WriteEndGame(jtw); + WriteEndGame(jtw); // If we have a new game, output the beginning of the new item if (lastgame == null || !string.Equals(lastgame, datItem.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.NameKey), StringComparison.OrdinalIgnoreCase)) - SabreJSON.WriteStartGame(jtw, datItem); + WriteStartGame(jtw, datItem); // Check for a "null" item datItem = ProcessNullifiedItem(datItem); @@ -425,7 +425,7 @@ namespace SabreTools.DatFiles.Formats } // Write the file footer out - SabreJSON.WriteFooter(jtw); + WriteFooter(jtw); logger.User($"'{outfile}' written!{Environment.NewLine}"); jtw.Close(); @@ -473,42 +473,40 @@ namespace SabreTools.DatFiles.Formats foreach (string key in ItemsDB.SortedKeys) { // If this machine doesn't contain any writable items, skip - var items = ItemsDB.GetItemsForBucket(key, filter: true); - if (items == null || !ContainsWritable(items)) + var itemsDict = ItemsDB.GetItemsForBucket(key, filter: true); + if (itemsDict == null || !ContainsWritable(itemsDict)) continue; // Resolve the names in the block - items = [.. DatItem.ResolveNamesDB([.. items])]; + var items = DatItem.ResolveNamesDB([.. itemsDict]); - for (int index = 0; index < items.Length; index++) + foreach (var kvp in items) { - var datItem = items[index]; - // Get the machine for the item - var machine = ItemsDB.GetMachineForItem(datItem.Item1); + var machine = ItemsDB.GetMachineForItem(kvp.Key); // If we have a different game and we're not at the start of the list, output the end of last item - if (lastgame != null && !string.Equals(lastgame, machine.Item2!.GetStringFieldValue(Models.Metadata.Machine.NameKey), StringComparison.OrdinalIgnoreCase)) - SabreJSON.WriteEndGame(jtw); + if (lastgame != null && !string.Equals(lastgame, machine.Value!.GetStringFieldValue(Models.Metadata.Machine.NameKey), StringComparison.OrdinalIgnoreCase)) + WriteEndGame(jtw); // If we have a new game, output the beginning of the new item - if (lastgame == null || !string.Equals(lastgame, machine.Item2!.GetStringFieldValue(Models.Metadata.Machine.NameKey), StringComparison.OrdinalIgnoreCase)) - WriteStartGameDB(jtw, datItem); + if (lastgame == null || !string.Equals(lastgame, machine.Value!.GetStringFieldValue(Models.Metadata.Machine.NameKey), StringComparison.OrdinalIgnoreCase)) + WriteStartGame(jtw, kvp.Value); // Check for a "null" item - datItem = ProcessNullifiedItem(datItem); + var datItem = ProcessNullifiedItem(kvp); // Write out the item if we're not ignoring - if (!ShouldIgnore(datItem, ignoreblanks)) - WriteDatItemDB(jtw, datItem); + if (!ShouldIgnore(datItem.Value, ignoreblanks)) + WriteDatItem(jtw, datItem.Value); // Set the new data to compare against - lastgame = machine.Item2!.GetStringFieldValue(Models.Metadata.Machine.NameKey); + lastgame = machine.Value!.GetStringFieldValue(Models.Metadata.Machine.NameKey); } } // Write the file footer out - SabreJSON.WriteFooter(jtw); + WriteFooter(jtw); logger.User($"'{outfile}' written!{Environment.NewLine}"); jtw.Close(); @@ -567,34 +565,6 @@ namespace SabreTools.DatFiles.Formats jtw.Flush(); } - /// - /// Write out Game start using the supplied JsonTextWriter - /// - /// JsonTextWriter to output to - /// DatItem object to be output - private void WriteStartGameDB(JsonTextWriter jtw, (long, DatItem) datItem) - { - // Get the machine for the item - var machine = ItemsDB.GetMachineForItem(datItem.Item1); - - // No game should start with a path separator - if (!string.IsNullOrEmpty(machine.Item2!.GetStringFieldValue(Models.Metadata.Machine.NameKey))) - machine.Item2!.SetFieldValue(Models.Metadata.Machine.NameKey, machine.Item2!.GetStringFieldValue(Models.Metadata.Machine.NameKey)!.TrimStart(Path.DirectorySeparatorChar)); - - // Build the state - jtw.WriteStartObject(); - - // Write the Machine - jtw.WritePropertyName("machine"); - JsonSerializer js = new() { Formatting = Formatting.Indented }; - js.Serialize(jtw, machine.Item2!); - - jtw.WritePropertyName("items"); - jtw.WriteStartArray(); - - jtw.Flush(); - } - /// /// Write out Game end using the supplied JsonTextWriter /// @@ -634,30 +604,6 @@ namespace SabreTools.DatFiles.Formats jtw.Flush(); } - /// - /// Write out DatItem using the supplied JsonTextWriter - /// - /// JsonTextWriter to output to - /// DatItem object to be output - private void WriteDatItemDB(JsonTextWriter jtw, (long, DatItem) datItem) - { - // Pre-process the item name - ProcessItemNameDB(datItem, true); - - // Build the state - jtw.WriteStartObject(); - - // Write the DatItem - jtw.WritePropertyName("datitem"); - JsonSerializer js = new() { ContractResolver = new BaseFirstContractResolver(), Formatting = Formatting.Indented }; - js.Serialize(jtw, datItem.Item2); - - // End item - jtw.WriteEndObject(); - - jtw.Flush(); - } - /// /// Write out DAT footer using the supplied JsonTextWriter /// diff --git a/SabreTools.DatFiles/Formats/SabreXML.cs b/SabreTools.DatFiles/Formats/SabreXML.cs index dba534a9..623e95e7 100644 --- a/SabreTools.DatFiles/Formats/SabreXML.cs +++ b/SabreTools.DatFiles/Formats/SabreXML.cs @@ -303,37 +303,35 @@ namespace SabreTools.DatFiles.Formats foreach (string key in ItemsDB.SortedKeys) { // If this machine doesn't contain any writable items, skip - var items = ItemsDB.GetItemsForBucket(key, filter: true); - if (items == null || !ContainsWritable(items)) + var itemsDict = ItemsDB.GetItemsForBucket(key, filter: true); + if (itemsDict == null || !ContainsWritable(itemsDict)) continue; // Resolve the names in the block - items = [.. DatItem.ResolveNamesDB([.. items])]; + var items = DatItem.ResolveNamesDB([.. itemsDict]); - for (int index = 0; index < items.Length; index++) + foreach (var kvp in items) { - var datItem = items[index]; - // Get the machine for the item - var machine = ItemsDB.GetMachineForItem(datItem.Item1); + var machine = ItemsDB.GetMachineForItem(kvp.Key); // If we have a different game and we're not at the start of the list, output the end of last item - if (lastgame != null && !string.Equals(lastgame, machine.Item2!.GetStringFieldValue(Models.Metadata.Machine.NameKey), StringComparison.OrdinalIgnoreCase)) + if (lastgame != null && !string.Equals(lastgame, machine.Value!.GetStringFieldValue(Models.Metadata.Machine.NameKey), StringComparison.OrdinalIgnoreCase)) WriteEndGame(xtw); // If we have a new game, output the beginning of the new item - if (lastgame == null || !string.Equals(lastgame, machine.Item2!.GetStringFieldValue(Models.Metadata.Machine.NameKey), StringComparison.OrdinalIgnoreCase)) - WriteStartGameDB(xtw, datItem); + if (lastgame == null || !string.Equals(lastgame, machine.Value!.GetStringFieldValue(Models.Metadata.Machine.NameKey), StringComparison.OrdinalIgnoreCase)) + WriteStartGame(xtw, kvp.Value); // Check for a "null" item - datItem = ProcessNullifiedItem(datItem); + var datItem = ProcessNullifiedItem(kvp); // Write out the item if we're not ignoring - if (!ShouldIgnore(datItem, ignoreblanks)) - WriteDatItemDB(xtw, datItem); + if (!ShouldIgnore(datItem.Value, ignoreblanks)) + WriteDatItem(xtw, datItem.Value); // Set the new data to compare against - lastgame = machine.Item2!.GetStringFieldValue(Models.Metadata.Machine.NameKey); + lastgame = machine.Value!.GetStringFieldValue(Models.Metadata.Machine.NameKey); } } @@ -397,31 +395,6 @@ namespace SabreTools.DatFiles.Formats xtw.Flush(); } - /// - /// Write out Game start using the supplied StreamWriter - /// - /// XmlTextWriter to output to - /// DatItem object to be output - private void WriteStartGameDB(XmlTextWriter xtw, (long, DatItem) datItem) - { - // Get the machine for the item - var machine = ItemsDB.GetMachineForItem(datItem.Item1); - - // No game should start with a path separator - machine.Item2!.SetFieldValue(Models.Metadata.Machine.NameKey, machine.Item2!.GetStringFieldValue(Models.Metadata.Machine.NameKey)?.TrimStart(Path.DirectorySeparatorChar) ?? string.Empty); - - // Write the machine - xtw.WriteStartElement("directory"); - XmlSerializer xs = new(typeof(Machine)); - XmlSerializerNamespaces ns = new(); - ns.Add("", ""); - xs.Serialize(xtw, machine.Item2, ns); - - xtw.WriteStartElement("files"); - - xtw.Flush(); - } - /// /// Write out Game start using the supplied StreamWriter /// @@ -456,25 +429,6 @@ namespace SabreTools.DatFiles.Formats xtw.Flush(); } - /// - /// Write out DatItem using the supplied StreamWriter - /// - /// XmlTextWriter to output to - /// DatItem object to be output - private void WriteDatItemDB(XmlTextWriter xtw, (long, DatItem) datItem) - { - // Pre-process the item name - ProcessItemNameDB(datItem, true); - - // Write the DatItem - XmlSerializer xs = new(typeof(DatItem)); - XmlSerializerNamespaces ns = new(); - ns.Add("", ""); - xs.Serialize(xtw, datItem.Item2, ns); - - xtw.Flush(); - } - /// /// Write out DAT footer using the supplied StreamWriter /// diff --git a/SabreTools.DatFiles/Formats/SeparatedValue.cs b/SabreTools.DatFiles/Formats/SeparatedValue.cs index ccf783be..509dc41c 100644 --- a/SabreTools.DatFiles/Formats/SeparatedValue.cs +++ b/SabreTools.DatFiles/Formats/SeparatedValue.cs @@ -54,7 +54,7 @@ namespace SabreTools.DatFiles.Formats /// protected override List? GetMissingRequiredFields(DatItem datItem) { - var missingFields = new List(); + List missingFields = []; // Check item name if (string.IsNullOrEmpty(datItem.GetName())) diff --git a/SabreTools.DatFiles/Formats/SoftwareList.cs b/SabreTools.DatFiles/Formats/SoftwareList.cs index 0b616267..3e9a159c 100644 --- a/SabreTools.DatFiles/Formats/SoftwareList.cs +++ b/SabreTools.DatFiles/Formats/SoftwareList.cs @@ -96,7 +96,7 @@ namespace SabreTools.DatFiles.Formats /// protected override List? GetMissingRequiredFields(DatItem datItem) { - var missingFields = new List(); + List missingFields = []; switch (datItem) { diff --git a/SabreTools.DatFiles/ItemDictionary.cs b/SabreTools.DatFiles/ItemDictionary.cs index 3229d090..e20524c4 100644 --- a/SabreTools.DatFiles/ItemDictionary.cs +++ b/SabreTools.DatFiles/ItemDictionary.cs @@ -846,7 +846,7 @@ namespace SabreTools.DatFiles #endif // Filter all items in the current key - var newItems = new List(); + List newItems = []; foreach (var item in items) { if (item.PassesFilter(filterRunner)) @@ -1242,15 +1242,16 @@ namespace SabreTools.DatFiles foreach (string machine in machines) { // If the machine doesn't have items, we continue - if (this[machine] == null || this[machine]!.Count == 0) + var datItems = this[machine]; + if (datItems == null || datItems.Count == 0) continue; // If the machine (is/is not) a device, we want to continue - if (dev ^ (this[machine]![0].GetFieldValue(DatItem.MachineKey)!.GetBoolFieldValue(Models.Metadata.Machine.IsDeviceKey) == true)) + if (dev ^ (datItems[0].GetFieldValue(DatItem.MachineKey)!.GetBoolFieldValue(Models.Metadata.Machine.IsDeviceKey) == true)) continue; // Get all device reference names from the current machine - List deviceReferences = this[machine]! + List deviceReferences = datItems .FindAll(i => i is DeviceRef) .ConvertAll(i => i as DeviceRef) .ConvertAll(dr => dr!.GetName()) @@ -1258,7 +1259,7 @@ namespace SabreTools.DatFiles .ToList(); // Get all slot option names from the current machine - List slotOptions = this[machine]! + List slotOptions = datItems .FindAll(i => i is Slot) .ConvertAll(i => i as Slot) .FindAll(s => s!.SlotOptionsSpecified) @@ -1274,13 +1275,13 @@ namespace SabreTools.DatFiles var newDeviceReferences = new HashSet(); foreach (string? deviceReference in deviceReferences) { - // If the machine doesn't exist then we continue - if (deviceReference == null || this[deviceReference] == null || this[deviceReference]!.Count == 0) + // If the device reference is missing + if (string.IsNullOrEmpty(deviceReference)) continue; // Add to the list of new device reference names - var devItems = this[deviceReference]; - if (devItems == null) + var devItems = this[deviceReference!]; + if (devItems == null || devItems.Count == 0) continue; newDeviceReferences.UnionWith(devItems @@ -1288,11 +1289,11 @@ namespace SabreTools.DatFiles .ConvertAll(i => (i as DeviceRef)!.GetName()!)); // Set new machine information and add to the current machine - DatItem copyFrom = this[machine]![0]; + DatItem copyFrom = datItems[0]; foreach (DatItem item in devItems) { // If the parent machine doesn't already contain this item, add it - if (!this[machine]!.Exists(i => i.GetStringFieldValue(Models.Metadata.DatItem.TypeKey) == item.GetStringFieldValue(Models.Metadata.DatItem.TypeKey) && i.GetName() == item.GetName())) + if (!datItems.Exists(i => i.GetStringFieldValue(Models.Metadata.DatItem.TypeKey) == item.GetStringFieldValue(Models.Metadata.DatItem.TypeKey) && i.GetName() == item.GetName())) { // Set that we found new items foundnew = true; @@ -1312,7 +1313,7 @@ namespace SabreTools.DatFiles { var deviceRef = new DeviceRef(); deviceRef.SetName(deviceReference); - this[machine]!.Add(deviceRef); + datItems.Add(deviceRef); } } } @@ -1324,13 +1325,14 @@ namespace SabreTools.DatFiles var newSlotOptions = new HashSet(); foreach (string? slotOption in slotOptions) { + // If the slot option is missing + if (string.IsNullOrEmpty(slotOption)) // If the machine doesn't exist then we continue - if (slotOption == null || this[slotOption] == null || this[slotOption]!.Count == 0) continue; // Add to the list of new slot option names - var slotItems = this[slotOption]; - if (slotItems == null) + var slotItems = this[slotOption!]; + if (slotItems == null || slotItems.Count == 0) continue; newSlotOptions.UnionWith(slotItems @@ -1340,11 +1342,11 @@ namespace SabreTools.DatFiles .Select(o => o.GetStringFieldValue(Models.Metadata.SlotOption.DevNameKey)!)); // Set new machine information and add to the current machine - DatItem copyFrom = this[machine]![0]; + DatItem copyFrom = datItems[0]; foreach (DatItem item in slotItems) { // If the parent machine doesn't already contain this item, add it - if (!this[machine]!.Exists(i => i.GetStringFieldValue(Models.Metadata.DatItem.TypeKey) == item.GetStringFieldValue(Models.Metadata.DatItem.TypeKey) && i.GetName() == item.GetName())) + if (!datItems.Exists(i => i.GetStringFieldValue(Models.Metadata.DatItem.TypeKey) == item.GetStringFieldValue(Models.Metadata.DatItem.TypeKey) && i.GetName() == item.GetName())) { // Set that we found new items foundnew = true; @@ -1368,7 +1370,7 @@ namespace SabreTools.DatFiles var slotItem = new Slot(); slotItem.SetFieldValue(Models.Metadata.Slot.SlotOptionKey, [slotOptionItem]); - this[machine]!.Add(slotItem); + datItems.Add(slotItem); } } } diff --git a/SabreTools.DatFiles/ItemDictionaryDB.cs b/SabreTools.DatFiles/ItemDictionaryDB.cs index 53d459f4..429d2d49 100644 --- a/SabreTools.DatFiles/ItemDictionaryDB.cs +++ b/SabreTools.DatFiles/ItemDictionaryDB.cs @@ -341,77 +341,86 @@ namespace SabreTools.DatFiles /// /// Get all item to machine mappings /// - public (long, long)[] GetItemMachineMappings() - => [.. _itemToMachineMapping.Select(kvp => (kvp.Key, kvp.Value))]; + public IDictionary GetItemMachineMappings() => _itemToMachineMapping; /// /// Get all item to source mappings /// - public (long, long)[] GetItemSourceMappings() - => [.. _itemToSourceMapping.Select(kvp => (kvp.Key, kvp.Value))]; + public IDictionary GetItemSourceMappings() => _itemToSourceMapping; /// /// Get all items and their indicies /// - public (long, DatItem)[] GetItems() - => [.. _items.Select(kvp => (kvp.Key, kvp.Value))]; + public IDictionary GetItems() => _items; /// /// Get the indices and items associated with a bucket name /// - public (long, DatItem)[]? GetItemsForBucket(string bucketName, bool filter = false) + public Dictionary GetItemsForBucket(string bucketName, bool filter = false) { if (!_buckets.ContainsKey(bucketName)) - return null; + return []; var itemIds = _buckets[bucketName]; - var datItems = new List<(long, DatItem)>(); + var datItems = new Dictionary(); foreach (long itemId in itemIds) { - if (_items.ContainsKey(itemId) && (!filter || _items[itemId].GetBoolFieldValue(DatItem.RemoveKey) != true)) - datItems.Add((itemId, _items[itemId])); + // Ignore missing IDs + if (!_items.ContainsKey(itemId)) + continue; + + if (!filter || _items[itemId].GetBoolFieldValue(DatItem.RemoveKey) != true) + datItems[itemId] = _items[itemId]; } - return [.. datItems]; + return datItems; } /// /// Get the indices and items associated with a machine index /// - public (long, DatItem)[]? GetItemsForMachine(long machineIndex, bool filter = false) + public IDictionary? GetItemsForMachine(long machineIndex, bool filter = false) { var itemIds = _itemToMachineMapping .Where(mapping => mapping.Value == machineIndex) .Select(mapping => mapping.Key); - var datItems = new List<(long, DatItem)>(); + var datItems = new Dictionary(); foreach (long itemId in itemIds) { - if (_items.ContainsKey(itemId) && (!filter || _items[itemId].GetBoolFieldValue(DatItem.RemoveKey) != true)) - datItems.Add((itemId, _items[itemId])); + // Ignore missing IDs + if (!_items.ContainsKey(itemId)) + continue; + + if (!filter || _items[itemId].GetBoolFieldValue(DatItem.RemoveKey) != true) + datItems[itemId] = _items[itemId]; } - return [.. datItems]; + return datItems; } /// /// Get the indices and items associated with a source index /// - public (long, DatItem)[]? GetItemsForSource(long sourceIndex, bool filter = false) + public IDictionary? GetItemsForSource(long sourceIndex, bool filter = false) { var itemIds = _itemToSourceMapping .Where(mapping => mapping.Value == sourceIndex) .Select(mapping => mapping.Key); - var datItems = new List<(long, DatItem)>(); + var datItems = new Dictionary(); foreach (long itemId in itemIds) { - if (_items.ContainsKey(itemId) && (!filter || _items[itemId].GetBoolFieldValue(DatItem.RemoveKey) != true)) - datItems.Add((itemId, _items[itemId])); + // Ignore missing IDs + if (!_items.ContainsKey(itemId)) + continue; + + if (!filter || _items[itemId].GetBoolFieldValue(DatItem.RemoveKey) != true) + datItems[itemId] = _items[itemId]; } - return [.. datItems]; + return datItems; } /// @@ -429,35 +438,34 @@ namespace SabreTools.DatFiles /// Get a machine based on the name /// /// This assume that all machines have unique names - public (long, Machine?) GetMachine(string? name) + public KeyValuePair GetMachine(string? name) { if (string.IsNullOrEmpty(name)) - return (-1, null); + return new KeyValuePair(-1, null); var machine = _machines.FirstOrDefault(m => m.Value.GetStringFieldValue(Models.Metadata.Machine.NameKey) == name); - return (machine.Key, machine.Value); + return new KeyValuePair(machine.Key, machine.Value); } /// /// Get the index and machine associated with an item index /// - public (long, Machine?) GetMachineForItem(long itemIndex) + public KeyValuePair GetMachineForItem(long itemIndex) { if (!_itemToMachineMapping.ContainsKey(itemIndex)) - return (-1, null); + return new KeyValuePair(-1, null); long machineIndex = _itemToMachineMapping[itemIndex]; if (!_machines.ContainsKey(machineIndex)) - return (-1, null); + return new KeyValuePair(-1, null); - return (machineIndex, _machines[machineIndex]); + return new KeyValuePair(machineIndex, _machines[machineIndex]); } /// /// Get all machines and their indicies /// - public (long, Machine)[] GetMachines() - => [.. _machines.Select(kvp => (kvp.Key, kvp.Value))]; + public IDictionary GetMachines() => _machines; /// /// Get a source based on the index @@ -473,23 +481,22 @@ namespace SabreTools.DatFiles /// /// Get the index and source associated with an item index /// - public (long, Source?) GetSourceForItem(long itemIndex) + public KeyValuePair GetSourceForItem(long itemIndex) { if (!_itemToSourceMapping.ContainsKey(itemIndex)) - return (-1, null); + return new KeyValuePair(-1, null); long sourceIndex = _itemToSourceMapping[itemIndex]; if (!_sources.ContainsKey(sourceIndex)) - return (-1, null); + return new KeyValuePair(-1, null); - return (sourceIndex, _sources[sourceIndex]); + return new KeyValuePair(sourceIndex, _sources[sourceIndex]); } /// /// Get all sources and their indicies /// - public (long, Source)[] GetSources() - => [.. _sources.Select(kvp => (kvp.Key, kvp.Value))]; + public IDictionary GetSources() => _sources; /// /// Remove an item, returning if it could be removed @@ -617,9 +624,9 @@ namespace SabreTools.DatFiles /// Item to try to match /// True if the DAT is already sorted accordingly, false otherwise (default) /// List of matched DatItem objects - public List<(long, DatItem)> GetDuplicates(DatItem datItem, bool sorted = false) + public Dictionary GetDuplicates(DatItem datItem, bool sorted = false) { - List<(long, DatItem)> output = []; + Dictionary output = []; // Check for an empty rom list first if (DatStatistics.TotalCount == 0) @@ -630,31 +637,29 @@ namespace SabreTools.DatFiles // If the key doesn't exist, return the empty list var roms = GetItemsForBucket(key); - if (roms == null || roms.Length == 0) + if (roms == null || roms.Count == 0) return output; // Try to find duplicates - List<(long, DatItem)> left = []; - for (int i = 0; i < roms.Length; i++) + Dictionary left = []; + foreach (var rom in roms) { - (long index, DatItem other) = roms[i]; - if (other.GetBoolFieldValue(DatItem.RemoveKey) == true) + if (rom.Value.GetBoolFieldValue(DatItem.RemoveKey) == true) continue; - if (datItem.Equals(other)) + if (datItem.Equals(rom.Value)) { - other.SetFieldValue(DatItem.RemoveKey, true); - output.Add((index, other)); + rom.Value.SetFieldValue(DatItem.RemoveKey, true); + output[rom.Key] = rom.Value; } else { - left.Add((index, other)); + left[rom.Key] = rom.Value; } } // Add back all roms with the proper flags - List<(long, DatItem)> combined = [.. output, .. left]; - _buckets[key] = combined.ConvertAll(i => i.Item1); + _buckets[key] = [.. output.Keys, .. left.Keys]; return output; } @@ -664,9 +669,9 @@ namespace SabreTools.DatFiles /// Item to try to match /// True if the DAT is already sorted accordingly, false otherwise (default) /// List of matched DatItem objects - public List<(long, DatItem)> GetDuplicates((long, DatItem) datItem, bool sorted = false) + public Dictionary GetDuplicates(KeyValuePair datItem, bool sorted = false) { - List<(long, DatItem)> output = []; + Dictionary output = []; // Check for an empty rom list first if (DatStatistics.TotalCount == 0) @@ -677,31 +682,29 @@ namespace SabreTools.DatFiles // If the key doesn't exist, return the empty list var roms = GetItemsForBucket(key); - if (roms == null || roms.Length == 0) + if (roms == null || roms.Count == 0) return output; // Try to find duplicates - List<(long, DatItem)> left = []; - for (int i = 0; i < roms.Length; i++) + Dictionary left = []; + foreach (var rom in roms) { - (long index, DatItem other) = roms[i]; - if (other.GetBoolFieldValue(DatItem.RemoveKey) == true) + if (rom.Value.GetBoolFieldValue(DatItem.RemoveKey) == true) continue; - if (datItem.Item2.Equals(other)) + if (datItem.Value.Equals(rom.Value)) { - other.SetFieldValue(DatItem.RemoveKey, true); - output.Add((index, other)); + rom.Value.SetFieldValue(DatItem.RemoveKey, true); + output[rom.Key] = rom.Value; } else { - left.Add((index, other)); + left[rom.Key] = rom.Value; } } // Add back all roms with the proper flags - List<(long, DatItem)> combined = [.. output, .. left]; - _buckets[key] = combined.ConvertAll(i => i.Item1); + _buckets[key] = [.. output.Keys, .. left.Keys]; return output; } @@ -711,7 +714,7 @@ namespace SabreTools.DatFiles /// Item to try to match /// True if the DAT is already sorted accordingly, false otherwise (default) /// True if it contains the rom, false otherwise - public bool HasDuplicates((long, DatItem) datItem, bool sorted = false) + public bool HasDuplicates(KeyValuePair datItem, bool sorted = false) { // Check for an empty rom list first if (DatStatistics.TotalCount == 0) @@ -722,36 +725,32 @@ namespace SabreTools.DatFiles // If the key doesn't exist var roms = GetItemsForBucket(key); - if (roms == null || roms.Length == 0) + if (roms == null || roms.Count == 0) return false; // Try to find duplicates - return Array.Exists(roms, r => datItem.Equals(r.Item2)); + return roms.Values.Any(r => datItem.Equals(r)); } /// /// Merge an arbitrary set of item pairs based on the supplied information /// /// List of pairs representing the items to be merged - private List<(long, DatItem)> Deduplicate(List<(long, DatItem)> itemMappings) + private List> Deduplicate(List> itemMappings) { // Check for null or blank roms first if (itemMappings == null || itemMappings.Count == 0) return []; // Create output list - List<(long, DatItem)> output = []; + List> output = []; // Then deduplicate them by checking to see if data matches previous saved roms int nodumpCount = 0; - for (int f = 0; f < itemMappings.Count; f++) + foreach (var kvp in itemMappings) { - long itemIndex = itemMappings[f].Item1; - DatItem datItem = itemMappings[f].Item2; - - // If we somehow have a null item, skip - if (datItem == null) - continue; + long itemIndex = kvp.Key; + DatItem datItem = kvp.Value; // If we don't have a Disk, File, Media, or Rom, we skip checking for duplicates if (datItem is not Disk && datItem is not DatItems.Formats.File && datItem is not Media && datItem is not Rom) @@ -760,20 +759,20 @@ namespace SabreTools.DatFiles // If it's a nodump, add and skip if (datItem is Rom rom && rom.GetStringFieldValue(Models.Metadata.Rom.StatusKey).AsEnumValue() == ItemStatus.Nodump) { - output.Add((itemIndex, datItem)); + output.Add(new KeyValuePair(itemIndex, datItem)); nodumpCount++; continue; } else if (datItem is Disk disk && disk.GetStringFieldValue(Models.Metadata.Disk.StatusKey).AsEnumValue() == ItemStatus.Nodump) { - output.Add((itemIndex, datItem)); + output.Add(new KeyValuePair(itemIndex, datItem)); nodumpCount++; continue; } // If it's the first non-nodump rom in the list, don't touch it else if (output.Count == 0 || output.Count == nodumpCount) { - output.Add((itemIndex, datItem)); + output.Add(new KeyValuePair(itemIndex, datItem)); continue; } @@ -784,8 +783,8 @@ namespace SabreTools.DatFiles int pos = -1; for (int i = 0; i < output.Count; i++) { - long lastIndex = output[i].Item1; - DatItem lastrom = output[i].Item2; + long lastIndex = output[i].Key; + DatItem lastrom = output[i].Value; // Get the sources associated with the items var savedSource = _sources[_itemToSourceMapping[savedIndex]]; @@ -840,13 +839,12 @@ namespace SabreTools.DatFiles // If no duplicate is found, add it to the list if (dupetype == 0x00) { - output.Add((itemIndex, datItem)); + output.Add(new KeyValuePair(itemIndex, datItem)); } // Otherwise, if a new rom information is found, add that - else { output.RemoveAt(pos); - output.Insert(pos, (savedIndex, saveditem)); + output.Insert(pos, new KeyValuePair(savedIndex, saveditem)); } } @@ -906,13 +904,13 @@ namespace SabreTools.DatFiles return string.Empty; var machine = GetMachineForItem(itemIndex); - if (machine.Item2 == null) + if (machine.Value == null) return string.Empty; var source = GetSourceForItem(itemIndex); - string sourceKeyPadded = source.Item2?.Index.ToString().PadLeft(10, '0') + '-'; - string machineName = machine.Item2.GetStringFieldValue(Models.Metadata.Machine.NameKey) ?? "Default"; + string sourceKeyPadded = source.Value?.Index.ToString().PadLeft(10, '0') + '-'; + string machineName = machine.Value.GetStringFieldValue(Models.Metadata.Machine.NameKey) ?? "Default"; string bucketKey = bucketBy switch { @@ -1067,7 +1065,8 @@ namespace SabreTools.DatFiles var datItems = itemIndices .FindAll(i => _items.ContainsKey(i)) - .ConvertAll(i => (i, _items[i])); + .Select(i => new KeyValuePair(i, _items[i])) + .ToList(); Sort(ref datItems, false); @@ -1075,7 +1074,7 @@ namespace SabreTools.DatFiles if (dedupeType == DedupeType.Full || (dedupeType == DedupeType.Game && bucketBy == ItemKey.Machine)) datItems = Deduplicate(datItems); - _buckets[bucketKeys[i]] = datItems.ConvertAll(m => m.i); + _buckets[bucketKeys[i]] = [.. datItems.Select(kvp => kvp.Key)]; #if NET40_OR_GREATER || NETCOREAPP }); #else @@ -1113,11 +1112,12 @@ namespace SabreTools.DatFiles var datItems = itemIndices .FindAll(i => _items.ContainsKey(i)) - .ConvertAll(i => (i, _items[i])); + .Select(i => new KeyValuePair(i, _items[i])) + .ToList(); Sort(ref datItems, norename); - _buckets[bucketKeys[i]] = datItems.ConvertAll(m => m.Item1); + _buckets[bucketKeys[i]] = [.. datItems.Select(kvp => kvp.Key)]; #if NET40_OR_GREATER || NETCOREAPP }); #else @@ -1131,41 +1131,41 @@ namespace SabreTools.DatFiles /// List of pairs representing the items to be sorted /// True if files are not renamed, false otherwise /// True if it sorted correctly, false otherwise - private bool Sort(ref List<(long, DatItem)> itemMappings, bool norename) + private bool Sort(ref List> itemMappings, bool norename) { - itemMappings.Sort(delegate ((long, DatItem) x, (long, DatItem) y) + itemMappings.Sort(delegate (KeyValuePair x, KeyValuePair y) { try { var nc = new NaturalComparer(); // If machine names don't match - string? xMachineName = _machines[_itemToMachineMapping[x.Item1]].GetStringFieldValue(Models.Metadata.Machine.NameKey); - string? yMachineName = _machines[_itemToMachineMapping[y.Item1]].GetStringFieldValue(Models.Metadata.Machine.NameKey); + string? xMachineName = _machines[_itemToMachineMapping[x.Key]].GetStringFieldValue(Models.Metadata.Machine.NameKey); + string? yMachineName = _machines[_itemToMachineMapping[y.Key]].GetStringFieldValue(Models.Metadata.Machine.NameKey); if (xMachineName != yMachineName) return nc.Compare(xMachineName, yMachineName); // If types don't match - string? xType = x.Item2.GetStringFieldValue(Models.Metadata.DatItem.TypeKey); - string? yType = y.Item2.GetStringFieldValue(Models.Metadata.DatItem.TypeKey); + string? xType = x.Value.GetStringFieldValue(Models.Metadata.DatItem.TypeKey); + string? yType = y.Value.GetStringFieldValue(Models.Metadata.DatItem.TypeKey); if (xType != yType) return xType.AsEnumValue() - yType.AsEnumValue(); // If directory names don't match - string? xDirectoryName = Path.GetDirectoryName(TextHelper.RemovePathUnsafeCharacters(x.Item2.GetName())); - string? yDirectoryName = Path.GetDirectoryName(TextHelper.RemovePathUnsafeCharacters(y.Item2.GetName())); + string? xDirectoryName = Path.GetDirectoryName(TextHelper.RemovePathUnsafeCharacters(x.Value.GetName())); + string? yDirectoryName = Path.GetDirectoryName(TextHelper.RemovePathUnsafeCharacters(y.Value.GetName())); if (xDirectoryName != yDirectoryName) return nc.Compare(xDirectoryName, yDirectoryName); // If item names don't match - string? xName = Path.GetFileName(TextHelper.RemovePathUnsafeCharacters(x.Item2.GetName())); - string? yName = Path.GetFileName(TextHelper.RemovePathUnsafeCharacters(y.Item2.GetName())); + string? xName = Path.GetFileName(TextHelper.RemovePathUnsafeCharacters(x.Value.GetName())); + string? yName = Path.GetFileName(TextHelper.RemovePathUnsafeCharacters(y.Value.GetName())); if (xName != yName) return nc.Compare(xName, yName); // Otherwise, compare on machine or source, depending on the flag - int? xSourceIndex = GetSourceForItem(x.Item1).Item2?.Index; - int? ySourceIndex = GetSourceForItem(y.Item1).Item2?.Index; + int? xSourceIndex = GetSourceForItem(x.Key).Value?.Index; + int? ySourceIndex = GetSourceForItem(y.Key).Value?.Index; return (norename ? nc.Compare(xMachineName, yMachineName) : (xSourceIndex - ySourceIndex) ?? 0); } catch @@ -1200,15 +1200,15 @@ namespace SabreTools.DatFiles /// Item to try to match /// True if the DAT is already sorted accordingly, false otherwise (default) /// Key to try to use - private string SortAndGetKey((long, DatItem) datItem, bool sorted = false) + private string SortAndGetKey(KeyValuePair datItem, bool sorted = false) { // If we're not already sorted, take care of it if (!sorted) BucketBy(GetBestAvailable(), DedupeType.None); // Now that we have the sorted type, we get the proper key - var source = GetSourceForItem(datItem.Item1); - return datItem.Item2.GetKey(_bucketedBy, source.Item2); + var source = GetSourceForItem(datItem.Key); + return datItem.Value.GetKey(_bucketedBy, source.Value); } #endregion @@ -1285,16 +1285,16 @@ namespace SabreTools.DatFiles foreach (string key in SortedKeys) { var items = GetItemsForBucket(key); - if (items == null || items.Length == 0) + if (items == null || items.Count == 0) continue; - var item = items[0]; - var machine = GetMachineForItem(item.Item1); - if (machine.Item2 == null) + var item = items.First(); + var machine = GetMachineForItem(item.Key); + if (machine.Value == null) continue; // Get machine information - Machine? machineObj = machine.Item2.GetFieldValue(DatItem.MachineKey); + Machine? machineObj = machine.Value.GetFieldValue(DatItem.MachineKey); string? machineName = machineObj?.GetStringFieldValue(Models.Metadata.Machine.NameKey)?.ToLowerInvariant(); if (machineObj == null || machineName == null) continue; @@ -1380,9 +1380,9 @@ namespace SabreTools.DatFiles continue; #endif - for (int i = 0; i < items.Length; i++) + foreach (var item in items) { - SetOneRomPerGame(items[i]); + SetOneRomPerGame(item); } #if NET40_OR_GREATER || NETCOREAPP }); @@ -1416,23 +1416,23 @@ namespace SabreTools.DatFiles continue; #endif - for (int j = 0; j < items.Length; j++) + List itemIds = []; + foreach (var item in items) { - var item = items[j]; - var machine = GetMachineForItem(item.Item1); - if (machine.Item2 == null) + var machine = GetMachineForItem(item.Key); + if (machine.Value == null) continue; - if (Regex.IsMatch(machine.Item2.GetStringFieldValue(Models.Metadata.Machine.NameKey)!, pattern)) - machine.Item2.SetFieldValue(Models.Metadata.Machine.NameKey, Regex.Replace(machine.Item2.GetStringFieldValue(Models.Metadata.Machine.NameKey)!, pattern, "$2")); + if (Regex.IsMatch(machine.Value.GetStringFieldValue(Models.Metadata.Machine.NameKey)!, pattern)) + machine.Value.SetFieldValue(Models.Metadata.Machine.NameKey, Regex.Replace(machine.Value.GetStringFieldValue(Models.Metadata.Machine.NameKey)!, pattern, "$2")); - if (Regex.IsMatch(machine.Item2.GetStringFieldValue(Models.Metadata.Machine.DescriptionKey)!, pattern)) - machine.Item2.SetFieldValue(Models.Metadata.Machine.DescriptionKey, Regex.Replace(machine.Item2.GetStringFieldValue(Models.Metadata.Machine.DescriptionKey)!, pattern, "$2")); + if (Regex.IsMatch(machine.Value.GetStringFieldValue(Models.Metadata.Machine.DescriptionKey)!, pattern)) + machine.Value.SetFieldValue(Models.Metadata.Machine.DescriptionKey, Regex.Replace(machine.Value.GetStringFieldValue(Models.Metadata.Machine.DescriptionKey)!, pattern, "$2")); - items[j] = item; + itemIds.Add(item.Key); } - _buckets[key] = [.. Array.ConvertAll(items, i => i.Item1)]; + _buckets[key] = itemIds; #if NET40_OR_GREATER || NETCOREAPP }); #else @@ -1466,20 +1466,20 @@ namespace SabreTools.DatFiles continue; #endif - foreach ((long, DatItem) item in items) + foreach (var item in items) { // Get the current machine - var machine = GetMachineForItem(item.Item1); - if (machine.Item2 == null) + var machine = GetMachineForItem(item.Key); + if (machine.Value == null) continue; // If the key mapping doesn't exist, add it #if NET40_OR_GREATER || NETCOREAPP - mapping.TryAdd(machine.Item2.GetStringFieldValue(Models.Metadata.Machine.NameKey)!, - machine.Item2.GetStringFieldValue(Models.Metadata.Machine.DescriptionKey)!.Replace('/', '_').Replace("\"", "''").Replace(":", " -")); + mapping.TryAdd(machine.Value.GetStringFieldValue(Models.Metadata.Machine.NameKey)!, + machine.Value.GetStringFieldValue(Models.Metadata.Machine.DescriptionKey)!.Replace('/', '_').Replace("\"", "''").Replace(":", " -")); #else - mapping[machine.Item2.GetStringFieldValue(Models.Metadata.Machine.NameKey)!] - = machine.Item2.GetStringFieldValue(Models.Metadata.Machine.DescriptionKey)!.Replace('/', '_').Replace("\"", "''").Replace(":", " -"); + mapping[machine.Value.GetStringFieldValue(Models.Metadata.Machine.NameKey)!] + = machine.Value.GetStringFieldValue(Models.Metadata.Machine.DescriptionKey)!.Replace('/', '_').Replace("\"", "''").Replace(":", " -"); #endif } #if NET40_OR_GREATER || NETCOREAPP @@ -1498,42 +1498,42 @@ namespace SabreTools.DatFiles /// Name of the bucket to filter on private void ExecuteFilterOnBucket(FilterRunner filterRunner, string bucketName) { - (long, DatItem)[]? items = GetItemsForBucket(bucketName); + var items = GetItemsForBucket(bucketName); if (items == null) return; // Filter all items in the current key - var newItems = new List<(long, DatItem)>(); + List newItems = []; foreach (var item in items) { - if (item.Item2.PassesFilter(filterRunner)) - newItems.Add(item); + if (item.Value.PassesFilter(filterRunner)) + newItems.Add(item.Key); } // Set the value in the key to the new set - _buckets[bucketName] = newItems.ConvertAll(i => i.Item1); + _buckets[bucketName] = newItems; } /// /// Set internal names to match One Rom Per Game (ORPG) logic /// /// DatItem to run logic on - private void SetOneRomPerGame((long, DatItem) datItem) + private void SetOneRomPerGame(KeyValuePair datItem) { - if (datItem.Item1 < 0 || datItem.Item2.GetName() == null) + if (datItem.Key < 0 || datItem.Value.GetName() == null) return; // Get the current machine - var machine = GetMachineForItem(datItem.Item1); - if (machine.Item2 == null) + var machine = GetMachineForItem(datItem.Key); + if (machine.Value == null) return; // Remove extensions from Rom items - string machineName = datItem.Item2.GetName()!; - if (datItem.Item2 is Rom) + string machineName = datItem.Value.GetName()!; + if (datItem.Value is Rom) { string[] splitname = machineName.Split('.'); - machineName = datItem.Item2.GetFieldValue(DatItem.MachineKey)! + machineName = datItem.Value.GetFieldValue(DatItem.MachineKey)! .GetStringFieldValue(Models.Metadata.Machine.NameKey) + $"/{string.Join(".", splitname, 0, splitname.Length > 1 ? splitname.Length - 1 : 1)}"; } @@ -1542,8 +1542,8 @@ namespace SabreTools.DatFiles if (machineName.StartsWith("Default")) machineName = machineName.Substring("Default".Length + 1); - machine.Item2.SetFieldValue(Models.Metadata.Machine.NameKey, machineName); - datItem.Item2.SetName(Path.GetFileName(datItem.Item2.GetName())); + machine.Value.SetFieldValue(Models.Metadata.Machine.NameKey, machineName); + datItem.Value.SetName(Path.GetFileName(datItem.Value.GetName())); } /// @@ -1567,36 +1567,36 @@ namespace SabreTools.DatFiles continue; #endif - List<(long, DatItem)> newItems = []; - foreach ((long, DatItem) item in items) + List newItems = []; + foreach (var item in items) { // Get the current machine - var machine = GetMachineForItem(item.Item1); - if (machine.Item2 == null) + var machine = GetMachineForItem(item.Key); + if (machine.Value == null) continue; // Update machine name - if (!string.IsNullOrEmpty(machine.Item2.GetStringFieldValue(Models.Metadata.Machine.NameKey)) && mapping.ContainsKey(machine.Item2.GetStringFieldValue(Models.Metadata.Machine.NameKey)!)) - machine.Item2.SetFieldValue(Models.Metadata.Machine.NameKey, mapping[machine.Item2.GetStringFieldValue(Models.Metadata.Machine.NameKey)!]); + if (!string.IsNullOrEmpty(machine.Value.GetStringFieldValue(Models.Metadata.Machine.NameKey)) && mapping.ContainsKey(machine.Value.GetStringFieldValue(Models.Metadata.Machine.NameKey)!)) + machine.Value.SetFieldValue(Models.Metadata.Machine.NameKey, mapping[machine.Value.GetStringFieldValue(Models.Metadata.Machine.NameKey)!]); // Update cloneof - if (!string.IsNullOrEmpty(machine.Item2.GetStringFieldValue(Models.Metadata.Machine.CloneOfKey)) && mapping.ContainsKey(machine.Item2.GetStringFieldValue(Models.Metadata.Machine.CloneOfKey)!)) - machine.Item2.SetFieldValue(Models.Metadata.Machine.CloneOfKey, mapping[machine.Item2.GetStringFieldValue(Models.Metadata.Machine.CloneOfKey)!]); + if (!string.IsNullOrEmpty(machine.Value.GetStringFieldValue(Models.Metadata.Machine.CloneOfKey)) && mapping.ContainsKey(machine.Value.GetStringFieldValue(Models.Metadata.Machine.CloneOfKey)!)) + machine.Value.SetFieldValue(Models.Metadata.Machine.CloneOfKey, mapping[machine.Value.GetStringFieldValue(Models.Metadata.Machine.CloneOfKey)!]); // Update romof - if (!string.IsNullOrEmpty(machine.Item2.GetStringFieldValue(Models.Metadata.Machine.RomOfKey)) && mapping.ContainsKey(machine.Item2.GetStringFieldValue(Models.Metadata.Machine.RomOfKey)!)) - machine.Item2.SetFieldValue(Models.Metadata.Machine.RomOfKey, mapping[machine.Item2.GetStringFieldValue(Models.Metadata.Machine.RomOfKey)!]); + if (!string.IsNullOrEmpty(machine.Value.GetStringFieldValue(Models.Metadata.Machine.RomOfKey)) && mapping.ContainsKey(machine.Value.GetStringFieldValue(Models.Metadata.Machine.RomOfKey)!)) + machine.Value.SetFieldValue(Models.Metadata.Machine.RomOfKey, mapping[machine.Value.GetStringFieldValue(Models.Metadata.Machine.RomOfKey)!]); // Update sampleof - if (!string.IsNullOrEmpty(machine.Item2.GetStringFieldValue(Models.Metadata.Machine.SampleOfKey)) && mapping.ContainsKey(machine.Item2.GetStringFieldValue(Models.Metadata.Machine.SampleOfKey)!)) - machine.Item2.SetFieldValue(Models.Metadata.Machine.SampleOfKey, mapping[machine.Item2.GetStringFieldValue(Models.Metadata.Machine.SampleOfKey)!]); + if (!string.IsNullOrEmpty(machine.Value.GetStringFieldValue(Models.Metadata.Machine.SampleOfKey)) && mapping.ContainsKey(machine.Value.GetStringFieldValue(Models.Metadata.Machine.SampleOfKey)!)) + machine.Value.SetFieldValue(Models.Metadata.Machine.SampleOfKey, mapping[machine.Value.GetStringFieldValue(Models.Metadata.Machine.SampleOfKey)!]); // Add the new item to the output list - newItems.Add(item); + newItems.Add(item.Key); } // Replace the old list of roms with the new one - _buckets[key] = newItems.ConvertAll(i => i.Item1); + _buckets[key] = newItems; #if NET40_OR_GREATER || NETCOREAPP }); #else @@ -1618,35 +1618,35 @@ namespace SabreTools.DatFiles { // Get the items for this game var items = GetItemsForBucket(game); - if (items == null || items.Length == 0) + if (items == null || items.Count == 0) continue; // Get the source for the first item - var source = GetSourceForItem(items[0].Item1); + var source = GetSourceForItem(items.First().Key); // Get the machine for the first item - var machine = GetMachineForItem(items[0].Item1); - if (machine.Item2 == null) + var machine = GetMachineForItem(items.First().Key); + if (machine.Value == null) continue; // Get the bios parent - string? romOf = machine.Item2.GetStringFieldValue(Models.Metadata.Machine.RomOfKey); + string? romOf = machine.Value.GetStringFieldValue(Models.Metadata.Machine.RomOfKey); if (string.IsNullOrEmpty(romOf)) continue; // If the parent doesn't have any items, we want to continue var parentItems = GetItemsForBucket(romOf!); - if (parentItems == null || parentItems.Length == 0) + if (parentItems == null || parentItems.Count == 0) continue; // If the parent exists and has items, we copy the items from the parent to the current game - foreach ((long, DatItem) item in parentItems) + foreach (var item in parentItems) { - DatItem datItem = (item.Item2.Clone() as DatItem)!; - if (Array.FindIndex(items, i => i.Item2.GetName() == datItem.GetName()) > -1 - && Array.FindIndex(items, i => i.Item2 == datItem) > -1) + DatItem datItem = (item.Value.Clone() as DatItem)!; + if (items.Any(i => i.Value.GetName() == datItem.GetName()) + && items.Any(i => i.Value == datItem)) { - AddItem(datItem, machine.Item1, source.Item1); + AddItem(datItem, machine.Key, source.Key); } } } @@ -1665,35 +1665,34 @@ namespace SabreTools.DatFiles { // If the game has no items in it, we want to continue var items = GetItemsForBucket(game); - if (items == null || items.Length == 0) + if (items == null || items.Count == 0) continue; // Get the source for the first item - var source = GetSourceForItem(items[0].Item1); + var source = GetSourceForItem(items.First().Key); // Get the machine for the first item - var machine = GetMachineForItem(items[0].Item1); - if (machine.Item2 == null) + var machine = GetMachineForItem(items.First().Key); + if (machine.Value == null) continue; // If the machine (is/is not) a device, we want to continue - if (dev ^ (machine.Item2.GetBoolFieldValue(Models.Metadata.Machine.IsDeviceKey) == true)) + if (dev ^ (machine.Value.GetBoolFieldValue(Models.Metadata.Machine.IsDeviceKey) == true)) continue; // Get all device reference names from the current machine - List<(long, DatItem)> itemsList = [.. items]; - List deviceReferences = itemsList - .FindAll(i => i.Item2 is DeviceRef) - .ConvertAll(i => i.Item2 as DeviceRef) - .ConvertAll(dr => dr!.GetName()) + List deviceReferences = items.Values + .Where(i => i is DeviceRef) + .Select(i => i as DeviceRef) + .Select(dr => dr!.GetName()) .Distinct() .ToList(); // Get all slot option names from the current machine - List slotOptions = itemsList - .FindAll(i => i.Item2 is Slot) - .ConvertAll(i => i.Item2 as Slot) - .FindAll(s => s!.SlotOptionsSpecified) + List slotOptions = items.Values + .Where(i => i is Slot) + .Select(i => i as Slot) + .Where(s => s!.SlotOptionsSpecified) .SelectMany(s => s!.GetFieldValue(Models.Metadata.Slot.SlotOptionKey)!) .Select(so => so.GetStringFieldValue(Models.Metadata.SlotOption.DevNameKey)) .Distinct() @@ -1712,33 +1711,31 @@ namespace SabreTools.DatFiles // If the machine doesn't exist then we continue var devItems = GetItemsForBucket(deviceReference); - if (devItems == null || devItems.Length == 0) + if (devItems == null || devItems.Count == 0) continue; // Add to the list of new device reference names - List<(long, DatItem)> devItemsList = [.. devItems]; - newDeviceReferences.UnionWith(devItemsList - .FindAll(i => i.Item2 is DeviceRef) - .ConvertAll(i => (i.Item2 as DeviceRef)!.GetName()!)); + newDeviceReferences.UnionWith(devItems.Values + .Where(i => i is DeviceRef) + .Select(i => (i as DeviceRef)!.GetName()!)); // Set new machine information and add to the current machine - var copyFrom = GetMachineForItem(items[0].Item1); - if (copyFrom.Item2 == null) + var copyFrom = GetMachineForItem(items.First().Key); + if (copyFrom.Value == null) continue; - foreach ((long, DatItem) item in devItems) + foreach (var item in devItems.Values) { // If the parent machine doesn't already contain this item, add it - if (!Array.Exists(items, - i => i.Item2.GetStringFieldValue(Models.Metadata.DatItem.TypeKey) == item.Item2.GetStringFieldValue(Models.Metadata.DatItem.TypeKey) - && i.Item2.GetName() == item.Item2.GetName())) + if (!items.Values.Any(i => i.GetStringFieldValue(Models.Metadata.DatItem.TypeKey) == item.GetStringFieldValue(Models.Metadata.DatItem.TypeKey) + && i.GetName() == item.GetName())) { // Set that we found new items foundnew = true; // Clone the item and then add it - DatItem datItem = (item.Item2.Clone() as DatItem)!; - AddItem(datItem, machine.Item1, source.Item1); + DatItem datItem = (item.Clone() as DatItem)!; + AddItem(datItem, machine.Key, source.Key); } } } @@ -1750,7 +1747,7 @@ namespace SabreTools.DatFiles { var deviceRef = new DeviceRef(); deviceRef.SetName(deviceReference); - AddItem(deviceRef, machine.Item1, source.Item1); + AddItem(deviceRef, machine.Key, source.Key); } } } @@ -1768,35 +1765,33 @@ namespace SabreTools.DatFiles // If the machine doesn't exist then we continue var slotItems = GetItemsForBucket(slotOption); - if (slotItems == null || slotItems.Length == 0) + if (slotItems == null || slotItems.Count == 0) continue; // Add to the list of new slot option names - List<(long, DatItem)> slotItemsList = [.. slotItems]; - newSlotOptions.UnionWith(slotItemsList - .FindAll(i => i.Item2 is Slot) - .FindAll(s => (s.Item2 as Slot)!.SlotOptionsSpecified) - .SelectMany(s => (s.Item2 as Slot)!.GetFieldValue(Models.Metadata.Slot.SlotOptionKey)!) + newSlotOptions.UnionWith(slotItems.Values + .Where(i => i is Slot) + .Where(s => (s as Slot)!.SlotOptionsSpecified) + .SelectMany(s => (s as Slot)!.GetFieldValue(Models.Metadata.Slot.SlotOptionKey)!) .Select(o => o.GetStringFieldValue(Models.Metadata.SlotOption.DevNameKey)!)); // Set new machine information and add to the current machine - var copyFrom = GetMachineForItem(GetItemsForBucket(game)![0].Item1); - if (copyFrom.Item2 == null) + var copyFrom = GetMachineForItem(GetItemsForBucket(game)!.First().Key); + if (copyFrom.Value == null) continue; - foreach ((long, DatItem) item in slotItems) + foreach (var item in slotItems.Values) { // If the parent machine doesn't already contain this item, add it - if (!Array.Exists(items, - i => i.Item2.GetStringFieldValue(Models.Metadata.DatItem.TypeKey) == item.Item2.GetStringFieldValue(Models.Metadata.DatItem.TypeKey) - && i.Item2.GetName() == item.Item2.GetName())) + if (!items.Values.Any(i => i.GetStringFieldValue(Models.Metadata.DatItem.TypeKey) == item.GetStringFieldValue(Models.Metadata.DatItem.TypeKey) + && i.GetName() == item.GetName())) { // Set that we found new items foundnew = true; // Clone the item and then add it - DatItem datItem = (item.Item2.Clone() as DatItem)!; - AddItem(datItem, machine.Item1, source.Item1); + DatItem datItem = (item.Clone() as DatItem)!; + AddItem(datItem, machine.Key, source.Key); } } } @@ -1812,7 +1807,7 @@ namespace SabreTools.DatFiles var slotItem = new Slot(); slotItem.SetFieldValue(Models.Metadata.Slot.SlotOptionKey, [slotOptionItem]); - AddItem(slotItem, machine.Item1, source.Item1); + AddItem(slotItem, machine.Key, source.Key); } } } @@ -1831,53 +1826,53 @@ namespace SabreTools.DatFiles { // If the game has no items in it, we want to continue var items = GetItemsForBucket(game); - if (items == null || items.Length == 0) + if (items == null || items.Count == 0) continue; // Get the source for the first item - var source = GetSourceForItem(items[0].Item1); + var source = GetSourceForItem(items.First().Key); // Get the machine for the first item in the list - var machine = GetMachineForItem(items[0].Item1); - if (machine.Item2 == null) + var machine = GetMachineForItem(items.First().Key); + if (machine.Value == null) continue; // Get the clone parent - string? cloneOf = machine.Item2.GetStringFieldValue(Models.Metadata.Machine.CloneOfKey); + string? cloneOf = machine.Value.GetStringFieldValue(Models.Metadata.Machine.CloneOfKey); if (string.IsNullOrEmpty(cloneOf)) continue; // If the parent doesn't have any items, we want to continue var parentItems = GetItemsForBucket(cloneOf!); - if (parentItems == null || parentItems.Length == 0) + if (parentItems == null || parentItems.Count == 0) continue; // If the parent exists and has items, we copy the items from the parent to the current game foreach (var item in parentItems) { - DatItem datItem = (DatItem)item.Item2.Clone(); - if (Array.FindIndex(items, i => i.Item2.GetName()?.ToLowerInvariant() == datItem.GetName()?.ToLowerInvariant()) > -1 - && Array.FindIndex(items, i => i.Item2 == datItem) > -1) + DatItem datItem = (DatItem)item.Value.Clone(); + if (items.Values.Any(i => i.GetName()?.ToLowerInvariant() == datItem.GetName()?.ToLowerInvariant()) + && items.Values.Any(i => i == datItem)) { - AddItem(datItem, machine.Item1, source.Item1); + AddItem(datItem, machine.Key, source.Key); } } // Get the parent machine - var parentMachine = GetMachineForItem(GetItemsForBucket(cloneOf!)![0].Item1); - if (parentMachine.Item2 == null) + var parentMachine = GetMachineForItem(GetItemsForBucket(cloneOf!)!.First().Key); + if (parentMachine.Value == null) continue; // Now we want to get the parent romof tag and put it in each of the items items = GetItemsForBucket(game); - string? romof = parentMachine.Item2.GetStringFieldValue(Models.Metadata.Machine.RomOfKey); - foreach ((long, DatItem) item in items!) + string? romof = parentMachine.Value.GetStringFieldValue(Models.Metadata.Machine.RomOfKey); + foreach (var key in items.Keys) { - var itemMachine = GetMachineForItem(item.Item1); - if (itemMachine.Item2 == null) + var itemMachine = GetMachineForItem(key); + if (itemMachine.Value == null) continue; - itemMachine.Item2.SetFieldValue(Models.Metadata.Machine.RomOfKey, romof); + itemMachine.Value.SetFieldValue(Models.Metadata.Machine.RomOfKey, romof); } } } @@ -1894,111 +1889,111 @@ namespace SabreTools.DatFiles { // If the game has no items in it, we want to continue var items = GetItemsForBucket(game); - if (items == null || items.Length == 0) + if (items == null || items.Count == 0) continue; // Get the machine for the first item - var machine = GetMachineForItem(items[0].Item1); - if (machine.Item2 == null) + var machine = GetMachineForItem(items.First().Key); + if (machine.Value == null) continue; // Get the clone parent - string? cloneOf = machine.Item2.GetStringFieldValue(Models.Metadata.Machine.CloneOfKey); + string? cloneOf = machine.Value.GetStringFieldValue(Models.Metadata.Machine.CloneOfKey); if (string.IsNullOrEmpty(cloneOf)) continue; // Get the clone parent machine var cloneOfMachine = GetMachine(cloneOf); - if (cloneOfMachine.Item2 == null) + if (cloneOfMachine.Value == null) continue; items = GetItemsForBucket(game); - foreach ((long, DatItem) item in items!) + foreach (var item in items) { // Get the parent items and current machine name var parentItems = GetItemsForBucket(cloneOf!); - if (parentItems == null || parentItems.Length == 0) + if (parentItems == null || parentItems.Count == 0) continue; - List<(long, DatItem)> parentItemslist = [.. parentItems]; - string? machineName = GetMachineForItem(item.Item1).Item2?.GetStringFieldValue(Models.Metadata.Machine.NameKey); + string? machineName = GetMachineForItem(item.Key).Value? + .GetStringFieldValue(Models.Metadata.Machine.NameKey); // Special disk handling - if (item.Item2 is Disk disk) + if (item.Value is Disk disk) { string? mergeTag = disk.GetStringFieldValue(Models.Metadata.Disk.MergeKey); // If the merge tag exists and the parent already contains it, skip - if (mergeTag != null && parentItemslist - .FindAll(i => i.Item2 is Disk) - .ConvertAll(i => (i.Item2 as Disk)!.GetName()) + if (mergeTag != null && parentItems.Values + .Where(i => i is Disk) + .Select(i => (i as Disk)!.GetName()) .Contains(mergeTag)) { continue; } // If the merge tag exists but the parent doesn't contain it, add to parent - else if (mergeTag != null && !parentItemslist - .FindAll(i => i.Item2 is Disk) - .ConvertAll(i => (i.Item2 as Disk)!.GetName()) + else if (mergeTag != null && !parentItems.Values + .Where(i => i is Disk) + .Select(i => (i as Disk)!.GetName()) .Contains(mergeTag)) { - _itemToMachineMapping[item.Item1] = cloneOfMachine.Item1; - _buckets[cloneOf!].Add(item.Item1); + _itemToMachineMapping[item.Key] = cloneOfMachine.Key; + _buckets[cloneOf!].Add(item.Key); } // If there is no merge tag, add to parent else if (mergeTag == null) { - _itemToMachineMapping[item.Item1] = cloneOfMachine.Item1; - _buckets[cloneOf!].Add(item.Item1); + _itemToMachineMapping[item.Key] = cloneOfMachine.Key; + _buckets[cloneOf!].Add(item.Key); } } // Special rom handling - else if (item.Item2 is Rom rom) + else if (item.Value is Rom rom) { // If the merge tag exists and the parent already contains it, skip - if (rom.GetStringFieldValue(Models.Metadata.Rom.MergeKey) != null && parentItemslist - .FindAll(i => i.Item2 is Rom) - .ConvertAll(i => (i.Item2 as Rom)!.GetName()) + if (rom.GetStringFieldValue(Models.Metadata.Rom.MergeKey) != null && parentItems.Values + .Where(i => i is Rom) + .Select(i => (i as Rom)!.GetName()) .Contains(rom.GetStringFieldValue(Models.Metadata.Rom.MergeKey))) { continue; } // If the merge tag exists but the parent doesn't contain it, add to subfolder of parent - else if (rom.GetStringFieldValue(Models.Metadata.Rom.MergeKey) != null && !parentItemslist - .FindAll(i => i.Item2 is Rom) - .ConvertAll(i => (i.Item2 as Rom)!.GetName()) + else if (rom.GetStringFieldValue(Models.Metadata.Rom.MergeKey) != null && !parentItems.Values + .Where(i => i is Rom) + .Select(i => (i as Rom)!.GetName()) .Contains(rom.GetStringFieldValue(Models.Metadata.Rom.MergeKey))) { if (subfolder) rom.SetName($"{machineName}\\{rom.GetName()}"); - _itemToMachineMapping[item.Item1] = cloneOfMachine.Item1; - _buckets[cloneOf!].Add(item.Item1); + _itemToMachineMapping[item.Key] = cloneOfMachine.Key; + _buckets[cloneOf!].Add(item.Key); } // If the parent doesn't already contain this item, add to subfolder of parent - else if (Array.IndexOf(parentItems, item) == -1 || skipDedup) + else if (!parentItems.Contains(item) || skipDedup) { if (subfolder) rom.SetName($"{machineName}\\{rom.GetName()}"); - _itemToMachineMapping[item.Item1] = cloneOfMachine.Item1; - _buckets[cloneOf!].Add(item.Item1); + _itemToMachineMapping[item.Key] = cloneOfMachine.Key; + _buckets[cloneOf!].Add(item.Key); } } // All other that would be missing to subfolder of parent - else if (parentItemslist.IndexOf(item) == -1) + else if (!parentItems.Contains(item)) { if (subfolder) - item.Item2.SetName($"{machineName}\\{item.Item2.GetName()}"); + item.Value.SetName($"{machineName}\\{item.Value.GetName()}"); - _itemToMachineMapping[item.Item1] = cloneOfMachine.Item1; - _buckets[cloneOf!].Add(item.Item1); + _itemToMachineMapping[item.Key] = cloneOfMachine.Key; + _buckets[cloneOf!].Add(item.Key); } } @@ -2021,21 +2016,21 @@ namespace SabreTools.DatFiles { // If the game has no items in it, we want to continue var items = GetItemsForBucket(game); - if (items == null || items.Length == 0) + if (items == null || items.Count == 0) continue; // Get the machine - var machine = GetMachineForItem(items[0].Item1); - if (machine.Item2 == null) + var machine = GetMachineForItem(items.First().Key); + if (machine.Value == null) continue; // Remove flagged items - if ((machine.Item2.GetBoolFieldValue(Models.Metadata.Machine.IsBiosKey) == true) - || (machine.Item2.GetBoolFieldValue(Models.Metadata.Machine.IsDeviceKey) == true)) + if ((machine.Value.GetBoolFieldValue(Models.Metadata.Machine.IsBiosKey) == true) + || (machine.Value.GetBoolFieldValue(Models.Metadata.Machine.IsDeviceKey) == true)) { - foreach (var item in items) + foreach (var key in items.Keys) { - RemoveItem(item.Item1); + RemoveItem(key); } } } @@ -2053,35 +2048,35 @@ namespace SabreTools.DatFiles { // If the game has no items in it, we want to continue var items = GetItemsForBucket(game); - if (items == null || items.Length == 0) + if (items == null || items.Count == 0) continue; // Get the machine for the item - var machine = GetMachineForItem(items[0].Item1); - if (machine.Item2 == null) + var machine = GetMachineForItem(items.First().Key); + if (machine.Value == null) continue; // If the game (is/is not) a bios, we want to continue - if (bios ^ (machine.Item2.GetBoolFieldValue(Models.Metadata.Machine.IsBiosKey) == true)) + if (bios ^ (machine.Value.GetBoolFieldValue(Models.Metadata.Machine.IsBiosKey) == true)) continue; // Get the bios parent - string? romOf = machine.Item2.GetStringFieldValue(Models.Metadata.Machine.RomOfKey); + string? romOf = machine.Value.GetStringFieldValue(Models.Metadata.Machine.RomOfKey); if (string.IsNullOrEmpty(romOf)) continue; // If the parent doesn't have any items, we want to continue var parentItems = GetItemsForBucket(romOf!); - if (parentItems == null || parentItems.Length == 0) + if (parentItems == null || parentItems.Count == 0) continue; // If the parent exists and has items, we remove the items that are in the parent from the current game - foreach ((long, DatItem) item in parentItems) + foreach (var item in parentItems) { - var matchedItems = Array.FindAll(items, i => i.Item2 == item.Item2); - foreach ((long index, _) in matchedItems) + var matchedItems = items.Where(i => i.Value == item.Value); + foreach (var match in matchedItems) { - RemoveItem(index); + RemoveItem(match.Key); } } } @@ -2097,48 +2092,48 @@ namespace SabreTools.DatFiles { // If the game has no items in it, we want to continue var items = GetItemsForBucket(game); - if (items == null || items.Length == 0) + if (items == null || items.Count == 0) continue; // Get the machine for the first item - var machine = GetMachineForItem(items[0].Item1); - if (machine.Item2 == null) + var machine = GetMachineForItem(items.First().Key); + if (machine.Value == null) continue; // Get the clone parent - string? cloneOf = machine.Item2.GetStringFieldValue(Models.Metadata.Machine.CloneOfKey); + string? cloneOf = machine.Value.GetStringFieldValue(Models.Metadata.Machine.CloneOfKey); if (string.IsNullOrEmpty(cloneOf)) continue; // If the parent doesn't have any items, we want to continue var parentItems = GetItemsForBucket(cloneOf!); - if (parentItems == null || parentItems.Length == 0) + if (parentItems == null || parentItems.Count == 0) continue; // If the parent exists and has items, we remove the parent items from the current game - foreach ((long, DatItem) item in parentItems) + foreach (var item in parentItems) { - var matchedItems = Array.FindAll(items, i => i.Item2 == item.Item2); - foreach ((long index, _) in matchedItems) + var matchedItems = items.Where(i => i.Value == item.Value); + foreach (var match in matchedItems) { - RemoveItem(index); + RemoveItem(match.Key); } } // Now we want to get the parent romof tag and put it in each of the remaining items items = GetItemsForBucket(game); - machine = GetMachineForItem(GetItemsForBucket(cloneOf!)![0].Item1); - if (machine.Item2 == null) + machine = GetMachineForItem(GetItemsForBucket(cloneOf!)!.First().Key); + if (machine.Value == null) continue; - string? romof = machine.Item2.GetStringFieldValue(Models.Metadata.Machine.RomOfKey); - foreach ((long, DatItem) item in items!) + string? romof = machine.Value.GetStringFieldValue(Models.Metadata.Machine.RomOfKey); + foreach (var item in items!) { - machine = GetMachineForItem(item.Item1); - if (machine.Item2 == null) + machine = GetMachineForItem(item.Key); + if (machine.Value == null) continue; - machine.Item2.SetFieldValue(Models.Metadata.Machine.RomOfKey, romof); + machine.Value.SetFieldValue(Models.Metadata.Machine.RomOfKey, romof); } } } @@ -2153,18 +2148,18 @@ namespace SabreTools.DatFiles { // If the game has no items in it, we want to continue var items = GetItemsForBucket(game); - if (items == null || items.Length == 0) + if (items == null || items.Count == 0) continue; - foreach ((long, DatItem) item in items) + foreach (long id in items.Keys) { - var machine = GetMachineForItem(item.Item1); - if (machine.Item2 == null) + var machine = GetMachineForItem(id); + if (machine.Value == null) continue; - machine.Item2.SetFieldValue(Models.Metadata.Machine.CloneOfKey, null); - machine.Item2.SetFieldValue(Models.Metadata.Machine.RomOfKey, null); - machine.Item2.SetFieldValue(Models.Metadata.Machine.SampleOfKey, null); + machine.Value.SetFieldValue(Models.Metadata.Machine.CloneOfKey, null); + machine.Value.SetFieldValue(Models.Metadata.Machine.RomOfKey, null); + machine.Value.SetFieldValue(Models.Metadata.Machine.SampleOfKey, null); } } } diff --git a/SabreTools.DatItems/DatItem.cs b/SabreTools.DatItems/DatItem.cs index 7e6b021f..3e9f240c 100644 --- a/SabreTools.DatItems/DatItem.cs +++ b/SabreTools.DatItems/DatItem.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Linq; using System.Reflection; using System.Xml.Serialization; using Newtonsoft.Json; @@ -729,45 +730,43 @@ namespace SabreTools.DatItems /// /// List of File objects representing the roms to be merged /// A List of DatItem objects representing the renamed roms - public static List<(long, DatItem)> ResolveNamesDB(List<(long, DatItem)> infiles) + public static List> ResolveNamesDB(List> infiles) { - // Create the output list - List<(long, DatItem)> output = []; + // Create the output dict + List> output = []; // First we want to make sure the list is in alphabetical order Sort(ref infiles, true); // Now we want to loop through and check names - (long, DatItem?) lastItem = (-1, null); + DatItem? lastItem = null; string? lastrenamed = null; int lastid = 0; - for (int i = 0; i < infiles.Count; i++) + foreach (var datItem in infiles) { - var datItem = infiles[i]; - // If we have the first item, we automatically add it - if (lastItem.Item2 == null) + if (lastItem == null) { output.Add(datItem); - lastItem = datItem; + lastItem = datItem.Value; continue; } // Get the last item name, if applicable - string lastItemName = lastItem.Item2.GetName() - ?? lastItem.Item2.GetStringFieldValue(Models.Metadata.DatItem.TypeKey).AsEnumValue().AsStringValue() + string lastItemName = lastItem.GetName() + ?? lastItem.GetStringFieldValue(Models.Metadata.DatItem.TypeKey).AsEnumValue().AsStringValue() ?? string.Empty; // Get the current item name, if applicable - string datItemName = datItem.Item2.GetName() - ?? datItem.Item2.GetStringFieldValue(Models.Metadata.DatItem.TypeKey).AsEnumValue().AsStringValue() + string datItemName = datItem.Value.GetName() + ?? datItem.Value.GetStringFieldValue(Models.Metadata.DatItem.TypeKey).AsEnumValue().AsStringValue() ?? string.Empty; // If the current item exactly matches the last item, then we don't add it #if NETFRAMEWORK - if ((datItem.Item2.GetDuplicateStatus(lastItem.Item2) & DupeType.All) != 0) + if ((datItem.Value.GetDuplicateStatus(lastItem) & DupeType.All) != 0) #else - if (datItem.Item2.GetDuplicateStatus(lastItem.Item2).HasFlag(DupeType.All)) + if (datItem.Value.GetDuplicateStatus(lastItem).HasFlag(DupeType.All)) #endif { staticLogger.Verbose($"Exact duplicate found for '{datItemName}'"); @@ -779,9 +778,9 @@ namespace SabreTools.DatItems { staticLogger.Verbose($"Name duplicate found for '{datItemName}'"); - if (datItem.Item2 is Disk || datItem.Item2 is Formats.File || datItem.Item2 is Media || datItem.Item2 is Rom) + if (datItem.Value is Disk || datItem.Value is Formats.File || datItem.Value is Media || datItem.Value is Rom) { - datItemName += GetDuplicateSuffix(datItem.Item2); + datItemName += GetDuplicateSuffix(datItem.Value); lastrenamed ??= datItemName; } @@ -800,8 +799,7 @@ namespace SabreTools.DatItems } // Set the item name back to the datItem - datItem.Item2.SetName(datItemName); - + datItem.Value.SetName(datItemName); output.Add(datItem); } @@ -809,7 +807,7 @@ namespace SabreTools.DatItems else { output.Add(datItem); - lastItem = datItem; + lastItem = datItem.Value; lastrenamed = null; lastid = 0; } @@ -895,41 +893,41 @@ namespace SabreTools.DatItems /// List of File objects representing the roms to be sorted /// True if files are not renamed, false otherwise /// True if it sorted correctly, false otherwise - public static bool Sort(ref List<(long, DatItem)> roms, bool norename) + public static bool Sort(ref List> roms, bool norename) { - roms.Sort(delegate ((long, DatItem) x, (long, DatItem) y) + roms.Sort(delegate (KeyValuePair x, KeyValuePair y) { try { var nc = new NaturalComparer(); // If machine names don't match - string? xMachineName = x.Item2.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.NameKey); - string? yMachineName = y.Item2.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.NameKey); + string? xMachineName = x.Value.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.NameKey); + string? yMachineName = y.Value.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.NameKey); if (xMachineName != yMachineName) return nc.Compare(xMachineName, yMachineName); // If types don't match - string? xType = x.Item2.GetStringFieldValue(Models.Metadata.DatItem.TypeKey); - string? yType = y.Item2.GetStringFieldValue(Models.Metadata.DatItem.TypeKey); + string? xType = x.Value.GetStringFieldValue(Models.Metadata.DatItem.TypeKey); + string? yType = y.Value.GetStringFieldValue(Models.Metadata.DatItem.TypeKey); if (xType != yType) return xType.AsEnumValue() - yType.AsEnumValue(); // If directory names don't match - string? xDirectoryName = Path.GetDirectoryName(TextHelper.RemovePathUnsafeCharacters(x.Item2.GetName() ?? string.Empty)); - string? yDirectoryName = Path.GetDirectoryName(TextHelper.RemovePathUnsafeCharacters(y.Item2.GetName() ?? string.Empty)); + string? xDirectoryName = Path.GetDirectoryName(TextHelper.RemovePathUnsafeCharacters(x.Value.GetName() ?? string.Empty)); + string? yDirectoryName = Path.GetDirectoryName(TextHelper.RemovePathUnsafeCharacters(y.Value.GetName() ?? string.Empty)); if (xDirectoryName != yDirectoryName) return nc.Compare(xDirectoryName, yDirectoryName); // If item names don't match - string? xName = Path.GetFileName(TextHelper.RemovePathUnsafeCharacters(x.Item2.GetName() ?? string.Empty)); - string? yName = Path.GetFileName(TextHelper.RemovePathUnsafeCharacters(y.Item2.GetName() ?? string.Empty)); + string? xName = Path.GetFileName(TextHelper.RemovePathUnsafeCharacters(x.Value.GetName() ?? string.Empty)); + string? yName = Path.GetFileName(TextHelper.RemovePathUnsafeCharacters(y.Value.GetName() ?? string.Empty)); if (xName != yName) return nc.Compare(xName, yName); // Otherwise, compare on machine or source, depending on the flag - int? xSourceIndex = x.Item2.GetFieldValue(DatItem.SourceKey)?.Index; - int? ySourceIndex = y.Item2.GetFieldValue(DatItem.SourceKey)?.Index; + int? xSourceIndex = x.Value.GetFieldValue(DatItem.SourceKey)?.Index; + int? ySourceIndex = y.Value.GetFieldValue(DatItem.SourceKey)?.Index; return (norename ? nc.Compare(xMachineName, yMachineName) : (xSourceIndex - ySourceIndex) ?? 0); } catch diff --git a/SabreTools.DatTools/Cleaner.cs b/SabreTools.DatTools/Cleaner.cs index dc877800..9a0487c5 100644 --- a/SabreTools.DatTools/Cleaner.cs +++ b/SabreTools.DatTools/Cleaner.cs @@ -211,10 +211,10 @@ namespace SabreTools.DatTools if (items == null) continue; - foreach ((long, DatItem) item in items) + foreach (var item in items) { // If we have a null item, we can't clean it it - if (item.Item2 == null) + if (item.Value == null) continue; // Run cleaning per item @@ -284,17 +284,17 @@ namespace SabreTools.DatTools /// /// ItemDictionaryDB to get machine information from /// DatItem to clean - internal void CleanDatItemDB(ItemDictionaryDB db, (long, DatItem) datItem) + internal void CleanDatItemDB(ItemDictionaryDB db, KeyValuePair datItem) { // Get the machine associated with the item, if possible - var machine = db.GetMachineForItem(datItem.Item1); - if (machine.Item2 == null) + var machine = db.GetMachineForItem(datItem.Key); + if (machine.Value == null) return; // Get the fields for processing - string? machineName = machine.Item2.GetStringFieldValue(Models.Metadata.Machine.NameKey); - string? machineDesc = machine.Item2.GetStringFieldValue(Models.Metadata.Machine.DescriptionKey); - string? datItemName = datItem.Item2.GetName(); + string? machineName = machine.Value.GetStringFieldValue(Models.Metadata.Machine.NameKey); + string? machineDesc = machine.Value.GetStringFieldValue(Models.Metadata.Machine.DescriptionKey); + string? datItemName = datItem.Value.GetName(); // If we're stripping unicode characters, strip machine name and description if (RemoveUnicode) @@ -331,9 +331,9 @@ namespace SabreTools.DatTools } // Set the fields back, if necessary - machine.Item2.SetFieldValue(Models.Metadata.Machine.NameKey, machineName); - machine.Item2.SetFieldValue(Models.Metadata.Machine.DescriptionKey, machineDesc); - datItem.Item2.SetName(datItemName); + machine.Value.SetFieldValue(Models.Metadata.Machine.NameKey, machineName); + machine.Value.SetFieldValue(Models.Metadata.Machine.DescriptionKey, machineDesc); + datItem.Value.SetName(datItemName); } #endregion diff --git a/SabreTools.DatTools/DatFileTool.cs b/SabreTools.DatTools/DatFileTool.cs index 7f01707a..56d59035 100644 --- a/SabreTools.DatTools/DatFileTool.cs +++ b/SabreTools.DatTools/DatFileTool.cs @@ -121,18 +121,18 @@ namespace SabreTools.DatTools continue; #endif - foreach ((long, DatItem) item in items) + foreach (var item in items) { - var source = datFile.ItemsDB.GetSourceForItem(item.Item1); - if (source.Item2 == null) + var source = datFile.ItemsDB.GetSourceForItem(item.Key); + if (source.Value == null) continue; - var machine = datFile.ItemsDB.GetMachineForItem(item.Item1); - if (machine.Item2 == null) + var machine = datFile.ItemsDB.GetMachineForItem(item.Key); + if (machine.Value == null) continue; - string filename = inputs[source.Item2.Index].CurrentPath; - string rootpath = inputs[source.Item2.Index].ParentPath ?? string.Empty; + string filename = inputs[source.Value.Index].CurrentPath; + string rootpath = inputs[source.Value.Index].ParentPath ?? string.Empty; if (rootpath.Length > 0 #if NETFRAMEWORK @@ -148,9 +148,9 @@ namespace SabreTools.DatTools filename = filename.Remove(0, rootpath.Length); - machine.Item2.SetFieldValue(Models.Metadata.Machine.NameKey, Path.GetDirectoryName(filename) + Path.DirectorySeparatorChar + machine.Value.SetFieldValue(Models.Metadata.Machine.NameKey, Path.GetDirectoryName(filename) + Path.DirectorySeparatorChar + Path.GetFileNameWithoutExtension(filename) + Path.DirectorySeparatorChar - + machine.Item2.GetStringFieldValue(Models.Metadata.Machine.NameKey)); + + machine.Value.GetStringFieldValue(Models.Metadata.Machine.NameKey)); } #if NET40_OR_GREATER || NETCOREAPP }); @@ -317,15 +317,15 @@ namespace SabreTools.DatTools continue; #endif - foreach ((long, DatItem) datItem in datItems) + foreach (var datItem in datItems) { var dupes = datFile.ItemsDB.GetDuplicates(datItem, sorted: true); - if (datItem.Item2.Clone() is not DatItem newDatItem) + if (datItem.Value.Clone() is not DatItem newDatItem) continue; // Replace fields from the first duplicate, if we have one if (dupes.Count > 0) - Replacer.ReplaceFields(datItem.Item2, dupes[0].Item2, itemFieldNames); + Replacer.ReplaceFields(datItem.Value, dupes.First().Value, itemFieldNames); } #if NET40_OR_GREATER || NETCOREAPP }); @@ -358,12 +358,12 @@ namespace SabreTools.DatTools continue; #endif - foreach ((long, DatItem) datItem in datItems) + foreach (var datItem in datItems) { - var datMachine = datFile.ItemsDB.GetMachineForItem(datFile.ItemsDB.GetItemsForBucket(key)![0].Item1); - var intMachine = intDat.ItemsDB.GetMachineForItem(datItem.Item1); - if (datMachine.Item2 != null && intMachine.Item2 != null) - Replacer.ReplaceFields(intMachine.Item2, datMachine.Item2, machineFieldNames, onlySame); + var datMachine = datFile.ItemsDB.GetMachineForItem(datFile.ItemsDB.GetItemsForBucket(key)!.First().Key); + var intMachine = intDat.ItemsDB.GetMachineForItem(datItem.Key); + if (datMachine.Value != null && intMachine.Value != null) + Replacer.ReplaceFields(intMachine.Value, datMachine.Value, machineFieldNames, onlySame); } #if NET40_OR_GREATER || NETCOREAPP }); @@ -648,11 +648,11 @@ namespace SabreTools.DatTools watch.Start("Populating duplicate DAT"); // Get all current items, machines, and mappings - var datItems = datFile.ItemsDB.GetItems().ToDictionary(m => m.Item1, m => m.Item2); - var machines = datFile.ItemsDB.GetMachines().ToDictionary(m => m.Item1, m => m.Item2); - var sources = datFile.ItemsDB.GetSources().ToDictionary(m => m.Item1, m => m.Item2); - var itemMachineMappings = datFile.ItemsDB.GetItemMachineMappings().ToDictionary(m => m.Item1, m => m.Item2); - var itemSourceMappings = datFile.ItemsDB.GetItemSourceMappings().ToDictionary(m => m.Item1, m => m.Item2); + var datItems = datFile.ItemsDB.GetItems(); + var machines = datFile.ItemsDB.GetMachines(); + var sources = datFile.ItemsDB.GetSources(); + var itemMachineMappings = datFile.ItemsDB.GetItemMachineMappings(); + var itemSourceMappings = datFile.ItemsDB.GetItemSourceMappings(); // Create mappings from old index to new index var machineRemapping = new Dictionary(); @@ -701,7 +701,7 @@ namespace SabreTools.DatTools var currentSource = sources[sourceIndex]; string? currentMachineName = machines[machineIndex].GetStringFieldValue(Models.Metadata.Machine.NameKey); var currentMachine = datFile.ItemsDB.GetMachine(currentMachineName); - if (currentMachine.Item2 == null) + if (currentMachine.Value == null) #if NET40_OR_GREATER || NETCOREAPP return; #else @@ -711,15 +711,15 @@ namespace SabreTools.DatTools // Get the source-specific machine string? renamedMachineName = $"{currentMachineName} ({Path.GetFileNameWithoutExtension(inputs[currentSource!.Index].CurrentPath)})"; var renamedMachine = datFile.ItemsDB.GetMachine(renamedMachineName); - if (renamedMachine.Item2 == null) + if (renamedMachine.Value == null) { - var newMachine = currentMachine.Item2.Clone() as Machine; + var newMachine = currentMachine.Value.Clone() as Machine; newMachine!.SetFieldValue(Models.Metadata.Machine.NameKey, renamedMachineName); long newMachineIndex = dupeData.ItemsDB.AddMachine(newMachine!); - renamedMachine = (newMachineIndex, newMachine); + renamedMachine = new KeyValuePair(newMachineIndex, newMachine); } - dupeData.ItemsDB.AddItem(item.Value, renamedMachine.Item1, sourceRemapping[sourceIndex], statsOnly: false); + dupeData.ItemsDB.AddItem(item.Value, renamedMachine.Key, sourceRemapping[sourceIndex], statsOnly: false); #if NET40_OR_GREATER || NETCOREAPP }); #else @@ -888,11 +888,11 @@ namespace SabreTools.DatTools watch.Start("Populating all individual DATs"); // Get all current items, machines, and mappings - var datItems = datFile.ItemsDB.GetItems().ToDictionary(m => m.Item1, m => m.Item2); - var machines = datFile.ItemsDB.GetMachines().ToDictionary(m => m.Item1, m => m.Item2); - var sources = datFile.ItemsDB.GetSources().ToDictionary(m => m.Item1, m => m.Item2); - var itemMachineMappings = datFile.ItemsDB.GetItemMachineMappings().ToDictionary(m => m.Item1, m => m.Item2); - var itemSourceMappings = datFile.ItemsDB.GetItemSourceMappings().ToDictionary(m => m.Item1, m => m.Item2); + var datItems = datFile.ItemsDB.GetItems(); + var machines = datFile.ItemsDB.GetMachines(); + var sources = datFile.ItemsDB.GetSources(); + var itemMachineMappings = datFile.ItemsDB.GetItemMachineMappings(); + var itemSourceMappings = datFile.ItemsDB.GetItemSourceMappings(); // Create mappings from old index to new index var machineRemapping = new Dictionary(); @@ -1081,11 +1081,11 @@ namespace SabreTools.DatTools watch.Start("Populating no duplicate DAT"); // Get all current items, machines, and mappings - var datItems = datFile.ItemsDB.GetItems().ToDictionary(m => m.Item1, m => m.Item2); - var machines = datFile.ItemsDB.GetMachines().ToDictionary(m => m.Item1, m => m.Item2); - var sources = datFile.ItemsDB.GetSources().ToDictionary(m => m.Item1, m => m.Item2); - var itemMachineMappings = datFile.ItemsDB.GetItemMachineMappings().ToDictionary(m => m.Item1, m => m.Item2); - var itemSourceMappings = datFile.ItemsDB.GetItemSourceMappings().ToDictionary(m => m.Item1, m => m.Item2); + var datItems = datFile.ItemsDB.GetItems(); + var machines = datFile.ItemsDB.GetMachines(); + var sources = datFile.ItemsDB.GetSources(); + var itemMachineMappings = datFile.ItemsDB.GetItemMachineMappings(); + var itemSourceMappings = datFile.ItemsDB.GetItemSourceMappings(); // Create mappings from old index to new index var machineRemapping = new Dictionary(); @@ -1134,7 +1134,7 @@ namespace SabreTools.DatTools var currentSource = sources[sourceIndex]; string? currentMachineName = machines[machineIndex].GetStringFieldValue(Models.Metadata.Machine.NameKey); var currentMachine = datFile.ItemsDB.GetMachine(currentMachineName); - if (currentMachine.Item2 == null) + if (currentMachine.Value == null) #if NET40_OR_GREATER || NETCOREAPP return; #else @@ -1144,15 +1144,15 @@ namespace SabreTools.DatTools // Get the source-specific machine string? renamedMachineName = $"{currentMachineName} ({Path.GetFileNameWithoutExtension(inputs[currentSource!.Index].CurrentPath)})"; var renamedMachine = datFile.ItemsDB.GetMachine(renamedMachineName); - if (renamedMachine.Item2 == null) + if (renamedMachine.Value == null) { - var newMachine = currentMachine.Item2.Clone() as Machine; + var newMachine = currentMachine.Value.Clone() as Machine; newMachine!.SetFieldValue(Models.Metadata.Machine.NameKey, renamedMachineName); long newMachineIndex = outerDiffData.ItemsDB.AddMachine(newMachine); - renamedMachine = (newMachineIndex, newMachine); + renamedMachine = new KeyValuePair(newMachineIndex, newMachine); } - outerDiffData.ItemsDB.AddItem(item.Value, renamedMachine.Item1, sourceRemapping[sourceIndex], statsOnly: false); + outerDiffData.ItemsDB.AddItem(item.Value, renamedMachine.Key, sourceRemapping[sourceIndex], statsOnly: false); #if NET40_OR_GREATER || NETCOREAPP }); #else @@ -1254,11 +1254,11 @@ namespace SabreTools.DatTools private static void AddFromExistingDB(DatFile addTo, DatFile addFrom, bool delete = false) { // Get all current items, machines, and mappings - var datItems = addFrom.ItemsDB.GetItems().ToDictionary(m => m.Item1, m => m.Item2); - var machines = addFrom.ItemsDB.GetMachines().ToDictionary(m => m.Item1, m => m.Item2); - var sources = addFrom.ItemsDB.GetSources().ToDictionary(m => m.Item1, m => m.Item2); - var itemMachineMappings = addFrom.ItemsDB.GetItemMachineMappings().ToDictionary(m => m.Item1, m => m.Item2); - var itemSourceMappings = addFrom.ItemsDB.GetItemSourceMappings().ToDictionary(m => m.Item1, m => m.Item2); + var datItems = addFrom.ItemsDB.GetItems(); + var machines = addFrom.ItemsDB.GetMachines(); + var sources = addFrom.ItemsDB.GetSources(); + var itemMachineMappings = addFrom.ItemsDB.GetItemMachineMappings(); + var itemSourceMappings = addFrom.ItemsDB.GetItemSourceMappings(); // Create mappings from old index to new index var machineRemapping = new Dictionary(); @@ -1359,11 +1359,11 @@ namespace SabreTools.DatTools private static void FillWithSourceIndexDB(DatFile datFile, DatFile indexDat, int index) { // Get all current items, machines, and mappings - var datItems = datFile.ItemsDB.GetItems().ToDictionary(m => m.Item1, m => m.Item2); - var machines = datFile.ItemsDB.GetMachines().ToDictionary(m => m.Item1, m => m.Item2); - var sources = datFile.ItemsDB.GetSources().ToDictionary(m => m.Item1, m => m.Item2); - var itemMachineMappings = datFile.ItemsDB.GetItemMachineMappings().ToDictionary(m => m.Item1, m => m.Item2); - var itemSourceMappings = datFile.ItemsDB.GetItemSourceMappings().ToDictionary(m => m.Item1, m => m.Item2); + var datItems = datFile.ItemsDB.GetItems(); + var machines = datFile.ItemsDB.GetMachines(); + var sources = datFile.ItemsDB.GetSources(); + var itemMachineMappings = datFile.ItemsDB.GetItemMachineMappings(); + var itemSourceMappings = datFile.ItemsDB.GetItemSourceMappings(); // Create mappings from old index to new index var machineRemapping = new Dictionary(); diff --git a/SabreTools.DatTools/ExtraIni.cs b/SabreTools.DatTools/ExtraIni.cs index e5c9efcf..08126356 100644 --- a/SabreTools.DatTools/ExtraIni.cs +++ b/SabreTools.DatTools/ExtraIni.cs @@ -182,11 +182,11 @@ namespace SabreTools.DatTools // Loop through and set the fields accordingly foreach (var datItem in datItems) { - var machine = datFile.ItemsDB.GetMachineForItem(datItem.Item1); - if (machine.Item2 != null) - setter.SetFields(machine.Item2); + var machine = datFile.ItemsDB.GetMachineForItem(datItem.Key); + if (machine.Value != null) + setter.SetFields(machine.Value); - setter.SetFields(datItem.Item2); + setter.SetFields(datItem.Value); } } } diff --git a/SabreTools.DatTools/Rebuilder.cs b/SabreTools.DatTools/Rebuilder.cs index c79a3788..1d55bd17 100644 --- a/SabreTools.DatTools/Rebuilder.cs +++ b/SabreTools.DatTools/Rebuilder.cs @@ -603,7 +603,7 @@ namespace SabreTools.DatTools /// True if the DAT should be used as a filter instead of a template, false otherwise /// Output list of duplicate items to rebuild to /// True if the item should be rebuilt, false otherwise - private static bool ShouldRebuildDB(DatFile datFile, (long, DatItem) datItem, Stream? stream, bool inverse, out List<(long, DatItem)> dupes) + private static bool ShouldRebuildDB(DatFile datFile, KeyValuePair datItem, Stream? stream, bool inverse, out Dictionary dupes) { // Find if the file has duplicates in the DAT dupes = datFile.ItemsDB.GetDuplicates(datItem); @@ -645,7 +645,7 @@ namespace SabreTools.DatTools } long index = datFile.ItemsDB.AddItem(item, machineIndex, -1, false); - dupes.Add((index, item)); + dupes[index] = item; return true; } diff --git a/SabreTools.DatTools/Splitter.cs b/SabreTools.DatTools/Splitter.cs index 37d43723..494281fb 100644 --- a/SabreTools.DatTools/Splitter.cs +++ b/SabreTools.DatTools/Splitter.cs @@ -142,11 +142,11 @@ namespace SabreTools.DatTools extBDat.Header.SetFieldValue(Models.Metadata.Header.DescriptionKey, extBDat.Header.GetStringFieldValue(Models.Metadata.Header.DescriptionKey) + $" ({newExtBString})"); // Get all current items, machines, and mappings - var datItems = datFile.ItemsDB.GetItems().ToDictionary(m => m.Item1, m => m.Item2); - var machines = datFile.ItemsDB.GetMachines().ToDictionary(m => m.Item1, m => m.Item2); - var sources = datFile.ItemsDB.GetSources().ToDictionary(m => m.Item1, m => m.Item2); - var itemMachineMappings = datFile.ItemsDB.GetItemMachineMappings().ToDictionary(m => m.Item1, m => m.Item2); - var itemSourceMappings = datFile.ItemsDB.GetItemSourceMappings().ToDictionary(m => m.Item1, m => m.Item2); + var datItems = datFile.ItemsDB.GetItems(); + var machines = datFile.ItemsDB.GetMachines(); + var sources = datFile.ItemsDB.GetSources(); + var itemMachineMappings = datFile.ItemsDB.GetItemMachineMappings(); + var itemSourceMappings = datFile.ItemsDB.GetItemSourceMappings(); // Create mappings from old index to new index var machineRemapping = new Dictionary(); @@ -350,11 +350,11 @@ namespace SabreTools.DatTools } // Get all current items, machines, and mappings - var datItems = datFile.ItemsDB.GetItems().ToDictionary(m => m.Item1, m => m.Item2); - var machines = datFile.ItemsDB.GetMachines().ToDictionary(m => m.Item1, m => m.Item2); - var sources = datFile.ItemsDB.GetSources().ToDictionary(m => m.Item1, m => m.Item2); - var itemMachineMappings = datFile.ItemsDB.GetItemMachineMappings().ToDictionary(m => m.Item1, m => m.Item2); - var itemSourceMappings = datFile.ItemsDB.GetItemSourceMappings().ToDictionary(m => m.Item1, m => m.Item2); + var datItems = datFile.ItemsDB.GetItems(); + var machines = datFile.ItemsDB.GetMachines(); + var sources = datFile.ItemsDB.GetSources(); + var itemMachineMappings = datFile.ItemsDB.GetItemMachineMappings(); + var itemSourceMappings = datFile.ItemsDB.GetItemSourceMappings(); // Create mappings from old index to new index var machineRemapping = new Dictionary(); @@ -680,11 +680,11 @@ namespace SabreTools.DatTools greaterThan.Header.SetFieldValue(Models.Metadata.Header.DescriptionKey, greaterThan.Header.GetStringFieldValue(Models.Metadata.Header.DescriptionKey) + $" (equal-greater than {radix})"); // Get all current items, machines, and mappings - var datItems = datFile.ItemsDB.GetItems().ToDictionary(m => m.Item1, m => m.Item2); - var machines = datFile.ItemsDB.GetMachines().ToDictionary(m => m.Item1, m => m.Item2); - var sources = datFile.ItemsDB.GetSources().ToDictionary(m => m.Item1, m => m.Item2); - var itemMachineMappings = datFile.ItemsDB.GetItemMachineMappings().ToDictionary(m => m.Item1, m => m.Item2); - var itemSourceMappings = datFile.ItemsDB.GetItemSourceMappings().ToDictionary(m => m.Item1, m => m.Item2); + var datItems = datFile.ItemsDB.GetItems(); + var machines = datFile.ItemsDB.GetMachines(); + var sources = datFile.ItemsDB.GetSources(); + var itemMachineMappings = datFile.ItemsDB.GetItemMachineMappings(); + var itemSourceMappings = datFile.ItemsDB.GetItemSourceMappings(); // Create mappings from old index to new index var machineRemapping = new Dictionary(); @@ -936,11 +936,11 @@ namespace SabreTools.DatTools private static void FillWithItemTypeDB(DatFile datFile, DatFile indexDat, ItemType itemType) { // Get all current items, machines, and mappings - var datItems = datFile.ItemsDB.GetItems().ToDictionary(m => m.Item1, m => m.Item2); - var machines = datFile.ItemsDB.GetMachines().ToDictionary(m => m.Item1, m => m.Item2); - var sources = datFile.ItemsDB.GetSources().ToDictionary(m => m.Item1, m => m.Item2); - var itemMachineMappings = datFile.ItemsDB.GetItemMachineMappings().ToDictionary(m => m.Item1, m => m.Item2); - var itemSourceMappings = datFile.ItemsDB.GetItemSourceMappings().ToDictionary(m => m.Item1, m => m.Item2); + var datItems = datFile.ItemsDB.GetItems(); + var machines = datFile.ItemsDB.GetMachines(); + var sources = datFile.ItemsDB.GetSources(); + var itemMachineMappings = datFile.ItemsDB.GetItemMachineMappings(); + var itemSourceMappings = datFile.ItemsDB.GetItemSourceMappings(); // Create mappings from old index to new index var machineRemapping = new Dictionary(); diff --git a/SabreTools.DatTools/Verification.cs b/SabreTools.DatTools/Verification.cs index 063615e0..7da13c26 100644 --- a/SabreTools.DatTools/Verification.cs +++ b/SabreTools.DatTools/Verification.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.IO; +using System.Linq; using SabreTools.Core.Tools; using SabreTools.DatFiles; using SabreTools.DatItems; @@ -180,8 +181,8 @@ namespace SabreTools.DatTools continue; // Now we want to remove all duplicates from the DAT - datFile.ItemsDB.GetDuplicates((-1, new Rom(fileinfo))) - .AddRange(datFile.ItemsDB.GetDuplicates((-1, new Disk(fileinfo)))); + datFile.ItemsDB.GetDuplicates(new KeyValuePair(-1, new Rom(fileinfo))) + .Concat(datFile.ItemsDB.GetDuplicates(new KeyValuePair(-1, new Disk(fileinfo)))); } watch.Stop(); @@ -270,14 +271,14 @@ namespace SabreTools.DatTools if (items == null) continue; - for (int i = 0; i < items.Length; i++) + foreach (var item in items) { // Get the source associated with the item - var source = datFile.ItemsDB.GetSourceForItem(items[i].Item1); + var source = datFile.ItemsDB.GetSourceForItem(item.Key); // Unmatched items will have a source ID of int.MaxValue, remove all others - if (source.Item2?.Index != int.MaxValue) - items[i].Item2.SetFieldValue(DatItem.RemoveKey, true); + if (source.Value?.Index != int.MaxValue) + item.Value.SetFieldValue(DatItem.RemoveKey, true); } } diff --git a/SabreTools.DatTools/Writer.cs b/SabreTools.DatTools/Writer.cs index 0d880a59..fd6144eb 100644 --- a/SabreTools.DatTools/Writer.cs +++ b/SabreTools.DatTools/Writer.cs @@ -144,11 +144,11 @@ namespace SabreTools.DatTools datFile.ItemsDB.DatStatistics.DisplayName = datFile.Header.GetStringFieldValue(DatHeader.FileNameKey); datFile.ItemsDB.DatStatistics.MachineCount = datFile.Items.Keys.Count; - var statsList = new List - { + List statsList = + [ datFile.Items.DatStatistics, //datFile.ItemsDB.DatStatistics, - }; + ]; var consoleOutput = BaseReport.Create(StatReportFormat.None, statsList); consoleOutput!.WriteToFile(null, true, true); } diff --git a/SabreTools.FileTypes/Archives/SevenZipArchive.cs b/SabreTools.FileTypes/Archives/SevenZipArchive.cs index a499c762..9490b82b 100644 --- a/SabreTools.FileTypes/Archives/SevenZipArchive.cs +++ b/SabreTools.FileTypes/Archives/SevenZipArchive.cs @@ -459,7 +459,7 @@ namespace SabreTools.FileTypes.Archives // Map all inputs to index Dictionary inputIndexMap = []; - var oldZipFileContents = new List(); + List oldZipFileContents = []; for (int i = 0; i < oldZipFile.LocalFilesCount(); i++) { oldZipFileContents.Add(oldZipFile.GetLocalFile(i).Filename!); @@ -675,7 +675,7 @@ namespace SabreTools.FileTypes.Archives Dictionary inputIndexMap = new(); for (int i = 0; i < inputFiles.Count; i++) { - var oldZipFileContents = new List(); + List oldZipFileContents = []; for (int j = 0; j < oldZipFile.LocalFilesCount(); j++) { oldZipFileContents.Add(oldZipFile.GetLocalFile(j).Filename!); diff --git a/SabreTools.FileTypes/Archives/ZipArchive.cs b/SabreTools.FileTypes/Archives/ZipArchive.cs index b6ac2535..665ea77e 100644 --- a/SabreTools.FileTypes/Archives/ZipArchive.cs +++ b/SabreTools.FileTypes/Archives/ZipArchive.cs @@ -314,7 +314,7 @@ namespace SabreTools.FileTypes.Archives if (Filename == null) return null; - var found = new List(); + List found = []; string? gamename = Path.GetFileNameWithoutExtension(Filename); try @@ -492,7 +492,7 @@ namespace SabreTools.FileTypes.Archives if (zf == null) throw new Exception($"Could not open {Filename} as a zip file"); - var zipEntries = new List<(string, bool)>(); + List<(string, bool)> zipEntries = []; for (int i = 0; i < zf.Entries.Count; i++) { // Get the local file @@ -638,7 +638,7 @@ namespace SabreTools.FileTypes.Archives // Map all inputs to index Dictionary inputIndexMap = new(); - var oldZipFileContents = new List(); + List oldZipFileContents = []; for (int i = 0; i < oldZipFile.LocalFilesCount(); i++) { oldZipFileContents.Add(oldZipFile.GetLocalFile(i).Filename!); @@ -850,7 +850,7 @@ namespace SabreTools.FileTypes.Archives Dictionary inputIndexMap = new(); for (int i = 0; i < inputFiles.Count; i++) { - var oldZipFileContents = new List(); + List oldZipFileContents = []; for (int j = 0; j < oldZipFile.LocalFilesCount(); j++) { oldZipFileContents.Add(oldZipFile.GetLocalFile(j).Filename!);