From a4da7f3657b407d061d3b77cd49f78dc194d29b3 Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Tue, 12 Nov 2024 21:12:06 -0500 Subject: [PATCH] Handle known enumerable types better --- RombaSharp/Features/Import.cs | 3 +- RombaSharp/Features/Merge.cs | 3 +- SabreTools.Core/DictionaryBaseExtensions.cs | 4 +- SabreTools.Core/Filter/FieldManipulator.cs | 3 +- SabreTools.Core/Filter/FilterKey.cs | 9 +- SabreTools.Core/Tools/AttributeHelper.cs | 5 +- SabreTools.Core/Tools/TypeHelper.cs | 24 ++-- SabreTools.DatFiles/DatFile.cs | 4 +- SabreTools.DatFiles/Formats/SabreJSON.cs | 2 +- SabreTools.DatFiles/Formats/SoftwareList.cs | 8 +- SabreTools.DatFiles/ItemDictionary.cs | 64 +++++++---- SabreTools.DatFiles/ItemDictionaryDB.cs | 65 ++++++----- SabreTools.DatItems/DatItem.cs | 6 +- SabreTools.DatTools/DatFileTool.cs | 11 +- SabreTools.DatTools/Splitter.cs | 13 ++- SabreTools.FileTypes/Folder.cs | 5 +- SabreTools.Help/Feature.cs | 29 ++--- SabreTools.Help/FeatureSet.cs | 31 +++++- SabreTools/Features/Batch.cs | 116 ++++++++++---------- 19 files changed, 227 insertions(+), 178 deletions(-) diff --git a/RombaSharp/Features/Import.cs b/RombaSharp/Features/Import.cs index 2b56064a..8b92221b 100644 --- a/RombaSharp/Features/Import.cs +++ b/RombaSharp/Features/Import.cs @@ -1,6 +1,5 @@ using System.Collections.Generic; using System.IO; -using System.Linq; using Microsoft.Data.Sqlite; using SabreTools.Help; using SabreTools.IO; @@ -33,7 +32,7 @@ namespace RombaSharp.Features logger.Error("This feature is not yet implemented: import"); // Ensure the inputs - var files = PathTool.GetFilesOnly(Inputs).Select(p => p.CurrentPath); + var files = PathTool.GetFilesOnly(Inputs).ConvertAll(p => p.CurrentPath); Inputs.Clear(); Inputs.AddRange(files); diff --git a/RombaSharp/Features/Merge.cs b/RombaSharp/Features/Merge.cs index 935e5e39..64a71a42 100644 --- a/RombaSharp/Features/Merge.cs +++ b/RombaSharp/Features/Merge.cs @@ -1,6 +1,5 @@ using System.Collections.Generic; using System.IO; -using System.Linq; using SabreTools.Help; using SabreTools.IO; @@ -43,7 +42,7 @@ namespace RombaSharp.Features logger.Error("This feature is not yet implemented: merge"); // Verify that the inputs are valid directories - var dirs = PathTool.GetDirectoriesOnly(Inputs).Select(p => p.CurrentPath); + var dirs = PathTool.GetDirectoriesOnly(Inputs).ConvertAll(p => p.CurrentPath); Inputs.Clear(); Inputs.AddRange(dirs); diff --git a/SabreTools.Core/DictionaryBaseExtensions.cs b/SabreTools.Core/DictionaryBaseExtensions.cs index e19563bd..80bd280c 100644 --- a/SabreTools.Core/DictionaryBaseExtensions.cs +++ b/SabreTools.Core/DictionaryBaseExtensions.cs @@ -33,8 +33,8 @@ namespace SabreTools.Core // Enumerable types byte[] bytArr => bytArr.Clone(), string[] strArr => strArr.Clone(), - DictionaryBase[] dbArr => dbArr.Select(Clone).ToArray(), - ICloneable[] clArr => clArr.Select(cl => cl.Clone()).ToArray(), + DictionaryBase[] dbArr => Array.ConvertAll(dbArr, Clone), + ICloneable[] clArr => Array.ConvertAll(clArr, cl => cl.Clone()), // Everything else just copies _ => value, diff --git a/SabreTools.Core/Filter/FieldManipulator.cs b/SabreTools.Core/Filter/FieldManipulator.cs index 2622d5fd..33c95700 100644 --- a/SabreTools.Core/Filter/FieldManipulator.cs +++ b/SabreTools.Core/Filter/FieldManipulator.cs @@ -1,5 +1,4 @@ using System; -using System.Linq; using SabreTools.Core.Tools; using SabreTools.Models.Metadata; @@ -62,7 +61,7 @@ namespace SabreTools.Core.Filter return false; // Get the value that matches the field name provided - string? realField = constants.FirstOrDefault(c => string.Equals(c, fieldName, StringComparison.OrdinalIgnoreCase)); + string? realField = Array.Find(constants, c => string.Equals(c, fieldName, StringComparison.OrdinalIgnoreCase)); if (realField == null) return false; diff --git a/SabreTools.Core/Filter/FilterKey.cs b/SabreTools.Core/Filter/FilterKey.cs index 94c99805..84b68ed2 100644 --- a/SabreTools.Core/Filter/FilterKey.cs +++ b/SabreTools.Core/Filter/FilterKey.cs @@ -1,5 +1,4 @@ using System; -using System.Linq; using SabreTools.Core.Tools; using SabreTools.Models.Metadata; @@ -110,7 +109,7 @@ namespace SabreTools.Core.Filter // Get if there's a match to the constant string localFieldName = fieldName; - string? constantMatch = constants.FirstOrDefault(c => string.Equals(c, localFieldName, StringComparison.OrdinalIgnoreCase)); + string? constantMatch = Array.Find(constants, c => string.Equals(c, localFieldName, StringComparison.OrdinalIgnoreCase)); if (constantMatch == null) return false; @@ -132,7 +131,7 @@ namespace SabreTools.Core.Filter // Get if there's a match to the constant string localFieldName = fieldName; - string? constantMatch = constants.FirstOrDefault(c => string.Equals(c, localFieldName, StringComparison.OrdinalIgnoreCase)); + string? constantMatch = Array.Find(constants, c => string.Equals(c, localFieldName, StringComparison.OrdinalIgnoreCase)); if (constantMatch == null) return false; @@ -156,7 +155,7 @@ namespace SabreTools.Core.Filter // If we get any matches string localFieldName = fieldName; - string? matchedType = itemTypes.FirstOrDefault(t => DatItemContainsField(t, localFieldName)); + string? matchedType = Array.Find(itemTypes, t => DatItemContainsField(t, localFieldName)); if (matchedType != null) { // Check for a matching field @@ -208,7 +207,7 @@ namespace SabreTools.Core.Filter // Get if there's a match to the constant string localFieldName = fieldName; - string? constantMatch = constants.FirstOrDefault(c => string.Equals(c, localFieldName, StringComparison.OrdinalIgnoreCase)); + string? constantMatch = Array.Find(constants, c => string.Equals(c, localFieldName, StringComparison.OrdinalIgnoreCase)); return constantMatch; } diff --git a/SabreTools.Core/Tools/AttributeHelper.cs b/SabreTools.Core/Tools/AttributeHelper.cs index fdac427a..f0af3984 100644 --- a/SabreTools.Core/Tools/AttributeHelper.cs +++ b/SabreTools.Core/Tools/AttributeHelper.cs @@ -1,5 +1,4 @@ using System; -using System.Linq; namespace SabreTools.Core.Tools { @@ -32,7 +31,7 @@ namespace SabreTools.Core.Tools return null; // Get the enum value info from the array, if possible - var enumValueMemberInfo = memberInfos.FirstOrDefault(m => m.DeclaringType == enumType); + var enumValueMemberInfo = Array.Find(memberInfos, m => m.DeclaringType == enumType); if (enumValueMemberInfo == null) return null; @@ -42,7 +41,7 @@ namespace SabreTools.Core.Tools return null; // Return the first attribute, if possible - return (MappingAttribute?)attributes.FirstOrDefault(); + return (MappingAttribute?)attributes[0]; } } } \ No newline at end of file diff --git a/SabreTools.Core/Tools/TypeHelper.cs b/SabreTools.Core/Tools/TypeHelper.cs index cd719d96..93f0bd02 100644 --- a/SabreTools.Core/Tools/TypeHelper.cs +++ b/SabreTools.Core/Tools/TypeHelper.cs @@ -50,19 +50,23 @@ namespace SabreTools.Core.Tools foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) { // If not all types can be loaded, use the ones that could be - List assemblyTypes = []; + Type?[] assemblyTypes = []; try { - assemblyTypes = [.. assembly.GetTypes()]; + assemblyTypes = assembly.GetTypes(); } catch (ReflectionTypeLoadException rtle) { - assemblyTypes = [.. rtle.Types.Where(t => t != null)]; + assemblyTypes = Array.FindAll(rtle.Types ?? [], t => t != null); } // Loop through all types - foreach (Type type in assemblyTypes) + foreach (Type? type in assemblyTypes) { + // If the type is invalid + if (type == null) + continue; + // If the type isn't a class or doesn't implement the interface if (!type.IsClass || !typeof(DatItem).IsAssignableFrom(type)) continue; @@ -89,19 +93,23 @@ namespace SabreTools.Core.Tools foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) { // If not all types can be loaded, use the ones that could be - List assemblyTypes = []; + Type?[] assemblyTypes = []; try { - assemblyTypes = [.. assembly.GetTypes()]; + assemblyTypes = assembly.GetTypes(); } catch (ReflectionTypeLoadException rtle) { - assemblyTypes = [.. rtle.Types.Where(t => t != null)]; + assemblyTypes = Array.FindAll(rtle.Types ?? [], t => t != null); } // Loop through all types - foreach (Type type in assemblyTypes) + foreach (Type? type in assemblyTypes) { + // If the type is invalid + if (type == null) + continue; + // If the type isn't a class or doesn't implement the interface if (!type.IsClass || !typeof(DatItem).IsAssignableFrom(type)) continue; diff --git a/SabreTools.DatFiles/DatFile.cs b/SabreTools.DatFiles/DatFile.cs index d96d5ed7..d97fe7ad 100644 --- a/SabreTools.DatFiles/DatFile.cs +++ b/SabreTools.DatFiles/DatFile.cs @@ -754,7 +754,7 @@ namespace SabreTools.DatFiles foreach (DatItem datItem in datItems) { ItemType itemType = datItem.GetStringFieldValue(Models.Metadata.DatItem.TypeKey).AsEnumValue(); - if (GetSupportedTypes().Contains(itemType)) + if (Array.Exists(GetSupportedTypes(), t => t == itemType)) return true; } @@ -776,7 +776,7 @@ namespace SabreTools.DatFiles foreach ((long, DatItem) datItem in datItems) { ItemType itemType = datItem.Item2.GetStringFieldValue(Models.Metadata.DatItem.TypeKey).AsEnumValue(); - if (GetSupportedTypes().Contains(itemType)) + if (Array.Exists(GetSupportedTypes(), t => t == itemType)) return true; } diff --git a/SabreTools.DatFiles/Formats/SabreJSON.cs b/SabreTools.DatFiles/Formats/SabreJSON.cs index ce82156e..a5699e63 100644 --- a/SabreTools.DatFiles/Formats/SabreJSON.cs +++ b/SabreTools.DatFiles/Formats/SabreJSON.cs @@ -478,7 +478,7 @@ namespace SabreTools.DatFiles.Formats continue; // Resolve the names in the block - items = [.. DatItem.ResolveNamesDB(items.ToList())]; + items = [.. DatItem.ResolveNamesDB([.. items])]; for (int index = 0; index < items.Length; index++) { diff --git a/SabreTools.DatFiles/Formats/SoftwareList.cs b/SabreTools.DatFiles/Formats/SoftwareList.cs index ba1a9c94..0b616267 100644 --- a/SabreTools.DatFiles/Formats/SoftwareList.cs +++ b/SabreTools.DatFiles/Formats/SoftwareList.cs @@ -1,5 +1,5 @@ -using System.Collections.Generic; -using System.Linq; +using System; +using System.Collections.Generic; using SabreTools.DatItems; using SabreTools.DatItems.Formats; @@ -122,9 +122,9 @@ namespace SabreTools.DatFiles.Formats if (dipSwitch.ValuesSpecified) { var dipValues = dipSwitch.GetFieldValue(Models.Metadata.DipSwitch.DipValueKey); - if (dipValues!.Any(dv => string.IsNullOrEmpty(dv.GetName()))) + if (Array.Find(dipValues!, dv => string.IsNullOrEmpty(dv.GetName())) != null) missingFields.Add(Models.Metadata.DipValue.NameKey); - if (dipValues!.Any(dv => string.IsNullOrEmpty(dv.GetStringFieldValue(Models.Metadata.DipValue.ValueKey)))) + if (Array.Find(dipValues!, dv => string.IsNullOrEmpty(dv.GetStringFieldValue(Models.Metadata.DipValue.ValueKey))) != null) missingFields.Add(Models.Metadata.DipValue.ValueKey); } diff --git a/SabreTools.DatFiles/ItemDictionary.cs b/SabreTools.DatFiles/ItemDictionary.cs index 1b61d306..d164763f 100644 --- a/SabreTools.DatFiles/ItemDictionary.cs +++ b/SabreTools.DatFiles/ItemDictionary.cs @@ -322,7 +322,7 @@ namespace SabreTools.DatFiles items.TryRemove(key, out _); // If there are no non-blank items, remove - else if (!value!.Any(i => i != null && i is not Blank)) + else if (value!.FindIndex(i => i != null && i is not Blank) == -1) items.TryRemove(key, out _); #else // If the key doesn't exist, skip @@ -334,7 +334,7 @@ namespace SabreTools.DatFiles items.Remove(key); // If there are no non-blank items, remove - else if (!items[key]!.Any(i => i != null && i is not Blank)) + else if (items[key]!.FindIndex(i => i != null && i is not Blank) == -1) items.Remove(key); #endif } @@ -348,8 +348,12 @@ namespace SabreTools.DatFiles List keys = [.. items.Keys]; foreach (string key in keys) { + // Skip invalid item lists List? oldItemList = items[key]; - List? newItemList = oldItemList?.Where(i => i.GetBoolFieldValue(DatItem.RemoveKey) != true)?.ToList(); + if (oldItemList == null) + return; + + List newItemList = oldItemList.FindAll(i => i.GetBoolFieldValue(DatItem.RemoveKey) != true); Remove(key); AddRange(key, newItemList); @@ -630,7 +634,7 @@ namespace SabreTools.DatFiles if (roms == null) return false; - return roms.Any(r => datItem.Equals(r)); + return roms.FindIndex(r => datItem.Equals(r)) > -1; } /// @@ -747,7 +751,7 @@ namespace SabreTools.DatFiles #endif { // Get the possibly unsorted list - List? sortedlist = this[key]?.ToList(); + List? sortedlist = this[key]; if (sortedlist == null) #if NET40_OR_GREATER || NETCOREAPP return; @@ -953,7 +957,7 @@ namespace SabreTools.DatFiles string? machine = default; foreach (string region in regionList) { - machine = parents[key].FirstOrDefault(m => Regex.IsMatch(m, @"\(.*" + region + @".*\)", RegexOptions.IgnoreCase)); + machine = parents[key].Find(m => Regex.IsMatch(m, @"\(.*" + region + @".*\)", RegexOptions.IgnoreCase)); if (machine != default) break; } @@ -1190,7 +1194,9 @@ namespace SabreTools.DatFiles /// public void AddRomsFromBios() { - List games = [.. Keys.OrderBy(g => g)]; + List games = [.. Keys]; + games.Sort(); + foreach (string game in games) { // If the game has no items in it, we want to continue @@ -1219,7 +1225,7 @@ namespace SabreTools.DatFiles { DatItem datItem = (DatItem)item.Clone(); datItem.CopyMachineInformation(copyFrom); - if (!items.Any(i => i.GetName() == datItem.GetName()) && !items.Contains(datItem)) + if (items.FindIndex(i => i.GetName() == datItem.GetName()) == -1 && !items.Contains(datItem)) Add(game, datItem); } } @@ -1233,7 +1239,9 @@ namespace SabreTools.DatFiles public bool AddRomsFromDevices(bool dev, bool useSlotOptions) { bool foundnew = false; - List machines = [.. Keys.OrderBy(g => g)]; + List machines = [.. Keys]; + machines.Sort(); + foreach (string machine in machines) { // If the machine doesn't have items, we continue @@ -1266,7 +1274,7 @@ namespace SabreTools.DatFiles if (deviceReferences.Count > 0) { // Loop through all names and check the corresponding machines - List newDeviceReferences = []; + var newDeviceReferences = new HashSet(); foreach (string? deviceReference in deviceReferences) { // If the machine doesn't exist then we continue @@ -1278,7 +1286,7 @@ namespace SabreTools.DatFiles if (devItems == null) continue; - newDeviceReferences.AddRange(devItems + newDeviceReferences.IntersectWith(devItems .Where(i => i is DeviceRef) .Select(i => (i as DeviceRef)!.GetName()!)); @@ -1301,7 +1309,7 @@ namespace SabreTools.DatFiles } // Now that every device reference is accounted for, add the new list of device references, if they don't already exist - foreach (string deviceReference in newDeviceReferences.Distinct()) + foreach (string deviceReference in newDeviceReferences) { if (!deviceReferences.Contains(deviceReference)) { @@ -1316,7 +1324,7 @@ namespace SabreTools.DatFiles if (useSlotOptions && slotOptions.Count > 0) { // Loop through all names and check the corresponding machines - List newSlotOptions = []; + var newSlotOptions = new HashSet(); foreach (string? slotOption in slotOptions) { // If the machine doesn't exist then we continue @@ -1328,7 +1336,7 @@ namespace SabreTools.DatFiles if (slotItems == null) continue; - newSlotOptions.AddRange(slotItems + newSlotOptions.IntersectWith(slotItems .Where(i => i is Slot) .Where(s => (s as Slot)!.SlotOptionsSpecified) .SelectMany(s => (s as Slot)!.GetFieldValue(Models.Metadata.Slot.SlotOptionKey)!) @@ -1353,7 +1361,7 @@ namespace SabreTools.DatFiles } // Now that every device is accounted for, add the new list of slot options, if they don't already exist - foreach (string slotOption in newSlotOptions.Distinct()) + foreach (string slotOption in newSlotOptions) { if (!slotOptions.Contains(slotOption)) { @@ -1377,7 +1385,9 @@ namespace SabreTools.DatFiles /// public void AddRomsFromParent() { - List games = [.. Keys.OrderBy(g => g)]; + List games = [.. Keys]; + games.Sort(); + foreach (string game in games) { // If the game has no items in it, we want to continue @@ -1406,7 +1416,7 @@ namespace SabreTools.DatFiles { DatItem datItem = (DatItem)item.Clone(); datItem.CopyMachineInformation(copyFrom); - if (!items.Any(i => string.Equals(i.GetName(), datItem.GetName(), StringComparison.OrdinalIgnoreCase)) + if (items.FindIndex(i => string.Equals(i.GetName(), datItem.GetName(), StringComparison.OrdinalIgnoreCase)) == -1 && !items.Contains(datItem)) { Add(game, datItem); @@ -1430,7 +1440,9 @@ namespace SabreTools.DatFiles /// True to skip checking for duplicate ROMs in parent, false otherwise public void AddRomsFromChildren(bool subfolder, bool skipDedup) { - List games = [.. Keys.OrderBy(g => g)]; + List games = [.. Keys]; + games.Sort(); + foreach (string game in games) { // If the game has no items in it, we want to continue @@ -1552,7 +1564,9 @@ namespace SabreTools.DatFiles /// public void RemoveBiosAndDeviceSets() { - List games = [.. Keys.OrderBy(g => g)]; + List games = [.. Keys]; + games.Sort(); + foreach (string game in games) { // If the game has no items in it, we want to continue @@ -1581,7 +1595,9 @@ namespace SabreTools.DatFiles public void RemoveBiosRomsFromChild(bool bios) { // Loop through the romof tags - List games = [.. Keys.OrderBy(g => g)]; + List games = [.. Keys]; + games.Sort(); + foreach (string game in games) { // If the game has no items in it, we want to continue @@ -1625,7 +1641,9 @@ namespace SabreTools.DatFiles /// public void RemoveRomsFromChild() { - List games = [.. Keys.OrderBy(g => g)]; + List games = [.. Keys]; + games.Sort(); + foreach (string game in games) { // If the game has no items in it, we want to continue @@ -1673,7 +1691,9 @@ namespace SabreTools.DatFiles /// public void RemoveTagsFromChild() { - List games = [.. Keys.OrderBy(g => g)]; + List games = [.. Keys]; + games.Sort(); + foreach (string game in games) { // If the game has no items in it, we want to continue diff --git a/SabreTools.DatFiles/ItemDictionaryDB.cs b/SabreTools.DatFiles/ItemDictionaryDB.cs index 2a5307cb..272e2b80 100644 --- a/SabreTools.DatFiles/ItemDictionaryDB.cs +++ b/SabreTools.DatFiles/ItemDictionaryDB.cs @@ -286,7 +286,7 @@ namespace SabreTools.DatFiles /// public void ClearEmpty() { - var keys = SortedKeys.Where(k => k != null).ToList(); + var keys = Array.FindAll(SortedKeys, k => k != null); foreach (string key in keys) { // If the key doesn't exist, skip @@ -302,7 +302,7 @@ namespace SabreTools.DatFiles #endif // If there are no non-blank items, remove - else if (!_buckets[key]!.Any(i => GetItem(i) != null && GetItem(i) is not Blank)) + else if (!_buckets[key].Any(i => GetItem(i) != null && GetItem(i) is not Blank)) #if NET40_OR_GREATER || NETCOREAPP _buckets.TryRemove(key, out _); #else @@ -724,7 +724,7 @@ namespace SabreTools.DatFiles return false; // Try to find duplicates - return roms.Any(r => datItem.Equals(r.Item2)); + return Array.Exists(roms, r => datItem.Equals(r.Item2)); } /// @@ -1064,9 +1064,8 @@ namespace SabreTools.DatFiles #endif var datItems = itemIndices - .Where(i => _items.ContainsKey(i)) - .Select(i => (i, _items[i])) - .ToList(); + .FindAll(i => _items.ContainsKey(i)) + .ConvertAll(i => (i, _items[i])); Sort(ref datItems, false); @@ -1074,7 +1073,7 @@ namespace SabreTools.DatFiles if (dedupeType == DedupeType.Full || (dedupeType == DedupeType.Game && bucketBy == ItemKey.Machine)) datItems = Deduplicate(datItems); - _buckets[bucketKeys[i]] = datItems.Select(m => m.Item1).ToList(); + _buckets[bucketKeys[i]] = datItems.ConvertAll(m => m.i); #if NET40_OR_GREATER || NETCOREAPP }); #else @@ -1338,7 +1337,7 @@ namespace SabreTools.DatFiles string? machine = default; foreach (string region in regionList) { - machine = parents[key].FirstOrDefault(m => Regex.IsMatch(m, @"\(.*" + region + @".*\)", RegexOptions.IgnoreCase)); + machine = parents[key].Find(m => Regex.IsMatch(m, @"\(.*" + region + @".*\)", RegexOptions.IgnoreCase)); if (machine != default) break; } @@ -1432,7 +1431,7 @@ namespace SabreTools.DatFiles items[j] = item; } - _buckets[key] = items.Select(i => i.Item1).ToList(); + _buckets[key] = [.. Array.ConvertAll(items, i => i.Item1)]; #if NET40_OR_GREATER || NETCOREAPP }); #else @@ -1511,7 +1510,7 @@ namespace SabreTools.DatFiles } // Set the value in the key to the new set - _buckets[bucketName] = newItems.Select(i => i.Item1).ToList(); + _buckets[bucketName] = newItems.ConvertAll(i => i.Item1); } /// @@ -1598,7 +1597,7 @@ namespace SabreTools.DatFiles } // Replace the old list of roms with the new one - _buckets[key] = newItems.Select(i => i.Item1).ToList(); + _buckets[key] = newItems.ConvertAll(i => i.Item1); #if NET40_OR_GREATER || NETCOREAPP }); #else @@ -1645,8 +1644,11 @@ namespace SabreTools.DatFiles foreach ((long, DatItem) item in parentItems) { DatItem datItem = (item.Item2.Clone() as DatItem)!; - if (!items.Any(i => i.Item2.GetName() == datItem.GetName()) && !items.Any(i => i.Item2 == datItem)) + if (Array.FindIndex(items, i => i.Item2.GetName() == datItem.GetName()) > -1 + && Array.FindIndex(items, i => i.Item2 == datItem) > -1) + { AddItem(datItem, machine.Item1, source.Item1); + } } } } @@ -1701,7 +1703,7 @@ namespace SabreTools.DatFiles if (deviceReferences.Count > 0) { // Loop through all names and check the corresponding machines - List newDeviceReferences = []; + var newDeviceReferences = new HashSet(); foreach (string? deviceReference in deviceReferences) { // If the device reference is invalid @@ -1714,7 +1716,7 @@ namespace SabreTools.DatFiles continue; // Add to the list of new device reference names - newDeviceReferences.AddRange(devItems + newDeviceReferences.IntersectWith(devItems .Where(i => i.Item2 is DeviceRef) .Select(i => (i.Item2 as DeviceRef)!.GetName()!)); @@ -1741,7 +1743,7 @@ namespace SabreTools.DatFiles } // Now that every device reference is accounted for, add the new list of device references, if they don't already exist - foreach (string deviceReference in newDeviceReferences.Distinct()) + foreach (string deviceReference in newDeviceReferences) { if (!deviceReferences.Contains(deviceReference)) { @@ -1756,7 +1758,7 @@ namespace SabreTools.DatFiles if (useSlotOptions && slotOptions.Count > 0) { // Loop through all names and check the corresponding machines - List newSlotOptions = []; + var newSlotOptions = new HashSet(); foreach (string? slotOption in slotOptions) { // If the slot option is invalid @@ -1769,7 +1771,7 @@ namespace SabreTools.DatFiles continue; // Add to the list of new slot option names - newSlotOptions.AddRange(slotItems + newSlotOptions.IntersectWith(slotItems .Where(i => i.Item2 is Slot) .Where(s => (s.Item2 as Slot)!.SlotOptionsSpecified) .SelectMany(s => (s.Item2 as Slot)!.GetFieldValue(Models.Metadata.Slot.SlotOptionKey)!) @@ -1798,7 +1800,7 @@ namespace SabreTools.DatFiles } // Now that every device is accounted for, add the new list of slot options, if they don't already exist - foreach (string slotOption in newSlotOptions.Distinct()) + foreach (string slotOption in newSlotOptions) { if (!slotOptions.Contains(slotOption)) { @@ -1852,8 +1854,8 @@ namespace SabreTools.DatFiles foreach (var item in parentItems) { DatItem datItem = (DatItem)item.Item2.Clone(); - if (!items.Any(i => i.Item2.GetName()?.ToLowerInvariant() == datItem.GetName()?.ToLowerInvariant()) - && !items.Any(i => i.Item2 == datItem)) + if (Array.FindIndex(items, i => i.Item2.GetName()?.ToLowerInvariant() == datItem.GetName()?.ToLowerInvariant()) > -1 + && Array.FindIndex(items, i => i.Item2 == datItem) > -1) { AddItem(datItem, machine.Item1, source.Item1); } @@ -1913,6 +1915,9 @@ namespace SabreTools.DatFiles { // Get the parent items and current machine name var parentItems = GetItemsForBucket(cloneOf!); + if (parentItems == null) + continue; + string? machineName = GetMachineForItem(item.Item1).Item2?.GetStringFieldValue(Models.Metadata.Machine.NameKey); // Special disk handling @@ -1921,7 +1926,7 @@ namespace SabreTools.DatFiles string? mergeTag = disk.GetStringFieldValue(Models.Metadata.Disk.MergeKey); // If the merge tag exists and the parent already contains it, skip - if (mergeTag != null && parentItems! + if (mergeTag != null && parentItems .Where(i => i.Item2 is Disk) .Select(i => (i.Item2 as Disk)!.GetName()) .Contains(mergeTag)) @@ -1930,7 +1935,7 @@ namespace SabreTools.DatFiles } // If the merge tag exists but the parent doesn't contain it, add to parent - else if (mergeTag != null && !parentItems! + else if (mergeTag != null && !parentItems .Where(i => i.Item2 is Disk) .Select(i => (i.Item2 as Disk)!.GetName()) .Contains(mergeTag)) @@ -1951,7 +1956,7 @@ namespace SabreTools.DatFiles else if (item.Item2 is Rom rom) { // If the merge tag exists and the parent already contains it, skip - if (rom.GetStringFieldValue(Models.Metadata.Rom.MergeKey) != null && parentItems! + if (rom.GetStringFieldValue(Models.Metadata.Rom.MergeKey) != null && parentItems .Where(i => i.Item2 is Rom) .Select(i => (i.Item2 as Rom)!.GetName()) .Contains(rom.GetStringFieldValue(Models.Metadata.Rom.MergeKey))) @@ -1960,7 +1965,7 @@ namespace SabreTools.DatFiles } // 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 && !parentItems! + else if (rom.GetStringFieldValue(Models.Metadata.Rom.MergeKey) != null && !parentItems .Where(i => i.Item2 is Rom) .Select(i => (i.Item2 as Rom)!.GetName()) .Contains(rom.GetStringFieldValue(Models.Metadata.Rom.MergeKey))) @@ -1973,7 +1978,7 @@ namespace SabreTools.DatFiles } // If the parent doesn't already contain this item, add to subfolder of parent - else if (!parentItems!.Contains(item) || skipDedup) + else if (Array.IndexOf(parentItems, item) == -1 || skipDedup) { if (subfolder) rom.SetName($"{machineName}\\{rom.GetName()}"); @@ -1984,7 +1989,7 @@ namespace SabreTools.DatFiles } // All other that would be missing to subfolder of parent - else if (!parentItems!.Contains(item)) + else if (Array.IndexOf(parentItems, item) == -1) { if (subfolder) item.Item2.SetName($"{machineName}\\{item.Item2.GetName()}"); @@ -2070,8 +2075,8 @@ namespace SabreTools.DatFiles // 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) { - var matchedIndices = items.Where(i => i.Item2 == item.Item2).Select(i => i.Item1); - foreach (long index in matchedIndices) + var matchedItems = Array.FindAll(items, i => i.Item2 == item.Item2); + foreach ((long index, _) in matchedItems) { RemoveItem(index); } @@ -2110,8 +2115,8 @@ namespace SabreTools.DatFiles // If the parent exists and has items, we remove the parent items from the current game foreach ((long, DatItem) item in parentItems) { - var matchedIndices = items.Where(i => i.Item2 == item.Item2).Select(i => i.Item1); - foreach (long index in matchedIndices) + var matchedItems = Array.FindAll(items, i => i.Item2 == item.Item2); + foreach ((long index, _) in matchedItems) { RemoveItem(index); } diff --git a/SabreTools.DatItems/DatItem.cs b/SabreTools.DatItems/DatItem.cs index ec544d70..4e32c7c3 100644 --- a/SabreTools.DatItems/DatItem.cs +++ b/SabreTools.DatItems/DatItem.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.IO; -using System.Linq; using System.Reflection; using System.Xml.Serialization; using Newtonsoft.Json; @@ -1022,9 +1021,8 @@ namespace SabreTools.DatItems /// Clone of the DatItem public override object Clone() { - var concrete = Assembly.GetExecutingAssembly() - .GetTypes() - .FirstOrDefault(t => !t.IsAbstract && t.IsClass && t.BaseType == typeof(DatItem)); + var concrete = Array.Find(Assembly.GetExecutingAssembly().GetTypes(), + t => !t.IsAbstract && t.IsClass && t.BaseType == typeof(DatItem)); var clone = Activator.CreateInstance(concrete!); (clone as DatItem)!._internal = _internal?.Clone() as T ?? Activator.CreateInstance(); diff --git a/SabreTools.DatTools/DatFileTool.cs b/SabreTools.DatTools/DatFileTool.cs index dcbcaf82..7f01707a 100644 --- a/SabreTools.DatTools/DatFileTool.cs +++ b/SabreTools.DatTools/DatFileTool.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -532,7 +533,7 @@ namespace SabreTools.DatTools /// List of inputs to write out from public static DatFile DiffDuplicates(DatFile datFile, List inputs) { - List paths = inputs.Select(i => new ParentablePath(i)).ToList(); + List paths = inputs.ConvertAll(i => new ParentablePath(i)); return DiffDuplicates(datFile, paths); //return DiffDuplicatesDB(datFile, paths); } @@ -737,7 +738,7 @@ namespace SabreTools.DatTools /// List of inputs to write out from public static List DiffIndividuals(DatFile datFile, List inputs) { - List paths = inputs.Select(i => new ParentablePath(i)).ToList(); + List paths = inputs.ConvertAll(i => new ParentablePath(i)); return DiffIndividuals(datFile, paths); //return DiffIndividualsDB(datFile, paths); } @@ -967,7 +968,7 @@ namespace SabreTools.DatTools /// List of inputs to write out from public static DatFile DiffNoDuplicates(DatFile datFile, List inputs) { - List paths = inputs.Select(i => new ParentablePath(i)).ToList(); + List paths = inputs.ConvertAll(i => new ParentablePath(i)); return DiffNoDuplicates(datFile, paths); //return DiffNoDuplicatesDB(datFile, paths); } @@ -1171,7 +1172,7 @@ namespace SabreTools.DatTools /// List of DatHeader objects representing headers public static List PopulateUserData(DatFile datFile, List inputs) { - List paths = inputs.Select(i => new ParentablePath(i)).ToList(); + List paths = inputs.ConvertAll(i => new ParentablePath(i)); return PopulateUserData(datFile, paths); } @@ -1216,7 +1217,7 @@ namespace SabreTools.DatTools watch.Stop(); - return [.. datFiles.Select(d => d.Header)]; + return [.. Array.ConvertAll(datFiles, d => d.Header)]; } /// diff --git a/SabreTools.DatTools/Splitter.cs b/SabreTools.DatTools/Splitter.cs index 180c6a58..37d43723 100644 --- a/SabreTools.DatTools/Splitter.cs +++ b/SabreTools.DatTools/Splitter.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -46,10 +47,10 @@ namespace SabreTools.DatTools InternalStopwatch watch = new($"Splitting DAT by extension"); // Make sure all of the extensions don't have a dot at the beginning - var newExtA = extA.Select(s => s.TrimStart('.').ToLowerInvariant()).ToArray(); + var newExtA = extA.ConvertAll(s => s.TrimStart('.').ToLowerInvariant()).ToArray(); string newExtAString = string.Join(",", newExtA); - var newExtB = extB.Select(s => s.TrimStart('.').ToLowerInvariant()).ToArray(); + var newExtB = extB.ConvertAll(s => s.TrimStart('.').ToLowerInvariant()).ToArray(); string newExtBString = string.Join(",", newExtB); // Set all of the appropriate outputs for each of the subsets @@ -82,11 +83,11 @@ namespace SabreTools.DatTools foreach (DatItem item in items) { - if (newExtA.Contains((item.GetName() ?? string.Empty).GetNormalizedExtension())) + if (Array.IndexOf(newExtA, (item.GetName() ?? string.Empty).GetNormalizedExtension()) > -1) { extADat.Items.Add(key, item); } - else if (newExtB.Contains((item.GetName() ?? string.Empty).GetNormalizedExtension())) + if (Array.IndexOf(newExtB, (item.GetName() ?? string.Empty).GetNormalizedExtension()) > -1) { extBDat.Items.Add(key, item); } @@ -123,10 +124,10 @@ namespace SabreTools.DatTools InternalStopwatch watch = new($"Splitting DAT by extension"); // Make sure all of the extensions don't have a dot at the beginning - var newExtA = extA.Select(s => s.TrimStart('.').ToLowerInvariant()).ToArray(); + var newExtA = extA.ConvertAll(s => s.TrimStart('.').ToLowerInvariant()).ToArray(); string newExtAString = string.Join(",", newExtA); - var newExtB = extB.Select(s => s.TrimStart('.').ToLowerInvariant()).ToArray(); + var newExtB = extB.ConvertAll(s => s.TrimStart('.').ToLowerInvariant()).ToArray(); string newExtBString = string.Join(",", newExtB); // Set all of the appropriate outputs for each of the subsets diff --git a/SabreTools.FileTypes/Folder.cs b/SabreTools.FileTypes/Folder.cs index bada0cbf..d47b6e1e 100644 --- a/SabreTools.FileTypes/Folder.cs +++ b/SabreTools.FileTypes/Folder.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.IO; -using System.Linq; using SabreTools.Core.Tools; using SabreTools.FileTypes.Archives; using SabreTools.IO; @@ -181,7 +180,7 @@ namespace SabreTools.FileTypes List files = PathTool.GetFilesOrdered(Filename); // Now sort through to find the first file that matches - string? match = files.Where(s => s.EndsWith(entryName)).FirstOrDefault(); + string? match = files.Find(s => s.EndsWith(entryName)); // If we had a file, copy that over to the new name if (!string.IsNullOrEmpty(match)) @@ -220,7 +219,7 @@ namespace SabreTools.FileTypes List files = PathTool.GetFilesOrdered(Filename); // Now sort through to find the first file that matches - string? match = files.Where(s => s.EndsWith(entryName)).FirstOrDefault(); + string? match = files.Find(s => s.EndsWith(entryName)); // If we had a file, open and return the stream if (!string.IsNullOrEmpty(match)) diff --git a/SabreTools.Help/Feature.cs b/SabreTools.Help/Feature.cs index 40aa0e85..b6a0f5a3 100644 --- a/SabreTools.Help/Feature.cs +++ b/SabreTools.Help/Feature.cs @@ -116,7 +116,7 @@ namespace SabreTools.Help /// True if the flag was found, false otherwise public bool ContainsFlag(string name) { - return Flags.Any(f => f == name || f.TrimStart('-') == name); + return Flags.Exists(f => f == name || f.TrimStart('-') == name); } /// @@ -126,7 +126,7 @@ namespace SabreTools.Help /// True if the flag was found, false otherwise public bool StartsWith(char c) { - return Flags.Any(f => f.TrimStart('-').ToLowerInvariant()[0] == c); + return Flags.Exists(f => f.TrimStart('-').ToLowerInvariant()[0] == c); } #endregion @@ -202,7 +202,7 @@ namespace SabreTools.Help for (int i = 0; i < split.Length; i++) { // If we have a newline character, reset the line and continue - if (split[i].Contains('\n')) + if (split[i].Contains("\n")) { string[] subsplit = split[i].Replace("\r", string.Empty).Split('\n'); for (int j = 0; j < subsplit.Length - 1; j++) @@ -339,7 +339,7 @@ namespace SabreTools.Help for (int i = 0; i < split.Length; i++) { // If we have a newline character, reset the line and continue - if (split[i].Contains('\n')) + if (split[i].Contains("\n")) { string[] subsplit = split[i].Replace("\r", string.Empty).Split('\n'); for (int j = 0; j < subsplit.Length - 1; j++) @@ -404,12 +404,15 @@ namespace SabreTools.Help { bool valid = false; + // Pre-split the input for efficiency + string[] splitInput = input.Split('='); + // Determine what we should be looking for switch (_featureType) { // If we have a flag, make sure it doesn't have an equal sign in it case ParameterType.Flag: - valid = !input.Contains('=') && Flags.Contains(input); + valid = !input.Contains("=") && Flags.Contains(input); if (valid) { _value = true; @@ -425,10 +428,10 @@ namespace SabreTools.Help // If we have an Int32, try to parse it if at all possible case ParameterType.Int32: - valid = input.Contains('=') && Flags.Contains(input.Split('=')[0]); + valid = input.Contains("=") && Flags.Contains(splitInput[0]); if (valid) { - if (!Int32.TryParse(input.Split('=')[1], out int value)) + if (!Int32.TryParse(splitInput[1], out int value)) value = Int32.MinValue; _value = value; @@ -444,10 +447,10 @@ namespace SabreTools.Help // If we have an Int32, try to parse it if at all possible case ParameterType.Int64: - valid = input.Contains('=') && Flags.Contains(input.Split('=')[0]); + valid = input.Contains("=") && Flags.Contains(splitInput[0]); if (valid) { - if (!Int64.TryParse(input.Split('=')[1], out long value)) + if (!Int64.TryParse(splitInput[1], out long value)) value = Int64.MinValue; _value = value; @@ -463,20 +466,20 @@ namespace SabreTools.Help // If we have an input, make sure it has an equals sign in it case ParameterType.List: - valid = input.Contains('=') && Flags.Contains(input.Split('=')[0]); + valid = input.Contains("=") && Flags.Contains(splitInput[0]); if (valid) { _value ??= new List(); - (_value as List)?.Add(string.Join("=", input.Split('=').Skip(1).ToArray())); + (_value as List)?.Add(string.Join("=", splitInput, 1, splitInput.Length - 1)); } break; case ParameterType.String: - valid = input.Contains('=') && Flags.Contains(input.Split('=')[0]); + valid = input.Contains("=") && Flags.Contains(input.Split('=')[0]); if (valid) { - _value = string.Join("=", input.Split('=').Skip(1).ToArray()); + _value = string.Join("=", splitInput, 1, splitInput.Length - 1); // If we've already found this feature before if (_foundOnce && !ignore) diff --git a/SabreTools.Help/FeatureSet.cs b/SabreTools.Help/FeatureSet.cs index 0f3ab391..d92ec455 100644 --- a/SabreTools.Help/FeatureSet.cs +++ b/SabreTools.Help/FeatureSet.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Linq; namespace SabreTools.Help { @@ -84,7 +83,20 @@ namespace SabreTools.Help /// Feature name public string GetFeatureName(string name) { - return _features.Keys.FirstOrDefault(f => _features[f]?.ValidateInput(name, exact: true, ignore: true) ?? false) ?? string.Empty; + foreach (var key in _features.Keys) + { + // Skip invalid features + var feature = _features[key]; + if (feature == null) + continue; + + // If validation passes + if (feature.ValidateInput(name, exact: true, ignore: true)) + return key; + } + + // No feature could be found + return string.Empty; } /// @@ -236,7 +248,20 @@ namespace SabreTools.Help /// True if the feature was found, false otherwise public bool TopLevelFlag(string flag) { - return _features.Keys.Any(f => _features[f]?.ValidateInput(flag, exact: true) ?? false); + foreach (var key in _features.Keys) + { + // Skip invalid features + var feature = _features[key]; + if (feature == null) + continue; + + // If validation passes + if (feature.ValidateInput(flag, exact: true)) + return true; + } + + // No feature could be found + return false; } /// diff --git a/SabreTools/Features/Batch.cs b/SabreTools/Features/Batch.cs index 9dcf373a..e813a170 100644 --- a/SabreTools/Features/Batch.cs +++ b/SabreTools/Features/Batch.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.IO; -using System.Linq; using System.Text.RegularExpressions; using SabreTools.Core.Filter; using SabreTools.Core.Tools; @@ -118,7 +117,7 @@ Reset the internal state: reset();"; } // Now run the command - logger.User($"Attempting to invoke {command.Name} with {(command.Arguments.Count == 0 ? "no arguments" : "the following argument(s): " + string.Join(", ", command.Arguments))}"); + logger.User($"Attempting to invoke {command.Name} with {(command.Arguments.Length == 0 ? "no arguments" : "the following argument(s): " + string.Join(", ", command.Arguments))}"); command.Process(batchState); } } @@ -136,14 +135,14 @@ Reset the internal state: reset();"; private abstract class BatchCommand { public string? Name { get; set; } - public List Arguments { get; private set; } = []; + public string[] Arguments { get; private set; } = []; /// /// Default constructor for setting arguments /// - public BatchCommand(List arguments) + public BatchCommand(string[] args) { - Arguments = arguments; + Arguments = args; } /// @@ -166,13 +165,8 @@ Reset the internal state: reset();"; // Otherwise, get the name and arguments string commandName = match.Groups[1].Value; - List arguments = match - .Groups[2] - .Value - .Split(',') - .Select(s => s.Trim().Trim('"').Trim()) - .Where(s => !string.IsNullOrWhiteSpace(s)) // TODO: This may interfere with header value replacement - .ToList(); + string[] arguments = match.Groups[2].Value.Split(','); + arguments = Array.ConvertAll(arguments, s => s.Trim().Trim('"').Trim()); return commandName.ToLowerInvariant() switch { @@ -219,7 +213,7 @@ Reset the internal state: reset();"; private class DescriptionAsNameCommand : BatchCommand { /// - public DescriptionAsNameCommand(List arguments) : base(arguments) { } + public DescriptionAsNameCommand(string[] args) : base(args) { } /// public override string Usage() @@ -230,9 +224,9 @@ Reset the internal state: reset();"; /// public override (bool, string?) ValidateArguments() { - if (Arguments.Count != 0) + if (Arguments.Length != 0) { - string message = $"Invoked {Name} and expected no arguments, but {Arguments.Count} arguments were provided"; + string message = $"Invoked {Name} and expected no arguments, but {Arguments.Length} arguments were provided"; return (false, message); } @@ -253,7 +247,7 @@ Reset the internal state: reset();"; private class DFDCommand : BatchCommand { /// - public DFDCommand(List arguments) : base(arguments) { } + public DFDCommand(string[] args) : base(args) { } /// public override string Usage() @@ -264,7 +258,7 @@ Reset the internal state: reset();"; /// public override (bool, string?) ValidateArguments() { - if (Arguments.Count == 0) + if (Arguments.Length == 0) { string message = $"Invoked {Name} but no arguments were provided"; return (false, message); @@ -299,7 +293,7 @@ Reset the internal state: reset();"; private class ExtraCommand : BatchCommand { /// - public ExtraCommand(List arguments) : base(arguments) { } + public ExtraCommand(string[] args) : base(args) { } /// public override string Usage() @@ -310,9 +304,9 @@ Reset the internal state: reset();"; /// public override (bool, string?) ValidateArguments() { - if (Arguments.Count != 2) + if (Arguments.Length != 2) { - string message = $"Invoked {Name} and expected 2 arguments, but {Arguments.Count} arguments were provided"; + string message = $"Invoked {Name} and expected 2 arguments, but {Arguments.Length} arguments were provided"; return (false, message); } @@ -363,7 +357,7 @@ Reset the internal state: reset();"; private class FilterCommand : BatchCommand { /// - public FilterCommand(List arguments) : base(arguments) { } + public FilterCommand(string[] args) : base(args) { } /// public override string Usage() @@ -374,19 +368,19 @@ Reset the internal state: reset();"; /// public override (bool, string?) ValidateArguments() { - if (Arguments.Count < 2 || Arguments.Count > 4) + if (Arguments.Length < 2 || Arguments.Length > 4) { - string message = $"Invoked {Name} and expected between 2-4 arguments, but {Arguments.Count} arguments were provided"; + string message = $"Invoked {Name} and expected between 2-4 arguments, but {Arguments.Length} arguments were provided"; return (false, message); } // Read in the individual arguments string itemFieldString = Arguments[0]; bool? filterRemove = false; - if (Arguments.Count >= 3) + if (Arguments.Length >= 3) filterRemove = Arguments[2].AsYesNo(); bool? filterPerMachine = false; - if (Arguments.Count >= 4) + if (Arguments.Length >= 4) filterPerMachine = Arguments[3].AsYesNo(); // If we had an invalid input, log and continue @@ -420,11 +414,11 @@ Reset the internal state: reset();"; string filterField = Arguments[0]; string filterValue = Arguments[1]; bool? filterRemove = false; - if (Arguments.Count >= 3) + if (Arguments.Length >= 3) filterRemove = Arguments[2].AsYesNo(); // TODO: Add back this functionality bool? filterPerMachine = false; - if (Arguments.Count >= 4) + if (Arguments.Length >= 4) filterPerMachine = Arguments[3].AsYesNo(); // Build the filter statement @@ -451,7 +445,7 @@ Reset the internal state: reset();"; private class FormatCommand : BatchCommand { /// - public FormatCommand(List arguments) : base(arguments) { } + public FormatCommand(string[] args) : base(args) { } /// public override string Usage() @@ -462,7 +456,7 @@ Reset the internal state: reset();"; /// public override (bool, string?) ValidateArguments() { - if (Arguments.Count == 0) + if (Arguments.Length == 0) { string message = $"Invoked {Name} but no arguments were provided"; return (false, message); @@ -505,7 +499,7 @@ Reset the internal state: reset();"; private class InputCommand : BatchCommand { /// - public InputCommand(List arguments) : base(arguments) { } + public InputCommand(string[] args) : base(args) { } /// public override string Usage() @@ -516,7 +510,7 @@ Reset the internal state: reset();"; /// public override (bool, string?) ValidateArguments() { - if (Arguments.Count == 0) + if (Arguments.Length == 0) { string message = $"Invoked {Name} but no arguments were provided"; return (false, message); @@ -529,7 +523,7 @@ Reset the internal state: reset();"; public override void Process(BatchState batchState) { // Get only files from inputs - List datFilePaths = PathTool.GetFilesOnly(Arguments); + List datFilePaths = PathTool.GetFilesOnly([.. Arguments]); // Assume there could be multiple foreach (ParentablePath datFilePath in datFilePaths) @@ -545,7 +539,7 @@ Reset the internal state: reset();"; private class MergeCommand : BatchCommand { /// - public MergeCommand(List arguments) : base(arguments) { } + public MergeCommand(string[] args) : base(args) { } /// public override string Usage() @@ -556,9 +550,9 @@ Reset the internal state: reset();"; /// public override (bool, string?) ValidateArguments() { - if (Arguments.Count != 1) + if (Arguments.Length != 1) { - string message = $"Invoked {Name} and expected 1 argument, but {Arguments.Count} arguments were provided"; + string message = $"Invoked {Name} and expected 1 argument, but {Arguments.Length} arguments were provided"; return (false, message); } @@ -593,7 +587,7 @@ Reset the internal state: reset();"; private class OneGamePerRegionCommand : BatchCommand { /// - public OneGamePerRegionCommand(List arguments) : base(arguments) { } + public OneGamePerRegionCommand(string[] args) : base(args) { } /// public override string Usage() @@ -604,7 +598,7 @@ Reset the internal state: reset();"; /// public override (bool, string?) ValidateArguments() { - if (Arguments.Count == 0) + if (Arguments.Length == 0) { string message = $"Invoked {Name} but no arguments were provided"; return (false, message); @@ -616,8 +610,8 @@ Reset the internal state: reset();"; /// public override void Process(BatchState batchState) { - batchState.DatFile.Items.SetOneGamePerRegion(Arguments); - batchState.DatFile.ItemsDB.SetOneGamePerRegion(Arguments); + batchState.DatFile.Items.SetOneGamePerRegion([.. Arguments]); + batchState.DatFile.ItemsDB.SetOneGamePerRegion([.. Arguments]); } } @@ -627,7 +621,7 @@ Reset the internal state: reset();"; private class OneRomPerGameCommand : BatchCommand { /// - public OneRomPerGameCommand(List arguments) : base(arguments) { } + public OneRomPerGameCommand(string[] args) : base(args) { } /// public override string Usage() @@ -638,9 +632,9 @@ Reset the internal state: reset();"; /// public override (bool, string?) ValidateArguments() { - if (Arguments.Count == 0) + if (Arguments.Length == 0) { - string message = $"Invoked {Name} and expected no arguments, but {Arguments.Count} arguments were provided"; + string message = $"Invoked {Name} and expected no arguments, but {Arguments.Length} arguments were provided"; return (false, message); } @@ -661,7 +655,7 @@ Reset the internal state: reset();"; private class OutputCommand : BatchCommand { /// - public OutputCommand(List arguments) : base(arguments) { } + public OutputCommand(string[] args) : base(args) { } /// public override string Usage() @@ -672,9 +666,9 @@ Reset the internal state: reset();"; /// public override (bool, string?) ValidateArguments() { - if (Arguments.Count != 1) + if (Arguments.Length != 1) { - string message = $"Invoked {Name} and expected exactly 1 argument, but {Arguments.Count} arguments were provided"; + string message = $"Invoked {Name} and expected exactly 1 argument, but {Arguments.Length} arguments were provided"; return (false, message); } @@ -694,7 +688,7 @@ Reset the internal state: reset();"; private class RemoveCommand : BatchCommand { /// - public RemoveCommand(List arguments) : base(arguments) { } + public RemoveCommand(string[] args) : base(args) { } /// public override string Usage() @@ -705,7 +699,7 @@ Reset the internal state: reset();"; /// public override (bool, string?) ValidateArguments() { - if (Arguments.Count == 0) + if (Arguments.Length == 0) { string message = $"Invoked {Name} but no arguments were provided"; return (false, message); @@ -718,7 +712,7 @@ Reset the internal state: reset();"; public override void Process(BatchState batchState) { var remover = new Remover(); - remover.PopulateExclusionsFromList(Arguments); + remover.PopulateExclusionsFromList([.. Arguments]); remover.ApplyRemovals(batchState.DatFile); } } @@ -729,7 +723,7 @@ Reset the internal state: reset();"; private class ResetCommand : BatchCommand { /// - public ResetCommand(List arguments) : base(arguments) { } + public ResetCommand(string[] args) : base(args) { } /// public override string Usage() @@ -740,9 +734,9 @@ Reset the internal state: reset();"; /// public override (bool, string?) ValidateArguments() { - if (Arguments.Count != 0) + if (Arguments.Length != 0) { - string message = $"Invoked {Name} and expected no arguments, but {Arguments.Count} arguments were provided"; + string message = $"Invoked {Name} and expected no arguments, but {Arguments.Length} arguments were provided"; return (false, message); } @@ -762,7 +756,7 @@ Reset the internal state: reset();"; private class SceneDateStripCommand : BatchCommand { /// - public SceneDateStripCommand(List arguments) : base(arguments) { } + public SceneDateStripCommand(string[] args) : base(args) { } /// public override string Usage() @@ -773,9 +767,9 @@ Reset the internal state: reset();"; /// public override (bool, string?) ValidateArguments() { - if (Arguments.Count != 0) + if (Arguments.Length != 0) { - string message = $"Invoked {Name} and expected no arguments, but {Arguments.Count} arguments were provided"; + string message = $"Invoked {Name} and expected no arguments, but {Arguments.Length} arguments were provided"; return (false, message); } @@ -796,7 +790,7 @@ Reset the internal state: reset();"; private class SetCommand : BatchCommand { /// - public SetCommand(List arguments) : base(arguments) { } + public SetCommand(string[] args) : base(args) { } /// public override string Usage() @@ -807,7 +801,7 @@ Reset the internal state: reset();"; /// public override (bool, string?) ValidateArguments() { - if (Arguments.Count != 2) + if (Arguments.Length != 2) { string message = $"Invoked {Name} but no arguments were provided"; return (false, message); @@ -853,7 +847,7 @@ Reset the internal state: reset();"; private class WriteCommand : BatchCommand { /// - public WriteCommand(List arguments) : base(arguments) { } + public WriteCommand(string[] args) : base(args) { } /// public override string Usage() @@ -864,15 +858,15 @@ Reset the internal state: reset();"; /// public override (bool, string?) ValidateArguments() { - if (Arguments.Count > 1) + if (Arguments.Length > 1) { - string message = $"Invoked {Name} and expected 0-1 arguments, but {Arguments.Count} arguments were provided"; + string message = $"Invoked {Name} and expected 0-1 arguments, but {Arguments.Length} arguments were provided"; return (false, message); } // Get overwrite value, if possible bool? overwrite = true; - if (Arguments.Count == 1) + if (Arguments.Length == 1) overwrite = Arguments[0].AsYesNo(); // If we had an invalid input, log and continue @@ -890,7 +884,7 @@ Reset the internal state: reset();"; { // Get overwrite value, if possible bool overwrite = true; - if (Arguments.Count == 1) + if (Arguments.Length == 1) overwrite = Arguments[0].AsYesNo() ?? true; // Write out the dat with the current state