Esempio n. 1
0
        // 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));
        }