public static Diff IDiffing(IEnumerable <object> pastObjs, IEnumerable <object> followingObjs, DiffingType diffingType = DiffingType.Automatic, DiffingConfig diffConfig = null) { if (!pastObjs.Any() || !followingObjs.Any()) { BH.Engine.Reflection.Compute.RecordWarning("No input objects provided."); return(null); } // Set configurations if diffConfig is null. Clone it for immutability in the UI. DiffingConfig dc = diffConfig == null ? new DiffingConfig() : diffConfig.DeepClone(); // If requested, compute the Diffing comparing each object one by one, in the same order. if (diffingType == DiffingType.OneByOne) { // If objects do not have any persistentId, `AllowOneByOneDiffing` is enabled and the collections have the same length, // compare objects from the two collections one by one. BH.Engine.Reflection.Compute.RecordNote($"Calling the diffing method '{nameof(DiffOneByOne)}'" + $"\nThis will only identify 'modified' or 'unchanged' objects. It will work correctly only if the input objects are in the same order."); return(DiffOneByOne(pastObjs, followingObjs, dc)); } // Check if the inputs specified are Revisions. In that case, use the Diffing-Revision workflow. if (diffingType == DiffingType.Automatic || diffingType == DiffingType.Revision) { if (pastObjs.Count() == 1 && followingObjs.Count() == 1) { Revision pastRev = pastObjs.First() as Revision; Revision follRev = followingObjs.First() as Revision; if (pastRev != null && follRev != null) { BH.Engine.Reflection.Compute.RecordNote($"Calling the diffing method '{nameof(DiffRevisions)}'."); if (!string.IsNullOrWhiteSpace(dc.CustomDataKey)) { BH.Engine.Reflection.Compute.RecordWarning($"The `{nameof(DiffingConfig)}.{nameof(dc.CustomDataKey)}` is not considered when the input objects are both of type {nameof(Revision)}."); } return(DiffRevisions(pastRev, follRev, dc)); } } if (diffingType == DiffingType.Revision) { return(DiffingError(diffingType)); } } IEnumerable <IBHoMObject> bHoMObjects_past = pastObjs.OfType <IBHoMObject>(); IEnumerable <IBHoMObject> bHoMObjects_following = followingObjs.OfType <IBHoMObject>(); // Check if the BHoMObjects all have a RevisionFragment assigned. // If so, we may attempt the Revision diffing. if (bHoMObjects_past.AllHaveRevisionFragment() && bHoMObjects_following.AllHaveRevisionFragment()) { BH.Engine.Reflection.Compute.RecordNote($"Calling the diffing method '{nameof(DiffRevisionObjects)}'."); return(DiffRevisionObjects(bHoMObjects_past, bHoMObjects_following, dc)); } // If a customDataKey was specified, use the Id found under that key in customdata to perform the Diffing. if (diffingType == DiffingType.Automatic || diffingType == DiffingType.CustomDataId) { if (diffingType == DiffingType.CustomDataId && !string.IsNullOrWhiteSpace(dc.CustomDataKey)) { return(DiffingError(diffingType)); } if (!string.IsNullOrWhiteSpace(dc.CustomDataKey) && bHoMObjects_past.Count() == pastObjs.Count() && bHoMObjects_following.Count() == followingObjs.Count()) { BH.Engine.Reflection.Compute.RecordNote($"Calling the diffing method '{nameof(DiffWithCustomId)}'."); return(DiffWithCustomId(bHoMObjects_past, bHoMObjects_following, dc.CustomDataKey, dc)); } else { BH.Engine.Reflection.Compute.RecordWarning($"To perform the diffing based on an Id stored in the Custom Data, the inputs must be collections of IBHoMObjects."); } } // Check if the bhomObjects have a persistentId assigned. List <object> reminder_past; List <object> reminder_following; List <IBHoMObject> bHoMObjects_past_persistId = bHoMObjects_past.WithNonNullPersistentAdapterId(out reminder_past); List <IBHoMObject> bHoMObjects_following_persistId = bHoMObjects_following.WithNonNullPersistentAdapterId(out reminder_following); Diff fragmentDiff = null; // For the BHoMObjects we can compute the Diff with the persistentId. if (diffingType == DiffingType.Automatic || diffingType == DiffingType.PersistentId) { if (bHoMObjects_past_persistId.Count != 0 && bHoMObjects_following_persistId.Count != 0) { BH.Engine.Reflection.Compute.RecordNote($"Calling the diffing method '{nameof(DiffWithFragmentId)}'."); } fragmentDiff = DiffWithFragmentId(bHoMObjects_past_persistId, bHoMObjects_following_persistId, typeof(IPersistentAdapterId), nameof(IPersistentAdapterId.PersistentId), dc); } // For the remaining objects (= all objects that are not BHoMObjects, and all BHoMObjects not having a PersistentId) we can Diff using the Hash. BH.Engine.Reflection.Compute.RecordNote($"Calling the most generic Diffing method, '{nameof(DiffWithHash)}'."); Diff diffGeneric = DiffWithHash(pastObjs as dynamic, followingObjs as dynamic, dc); if (fragmentDiff == null) { return(diffGeneric); } return(fragmentDiff.CombineDiffs(diffGeneric)); }
private static Diff DiffingError(DiffingType diffingType) { BH.Engine.Reflection.Compute.RecordError($"Invalid inputs for the selected DiffingType `{diffingType}`."); return(null); }