diff --git a/SabreTools.DatFiles/ItemDictionaryDB.cs b/SabreTools.DatFiles/ItemDictionaryDB.cs
index 429d2d49..1b8ffb09 100644
--- a/SabreTools.DatFiles/ItemDictionaryDB.cs
+++ b/SabreTools.DatFiles/ItemDictionaryDB.cs
@@ -736,7 +736,7 @@ namespace SabreTools.DatFiles
/// Merge an arbitrary set of item pairs based on the supplied information
///
/// List of pairs representing the items to be merged
- private List> Deduplicate(List> itemMappings)
+ private List> Merge(List> itemMappings)
{
// Check for null or blank roms first
if (itemMappings == null || itemMappings.Count == 0)
@@ -769,83 +769,66 @@ namespace SabreTools.DatFiles
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)
+ if (output.Count == nodumpCount)
{
output.Add(new KeyValuePair(itemIndex, datItem));
continue;
}
- // Check if the rom is a duplicate
- DupeType dupetype = 0x00;
- long savedIndex = -1;
- DatItem saveditem = new Blank();
- int pos = -1;
- for (int i = 0; i < output.Count; i++)
- {
- long lastIndex = output[i].Key;
- DatItem lastrom = output[i].Value;
-
- // Get the sources associated with the items
- var savedSource = _sources[_itemToSourceMapping[savedIndex]];
- var itemSource = _sources[_itemToSourceMapping[itemIndex]];
-
- // Get the duplicate status
- dupetype = datItem.GetDuplicateStatus(itemSource, lastrom, savedSource);
-
- // If it's a duplicate, skip adding it to the output but add any missing information
- if (dupetype != 0x00)
- {
- savedIndex = lastIndex;
- saveditem = lastrom;
- pos = i;
-
- // Disks, Media, and Roms have more information to fill
- if (datItem is Disk disk && saveditem is Disk savedDisk)
- savedDisk.FillMissingInformation(disk);
- else if (datItem is DatItems.Formats.File fileItem && saveditem is DatItems.Formats.File savedFile)
- savedFile.FillMissingInformation(fileItem);
- else if (datItem is Media media && saveditem is Media savedMedia)
- savedMedia.FillMissingInformation(media);
- else if (datItem is Rom romItem && saveditem is Rom savedRom)
- savedRom.FillMissingInformation(romItem);
-
- saveditem.SetFieldValue(DatItem.DupeTypeKey, dupetype);
-
- // Get the machines associated with the items
- var savedMachine = _machines[_itemToMachineMapping[savedIndex]];
- var itemMachine = _machines[_itemToMachineMapping[itemIndex]];
-
- // If the current system has a lower ID than the previous, set the system accordingly
- if (itemSource?.Index < savedSource?.Index)
- {
- _itemToSourceMapping[itemIndex] = _itemToSourceMapping[savedIndex];
- _machines[_itemToMachineMapping[savedIndex]] = (itemMachine.Clone() as Machine)!;
- saveditem.SetName(datItem.GetName());
- }
-
- // If the current machine is a child of the new machine, use the new machine instead
- if (savedMachine.GetStringFieldValue(Models.Metadata.Machine.CloneOfKey) == itemMachine.GetStringFieldValue(Models.Metadata.Machine.NameKey)
- || savedMachine.GetStringFieldValue(Models.Metadata.Machine.RomOfKey) == itemMachine.GetStringFieldValue(Models.Metadata.Machine.NameKey))
- {
- _machines[_itemToMachineMapping[savedIndex]] = (itemMachine.Clone() as Machine)!;
- saveditem.SetName(datItem.GetName());
- }
-
- break;
- }
- }
-
- // If no duplicate is found, add it to the list
- if (dupetype == 0x00)
+ // Find the index of the first duplicate, if one exists
+ int pos = output.FindIndex(lastItem => datItem.GetDuplicateStatus(lastItem.Value) != 0x00);
+ if (pos < 0)
{
output.Add(new KeyValuePair(itemIndex, datItem));
+ continue;
}
- // Otherwise, if a new rom information is found, add that
+
+ // Get the duplicate item
+ long savedIndex = output[pos].Key;
+ DatItem savedItem = output[pos].Value;
+ DupeType dupetype = datItem.GetDuplicateStatus(savedItem);
+
+ // Disks, Media, and Roms have more information to fill
+ if (datItem is Disk diskItem && savedItem is Disk savedDisk)
+ savedDisk.FillMissingInformation(diskItem);
+ else if (datItem is DatItems.Formats.File fileItem && savedItem is DatItems.Formats.File savedFile)
+ savedFile.FillMissingInformation(fileItem);
+ else if (datItem is Media mediaItem && savedItem is Media savedMedia)
+ savedMedia.FillMissingInformation(mediaItem);
+ else if (datItem is Rom romItem && savedItem is Rom savedRom)
+ savedRom.FillMissingInformation(romItem);
+
+ savedItem.SetFieldValue(DatItem.DupeTypeKey, dupetype);
+
+ // Get the sources associated with the items
+ var savedSource = _sources[_itemToSourceMapping[savedIndex]];
+ var itemSource = _sources[_itemToSourceMapping[itemIndex]];
+
+ // Get the machines associated with the items
+ var savedMachine = _machines[_itemToMachineMapping[savedIndex]];
+ var itemMachine = _machines[_itemToMachineMapping[itemIndex]];
+
+ // If the current system has a lower ID than the previous, set the system accordingly
+ if (itemSource?.Index < savedSource?.Index)
{
- output.RemoveAt(pos);
- output.Insert(pos, new KeyValuePair(savedIndex, saveditem));
+ _itemToSourceMapping[itemIndex] = _itemToSourceMapping[savedIndex];
+ _machines[_itemToMachineMapping[savedIndex]] = (itemMachine.Clone() as Machine)!;
+ savedItem.SetName(datItem.GetName());
}
+
+ // If the current machine is a child of the new machine, use the new machine instead
+ if (savedMachine.GetStringFieldValue(Models.Metadata.Machine.CloneOfKey) == itemMachine.GetStringFieldValue(Models.Metadata.Machine.NameKey)
+ || savedMachine.GetStringFieldValue(Models.Metadata.Machine.RomOfKey) == itemMachine.GetStringFieldValue(Models.Metadata.Machine.NameKey))
+ {
+ _machines[_itemToMachineMapping[savedIndex]] = (itemMachine.Clone() as Machine)!;
+ savedItem.SetName(datItem.GetName());
+ }
+
+ // Replace the original item in the list
+ output.RemoveAt(pos);
+ output.Insert(pos, new KeyValuePair(savedIndex, savedItem));
}
return output;
@@ -1072,7 +1055,7 @@ namespace SabreTools.DatFiles
// If we're merging the roms, do so
if (dedupeType == DedupeType.Full || (dedupeType == DedupeType.Game && bucketBy == ItemKey.Machine))
- datItems = Deduplicate(datItems);
+ datItems = Merge(datItems);
_buckets[bucketKeys[i]] = [.. datItems.Select(kvp => kvp.Key)];
#if NET40_OR_GREATER || NETCOREAPP
diff --git a/SabreTools.DatItems/DatItem.cs b/SabreTools.DatItems/DatItem.cs
index 6ac2045e..d1dee63d 100644
--- a/SabreTools.DatItems/DatItem.cs
+++ b/SabreTools.DatItems/DatItem.cs
@@ -123,75 +123,6 @@ namespace SabreTools.DatItems
/// Clone of the DatItem
public abstract object Clone();
- ///
- /// Conditionally copy all machine information from another item
- ///
- /// Existing item to copy information from
- ///
- /// The cases when Machine data is updated:
- /// - Current machine is a clone of the other machine
- /// - Current machine is a rom of the other machine
- ///
- public void ConditionalUpdateMachine(DatItem item)
- {
- // Get the machines for the two items
- Machine? selfMachine = GetFieldValue(DatItem.MachineKey);
- Machine? itemMachine = item.GetFieldValue(DatItem.MachineKey);
-
- // If either machine is missing
- if (selfMachine == null || itemMachine == null)
- return;
-
- // Get the required strings
- string? selfCloneOf = selfMachine.GetStringFieldValue(Models.Metadata.Machine.CloneOfKey);
- string? selfRomOf = selfMachine.GetStringFieldValue(Models.Metadata.Machine.RomOfKey);
- string? otherMachineName = itemMachine.GetStringFieldValue(Models.Metadata.Machine.NameKey);
-
- // If the other machine has no name
- if (otherMachineName == null)
- return;
-
- // If the current machine is a child of the new machine, use the new machine instead
- if (selfCloneOf == otherMachineName)
- {
- CopyMachineInformation(item);
- SetName(item.GetName());
- }
- else if (selfRomOf == otherMachineName)
- {
- CopyMachineInformation(item);
- SetName(item.GetName());
- }
- }
-
- ///
- /// Conditionally copy all source information from another item
- ///
- /// Existing item to copy information from
- ///
- /// The cases when Source data is updated:
- /// - Current source data has an index higher than the other item
- ///
- public void ConditionalUpdateSource(DatItem item)
- {
- // Get the sources for comparison
- Source? selfSource = GetFieldValue(DatItem.SourceKey);
- Source? itemSource = item.GetFieldValue(DatItem.SourceKey);
-
- // If either source is missing
- if (selfSource == null || itemSource == null)
- return;
-
- // Use the new source if less than
- if (selfSource.Index > itemSource.Index)
- {
- SetFieldValue(DatItem.SourceKey, itemSource.Clone() as Source);
- CopyMachineInformation(item);
- SetName(item.GetName());
- return;
- }
- }
-
///
/// Copy all machine information over in one shot
///
diff --git a/SabreTools.DatItems/DatItemTool.cs b/SabreTools.DatItems/DatItemTool.cs
index 314b5cd2..300ee2b1 100644
--- a/SabreTools.DatItems/DatItemTool.cs
+++ b/SabreTools.DatItems/DatItemTool.cs
@@ -281,85 +281,93 @@ namespace SabreTools.DatItems
return [];
// Create output list
- List outfiles = [];
+ List output = [];
// Then deduplicate them by checking to see if data matches previous saved roms
int nodumpCount = 0;
- foreach (DatItem item in items)
+ foreach (DatItem datItem in items)
{
// If we don't have a Disk, File, Media, or Rom, we skip checking for duplicates
- if (item is not Disk && item is not Formats.File && item is not Media && item is not Rom)
+ if (datItem is not Disk && datItem is not Formats.File && datItem is not Media && datItem is not Rom)
continue;
// If it's a nodump, add and skip
- if (item is Rom rom && rom.GetStringFieldValue(Models.Metadata.Rom.StatusKey).AsEnumValue() == ItemStatus.Nodump)
+ if (datItem is Rom rom && rom.GetStringFieldValue(Models.Metadata.Rom.StatusKey).AsEnumValue() == ItemStatus.Nodump)
{
- outfiles.Add(item);
+ output.Add(datItem);
nodumpCount++;
continue;
}
- else if (item is Disk disk && disk.GetStringFieldValue(Models.Metadata.Disk.StatusKey).AsEnumValue() == ItemStatus.Nodump)
+ else if (datItem is Disk disk && disk.GetStringFieldValue(Models.Metadata.Disk.StatusKey).AsEnumValue() == ItemStatus.Nodump)
{
- outfiles.Add(item);
+ output.Add(datItem);
nodumpCount++;
continue;
}
// If it's the first non-nodump item in the list, don't touch it
- if (outfiles.Count == nodumpCount)
+ if (output.Count == nodumpCount)
{
- outfiles.Add(item);
+ output.Add(datItem);
continue;
}
- // Check if the item is a duplicate
- DupeType dupetype = 0x00;
- DatItem savedItem = new Blank();
- int pos = -1;
- for (int i = 0; i < outfiles.Count; i++)
+ // Find the index of the first duplicate, if one exists
+ int pos = output.FindIndex(lastItem => datItem.GetDuplicateStatus(lastItem) != 0x00);
+ if (pos < 0)
{
- // Get the next item
- DatItem lastItem = outfiles[i];
-
- // Get the duplicate status
- dupetype = item.GetDuplicateStatus(lastItem);
- if (dupetype == 0x00)
- continue;
-
- // If it's a duplicate, skip adding it to the output but add any missing information
- savedItem = lastItem;
- pos = i;
-
- // Disks, File, Media, and Roms have more information to fill
- if (item is Disk disk && savedItem is Disk savedDisk)
- savedDisk.FillMissingInformation(disk);
- else if (item is Formats.File fileItem && savedItem is Formats.File savedFile)
- savedFile.FillMissingInformation(fileItem);
- else if (item is Media media && savedItem is Media savedMedia)
- savedMedia.FillMissingInformation(media);
- else if (item is Rom romItem && savedItem is Rom savedRom)
- savedRom.FillMissingInformation(romItem);
-
- // Set the duplicate type on the saved item
- savedItem.SetFieldValue(DatItem.DupeTypeKey, dupetype);
- break;
+ output.Add(datItem);
+ continue;
}
- // If no duplicate is found, add it to the list
- if (dupetype == 0x00 || pos < 0)
+ // Get the duplicate item
+ DatItem savedItem = output[pos];
+ DupeType dupetype = datItem.GetDuplicateStatus(savedItem);
+
+ // Disks, File, Media, and Roms have more information to fill
+ if (datItem is Disk diskItem && savedItem is Disk savedDisk)
+ savedDisk.FillMissingInformation(diskItem);
+ else if (datItem is Formats.File fileItem && savedItem is Formats.File savedFile)
+ savedFile.FillMissingInformation(fileItem);
+ else if (datItem is Media mediaItem && savedItem is Media savedMedia)
+ savedMedia.FillMissingInformation(mediaItem);
+ else if (datItem is Rom romItem && savedItem is Rom savedRom)
+ savedRom.FillMissingInformation(romItem);
+
+ // Set the duplicate type on the saved item
+ savedItem.SetFieldValue(DatItem.DupeTypeKey, dupetype);
+
+ // Get the sources associated with the items
+ var savedSource = savedItem.GetFieldValue(DatItem.SourceKey);
+ var itemSource = datItem.GetFieldValue(DatItem.SourceKey);
+
+ // Get the machines associated with the items
+ var savedMachine = savedItem.GetFieldValue(DatItem.MachineKey);
+ var itemMachine = datItem.GetFieldValue(DatItem.MachineKey);
+
+ // If the current system has a lower ID than the previous, set the system accordingly
+ if (itemSource?.Index < savedSource?.Index)
{
- outfiles.Add(item);
+ datItem.SetFieldValue(DatItem.SourceKey, savedSource.Clone() as Source);
+ savedItem.CopyMachineInformation(datItem);
+ savedItem.SetName(datItem.GetName());
}
- // Otherwise, if a new rom information is found, add that
- else
+
+ // If the current machine is a child of the new machine, use the new machine instead
+ if (savedMachine?.GetStringFieldValue(Models.Metadata.Machine.CloneOfKey) == itemMachine?.GetStringFieldValue(Models.Metadata.Machine.NameKey)
+ || savedMachine?.GetStringFieldValue(Models.Metadata.Machine.RomOfKey) == itemMachine?.GetStringFieldValue(Models.Metadata.Machine.NameKey))
{
- outfiles.RemoveAt(pos);
- outfiles.Insert(pos, savedItem);
+ savedItem.CopyMachineInformation(datItem);
+ savedItem.SetName(datItem.GetName());
}
+
+ // Replace the original item in the list
+ output.RemoveAt(pos);
+ output.Insert(pos, savedItem);
}
// Then return the result
- return outfiles;
+ return output;
}
///
diff --git a/SabreTools.DatItems/Formats/Disk.cs b/SabreTools.DatItems/Formats/Disk.cs
index 826cdba5..c1eb5804 100644
--- a/SabreTools.DatItems/Formats/Disk.cs
+++ b/SabreTools.DatItems/Formats/Disk.cs
@@ -99,11 +99,7 @@ namespace SabreTools.DatItems.Formats
///
/// Disk to fill information from
public void FillMissingInformation(Disk other)
- {
- _internal.FillMissingHashes(other._internal);
- ConditionalUpdateSource(other);
- ConditionalUpdateMachine(other);
- }
+ => _internal.FillMissingHashes(other._internal);
///
/// Get unique duplicate suffix on name collision
diff --git a/SabreTools.DatItems/Formats/File.cs b/SabreTools.DatItems/Formats/File.cs
index 01a5fcc6..b288a56f 100644
--- a/SabreTools.DatItems/Formats/File.cs
+++ b/SabreTools.DatItems/Formats/File.cs
@@ -207,9 +207,6 @@ namespace SabreTools.DatItems.Formats
if (_sha256.IsNullOrEmpty() && !other._sha256.IsNullOrEmpty())
_sha256 = other._sha256;
-
- ConditionalUpdateSource(other);
- ConditionalUpdateMachine(other);
}
///
diff --git a/SabreTools.DatItems/Formats/Media.cs b/SabreTools.DatItems/Formats/Media.cs
index 35a8def1..809d4270 100644
--- a/SabreTools.DatItems/Formats/Media.cs
+++ b/SabreTools.DatItems/Formats/Media.cs
@@ -60,11 +60,7 @@ namespace SabreTools.DatItems.Formats
///
/// Media to fill information from
public void FillMissingInformation(Media other)
- {
- _internal.FillMissingHashes(other._internal);
- ConditionalUpdateSource(other);
- ConditionalUpdateMachine(other);
- }
+ => _internal.FillMissingHashes(other._internal);
///
/// Get unique duplicate suffix on name collision
diff --git a/SabreTools.DatItems/Formats/Rom.cs b/SabreTools.DatItems/Formats/Rom.cs
index 50b07c0e..35b9b0a9 100644
--- a/SabreTools.DatItems/Formats/Rom.cs
+++ b/SabreTools.DatItems/Formats/Rom.cs
@@ -103,11 +103,7 @@ namespace SabreTools.DatItems.Formats
///
/// Rom to fill information from
public void FillMissingInformation(Rom other)
- {
- _internal.FillMissingHashes(other._internal);
- ConditionalUpdateSource(other);
- ConditionalUpdateMachine(other);
- }
+ => _internal.FillMissingHashes(other._internal);
///
/// Get unique duplicate suffix on name collision