예제 #1
0
        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));
        }
예제 #2
0
 private static Diff DiffingError(DiffingType diffingType)
 {
     BH.Engine.Reflection.Compute.RecordError($"Invalid inputs for the selected DiffingType `{diffingType}`.");
     return(null);
 }