using System.Collections.Generic; #if NET40_OR_GREATER || NETCOREAPP using System.Threading.Tasks; #endif using SabreTools.Core.Tools; using SabreTools.DatItems; using SabreTools.DatItems.Formats; namespace SabreTools.DatFiles { public partial class DatFile { #region Removal /// /// Remove header fields with given values /// public void RemoveHeaderFields(List fields) { // If we have an invalid input, return if (fields.Count == 0) return; foreach (var fieldName in fields) { bool removed = Header.RemoveField(fieldName); _logger.Verbose($"Header field {fieldName} {(removed ? "removed" : "could not be removed")}"); } } /// /// Apply removals to the item dictionary /// public void RemoveItemFields(List machineFields, Dictionary> itemFields) { // If we have an invalid input, return if (machineFields.Count == 0 && itemFields.Count == 0) return; #if NET452_OR_GREATER || NETCOREAPP Parallel.ForEach(Items.Keys, Core.Globals.ParallelOptions, key => #elif NET40_OR_GREATER Parallel.ForEach(Items.Keys, key => #else foreach (var key in Items.Keys) #endif { List? items = Items[key]; if (items == null) #if NET40_OR_GREATER || NETCOREAPP return; #else continue; #endif for (int j = 0; j < items.Count; j++) { RemoveFields(items[j], machineFields, itemFields); } #if NET40_OR_GREATER || NETCOREAPP }); #else } #endif } /// /// Apply removals to the item dictionary /// public void RemoveItemFieldsDB(List machineFields, Dictionary> itemFields) { // If we have an invalid input, return if (machineFields.Count == 0 && itemFields.Count == 0) return; // Handle machine removals #if NET452_OR_GREATER || NETCOREAPP Parallel.ForEach(ItemsDB.GetMachines(), Core.Globals.ParallelOptions, kvp => #elif NET40_OR_GREATER Parallel.ForEach(ItemsDB.GetMachines(), kvp => #else foreach (var kvp in ItemsDB.GetMachines()) #endif { RemoveFields(kvp.Value, machineFields); #if NET40_OR_GREATER || NETCOREAPP }); #else } #endif // Handle item removals #if NET452_OR_GREATER || NETCOREAPP Parallel.ForEach(ItemsDB.SortedKeys, Core.Globals.ParallelOptions, key => #elif NET40_OR_GREATER Parallel.ForEach(ItemsDB.SortedKeys, key => #else foreach (var key in ItemsDB.SortedKeys) #endif { var items = ItemsDB.GetItemsForBucket(key); if (items == null) #if NET40_OR_GREATER || NETCOREAPP return; #else continue; #endif foreach (var item in items.Values) { RemoveFields(item, [], itemFields); } #if NET40_OR_GREATER || NETCOREAPP }); #else } #endif } /// /// Remove machine fields with given values /// private static void RemoveFields(Machine? machine, List fields) { // If we have an invalid input, return if (machine == null || fields.Count == 0) return; foreach (var fieldName in fields) { machine.RemoveField(fieldName); } } /// /// Remove fields with given values /// /// DatItem to remove fields from private static void RemoveFields(DatItem? datItem, List machineFields, Dictionary> itemFields) { if (datItem == null) return; #region Common // Handle Machine fields var machine = datItem.GetFieldValue(DatItem.MachineKey); if (machineFields.Count > 0 && machine != null) RemoveFields(machine, machineFields); // If there are no field names, return if (itemFields == null || itemFields.Count == 0) return; // If there are no field names for this type or generic, return string? itemType = datItem.GetStringFieldValue(Models.Metadata.DatItem.TypeKey).AsEnumValue().AsStringValue(); if (itemType == null || (!itemFields.ContainsKey(itemType) && !itemFields.ContainsKey("item"))) return; // Get the combined list of fields to remove var fields = new HashSet(); if (itemFields.ContainsKey(itemType)) fields.UnionWith(itemFields[itemType]); if (itemFields.ContainsKey("item")) fields.UnionWith(itemFields["item"]); // If the field specifically contains Name, set it separately if (fields.Contains(Models.Metadata.Rom.NameKey)) datItem.SetName(null); #endregion #region Item-Specific // Handle unnested removals first foreach (var datItemField in fields) { datItem.RemoveField(datItemField); } // Handle nested removals switch (datItem) { case Adjuster adjuster: RemoveFields(adjuster, itemFields); break; case Configuration configuration: RemoveFields(configuration, itemFields); break; case ConfSetting confSetting: RemoveFields(confSetting, itemFields); break; case Device device: RemoveFields(device, itemFields); break; case DipSwitch dipSwitch: RemoveFields(dipSwitch, itemFields); break; case DipValue dipValue: RemoveFields(dipValue, itemFields); break; case Disk disk: RemoveFields(disk, itemFields); break; case Input input: RemoveFields(input, itemFields); break; case Part part: RemoveFields(part, itemFields); break; case Port port: RemoveFields(port, itemFields); break; case Rom rom: RemoveFields(rom, itemFields); break; case Slot slot: RemoveFields(slot, itemFields); break; } #endregion } /// /// Remove fields with given values /// /// Adjuster to remove fields from private static void RemoveFields(Adjuster adjuster, Dictionary> fields) { var conditions = adjuster.GetFieldValue(Models.Metadata.Adjuster.ConditionKey) ?? []; foreach (Condition subCondition in conditions) { RemoveFields(subCondition, [], fields); } } /// /// Remove fields with given values /// /// Configuration to remove fields from private static void RemoveFields(Configuration configuration, Dictionary> fields) { var conditions = configuration.GetFieldValue(Models.Metadata.Configuration.ConditionKey) ?? []; foreach (Condition subCondition in conditions) { RemoveFields(subCondition, [], fields); } var locations = configuration.GetFieldValue(Models.Metadata.Configuration.ConfLocationKey) ?? []; foreach (ConfLocation subLocation in locations) { RemoveFields(subLocation, [], fields); } var settings = configuration.GetFieldValue(Models.Metadata.Configuration.ConfSettingKey) ?? []; foreach (ConfSetting subSetting in settings) { RemoveFields(subSetting as DatItem, [], fields); } } /// /// Remove fields with given values /// /// ConfSetting to remove fields from private static void RemoveFields(ConfSetting confsetting, Dictionary> fields) { var conditions = confsetting.GetFieldValue(Models.Metadata.ConfSetting.ConditionKey) ?? []; foreach (Condition subCondition in conditions) { RemoveFields(subCondition, [], fields); } } /// /// Remove fields with given values /// /// Device to remove fields from private static void RemoveFields(Device device, Dictionary> fields) { var extensions = device.GetFieldValue(Models.Metadata.Device.ExtensionKey) ?? []; foreach (Extension subExtension in extensions) { RemoveFields(subExtension, [], fields); } var instances = device.GetFieldValue(Models.Metadata.Device.InstanceKey) ?? []; foreach (Instance subInstance in instances) { RemoveFields(subInstance, [], fields); } } /// /// Remove fields with given values /// /// DipSwitch to remove fields from private static void RemoveFields(DipSwitch dipSwitch, Dictionary> fields) { var conditions = dipSwitch.GetFieldValue(Models.Metadata.DipSwitch.ConditionKey) ?? []; foreach (Condition subCondition in conditions) { RemoveFields(subCondition, [], fields); } var locations = dipSwitch.GetFieldValue(Models.Metadata.DipSwitch.DipLocationKey) ?? []; foreach (DipLocation subLocation in locations) { RemoveFields(subLocation, [], fields); } var dipValues = dipSwitch.GetFieldValue(Models.Metadata.DipSwitch.DipValueKey) ?? []; foreach (DipValue subValue in dipValues) { RemoveFields(subValue as DatItem, [], fields); } var part = dipSwitch.GetFieldValue(DipSwitch.PartKey); if (part != null) RemoveFields(part as DatItem, [], fields); } /// /// Remove fields with given values /// /// DipValue to remove fields from private static void RemoveFields(DipValue dipValue, Dictionary> fields) { var conditions = dipValue.GetFieldValue(Models.Metadata.DipValue.ConditionKey) ?? []; foreach (Condition subCondition in conditions) { RemoveFields(subCondition, [], fields); } } /// /// Remove fields with given values /// /// Disk to remove fields from private static void RemoveFields(Disk disk, Dictionary> fields) { var diskArea = disk.GetFieldValue(Disk.DiskAreaKey); if (diskArea != null) RemoveFields(diskArea as DatItem, [], fields); var part = disk.GetFieldValue(Disk.PartKey); if (part != null) RemoveFields(part as DatItem, [], fields); } /// /// Remove fields with given values /// /// Input to remove fields from private static void RemoveFields(Input input, Dictionary> fields) { var controls = input.GetFieldValue(Models.Metadata.Input.ControlKey) ?? []; foreach (Control subControl in controls) { RemoveFields(subControl, [], fields); } } /// /// Remove fields with given values /// /// Part to remove fields from private static void RemoveFields(Part part, Dictionary> fields) { var features = part.GetFieldValue(Models.Metadata.Part.FeatureKey) ?? []; foreach (PartFeature subPartFeature in features) { RemoveFields(subPartFeature, [], fields); } } /// /// Remove fields with given values /// /// Port to remove fields from private static void RemoveFields(Port port, Dictionary> fields) { var analogs = port.GetFieldValue(Models.Metadata.Port.AnalogKey) ?? []; foreach (Analog subAnalog in analogs) { RemoveFields(subAnalog, [], fields); } } /// /// Remove fields with given values /// /// Rom to remove fields from private static void RemoveFields(Rom rom, Dictionary> fields) { var dataArea = rom.GetFieldValue(Rom.DataAreaKey); if (dataArea != null) RemoveFields(dataArea as DatItem, [], fields); var part = rom.GetFieldValue(Rom.PartKey); if (part != null) RemoveFields(part as DatItem, [], fields); } /// /// Remove fields with given values /// /// Slot to remove fields from private static void RemoveFields(Slot slot, Dictionary> fields) { var slotOptions = slot.GetFieldValue(Models.Metadata.Slot.SlotOptionKey) ?? []; foreach (SlotOption subSlotOption in slotOptions) { RemoveFields(subSlotOption, [], fields); } } #endregion } }