// Computes the Diffing for BHoMObjects that all have a HashFragment assigned (like when they have been passed through a Revision). private static Diff DiffRevisionObjects(IEnumerable <IBHoMObject> pastObjects, IEnumerable <IBHoMObject> currentObjects, DiffingConfig diffingConfig = null) { // Set configurations if DiffingConfig is null. Clone it for immutability in the UI. DiffingConfig dc = diffingConfig == null ? new DiffingConfig() : diffingConfig.DeepClone() as DiffingConfig; // Take the Revision's objects List <IBHoMObject> currentObjs = currentObjects.ToList(); List <IBHoMObject> readObjs = pastObjects.ToList(); // Make dictionary with object hashes to speed up the next lookups Dictionary <string, IBHoMObject> readObjs_dict = readObjs.ToDictionary(obj => obj.RevisionFragment().Hash, obj => obj); // Dispatch the objects: new, modified or old List <IBHoMObject> newObjs = new List <IBHoMObject>(); List <IBHoMObject> modifiedObjs = new List <IBHoMObject>(); List <IBHoMObject> oldObjs = new List <IBHoMObject>(); List <IBHoMObject> unChanged = new List <IBHoMObject>(); var objModifiedProps = new Dictionary <string, Dictionary <string, Tuple <object, object> > >(); foreach (IBHoMObject bhomObj in currentObjs) { RevisionFragment revisionFragm = bhomObj.RevisionFragment(); if (revisionFragm?.PreviousHash == null) { newObjs.Add(bhomObj); // It's a new object } else if (revisionFragm.PreviousHash == revisionFragm.Hash) { // It's NOT been modified if (dc.IncludeUnchangedObjects) { unChanged.Add(bhomObj); } } else if (revisionFragm.PreviousHash != revisionFragm.Hash) { modifiedObjs.Add(bhomObj); // It's been modified if (dc.EnablePropertyDiffing) { // Determine changed properties IBHoMObject oldBhomObj = null; readObjs_dict.TryGetValue(revisionFragm.PreviousHash, out oldBhomObj); if (oldBhomObj == null) { continue; } // To compute differentProps in a Revision-Diffing, make sure we remove the RevisionFragment. We don't want to consider that. var differentProps = Query.DifferentProperties(bhomObj.RemoveFragment(typeof(RevisionFragment)), oldBhomObj.RemoveFragment(typeof(RevisionFragment)), dc); if (differentProps != null) { objModifiedProps.Add(revisionFragm.Hash, differentProps); } } } else { throw new Exception("Could not find hash information to perform Diffing on some objects."); } } // If no modified property was found, set the field to null (otherwise will get empty list) objModifiedProps = objModifiedProps.Count == 0 ? null : objModifiedProps; // All ReadObjs that cannot be found by hash in the previousHash of the CurrentObjs are toBeDeleted Dictionary <string, IBHoMObject> CurrentObjs_withPreviousHash_dict = currentObjs .Where(obj => obj.RevisionFragment().PreviousHash != null) .ToDictionary(obj => obj.RevisionFragment().PreviousHash, obj => obj); oldObjs = readObjs_dict.Keys.Except(CurrentObjs_withPreviousHash_dict.Keys) .Where(k => readObjs_dict.ContainsKey(k)).Select(k => readObjs_dict[k]).ToList(); return(new Diff(newObjs, oldObjs, modifiedObjs, diffingConfig, objModifiedProps, unChanged)); }