How deep is a deep copy? #208
Replies: 1 comment 6 replies
-
Definitions as I see them: Shallow CopyA shallow copied npc would be a new C# object, but all references within it would point to the same objects as the original. So you would get this behavior: var npc = new Npc();
npc.Name = "MyName";
var npcShallowCopy = npc.ShallowCopy();
npc.Items.Add(new ContainerEntry());
// This will print 1, because both npcs point to the same list for their Items member
Console.WriteLine($"Shallow npc has {npcShallowCopy.Items.Count} items and is named {npcShallowCopy.Name}.");
// prints Shallow npc has 1 items and is named MyName This concept does not exist in Mutagen DeepCopyA deep copy is exactly the same above, except each subobject also gets cloned to a new object, but with the same overall contents. Equals would return true, and when exported the bytes would be identical. But this would be out of coincidence. They're identical twins, not siamese twins. var npc = new Npc();
npc.Name = "MyName";
var npcShallowCopy = npc.DeepCopy();
npc.Items.Add(new ContainerEntry());
Console.WriteLine($"Shallow npc has {npcShallowCopy.Items.Count} items and is named {npcShallowCopy.Name}.");
// prints Shallow npc has 0 items and is named MyName The name was copied from FormLinksFormLinks get their value copied over. So if the original record pointed to something DeepCopyInDeepCopyIn is the same, except the object being filled is given to it, rather than created internally. So actually, a DeepCopy could be seen as using DeepCopyIn:
DeepCopyIn would actually be doing the heavy lifting of cloning the content DuplicateThis is actually what I'd say is the equivalent of xEdit's "copy as new". It does a DeepCopy, but assigns a new FormKey. DuplicateFromOnlyReferencedA variant of this is probably what you're after. It's half done, experimental, and horridly named. This code will inspect a target mod, and duplicate all contained records of a given type (copy + give it a new FormKey), as well as duplicating all records they point to, recursively. It will then also reroute the FormLinks in all the records to each other's dups (via the RemapLinks call). https://github.com/Mutagen-Modding/Mutagen/blob/release/Mutagen.Bethesda.Core/Extensions/DuplicateFromMixIn.cs Work to be DoneI imagine I might rename |
Beta Was this translation helpful? Give feedback.
-
I've been trying this out and seeing results that look more like a shallow copy to me. I read the wiki page on copying but it's a tad ambiguous to me, and also had a somewhat hard time following the code.
My interpretation of "deep" is that it also clones dependencies, so e.g. if I
DeepCopyIn
an NPC including head parts, it will copy theHDPT
records as well. But I think perhaps what "deep copy" really means is that it copies the entire binary blob and will therefore preserve things like arrays containing structs containing arrays, if such a thing exists. But it looks like references are still copied as references, and new masters are added as required. This isn't much different from what XEdit's "copy as new" does, I just had different expectations based on the name.Is this the intended behavior, or am I somehow using it wrong? Ultimately the behavior I want is something like "recursively copy the targets of any form links, unless those targets are already present in the destination plugin's masters, or there's already a copy sitting in the destination plugin". From what I gather, I will have to do this explicitly, and not be able to rely on
DeepCopy
semantics?Beta Was this translation helpful? Give feedback.
All reactions