Ejemplo n.º 1
0
        private static void ProcessAttributesNodeDifferences(SerializedNode fromTree, SerializedNode toTree,
                                                             NodeDiff applyDiff)
        {
            var fromInterpreters = fromTree.Interpreters;
            var toInterpreters   = toTree.Interpreters;

            foreach (var attributeName in fromInterpreters.Keys)
            {
                if (false == toInterpreters.ContainsKey(attributeName))
                {
                    applyDiff.RemovedAttributes.Add(attributeName);
                }
                else
                {
                    var fromData = GetSerializedAttribute(fromTree, attributeName);
                    var toData   = GetSerializedAttribute(toTree, attributeName);

                    if (false == fromData.IsSame(toData))
                    {
                        applyDiff.ModifiedAttributeData[attributeName] = toData;
                    }
                }
            }
            foreach (var attributeName in toInterpreters.Keys)
            {
                if (false == fromTree.Interpreters.ContainsKey(attributeName))
                {
                    applyDiff.ModifiedAttributeData[attributeName] = GetSerializedAttribute(toTree, attributeName);
                }
            }
        }
Ejemplo n.º 2
0
 private static void ReflectTreeAttributesToDiff(SerializedNode node, NodeDiff diff)
 {
     foreach (var attribute in node.Interpreters.Keys)
     {
         diff.ModifiedAttributeData[attribute] = GetSerializedAttribute(node, attribute);
     }
 }
Ejemplo n.º 3
0
        /// <summary>
        ///   Makes changes permanently and let them to be affected by Undo/Redo commands
        /// </summary>
        /// <param name = "reason">The reason of comit. It can be used to see cause of the commit.
        ///   empty string for reason is used in revert or commits with no important reason to get notify</param>
        /// <returns> Returns true in case that there are changes to the previous Transact call</returns>
        public bool Commit(string reason)
        {
            NotifyPreChanges();
            if (!_transactStarted)
            {
                _transactStarted = true;
                if (_treeMirror == null)
                {
                    _treeMirror = ReflectTreeMirror(Root);
                }
                Revert();
                return(false);
            }
            var redo = new NodeDiff(null);

            redo.ComputeMarkingDiff(_treeMirror, Root);
            var undo = NodeDiff.ApplyDiffToSerializedNode(_treeMirror, redo);

            if (!undo.Empty)
            {
                _historyPos++;
                RemoveInvalidUndoRedoItems();
                AddUndoRedoDiffs(reason, undo);
            }
            else
            {
                return(false);
            }

            _transactStarted = false;
            //empty string for reason is used in revert or commits with no important reason to get notify
            NotifyChanges(reason);
            return(true);
        }
Ejemplo n.º 4
0
        /// <summary>
        ///   Goes back to previous Transact call
        /// </summary>
        public void Undo()
        {
            if (_historyPos < 0)
            {
                return;
            }
            try
            {
                var undoDiff = GetHistoryItem(_historyPos);
                NodeDiff.ApplyDiff(Root, undoDiff);

                var redo = NodeDiff.ApplyDiffToSerializedNode(_treeMirror, undoDiff);
                SetHistoryItem(_historyPos, redo);
                _historyPos--;
                NotifyChanges("Undo");
            }
            catch (Exception e)
            {
                Log.Info("Exception on Undo:" + e.Message + Environment.NewLine + e.StackTrace);
                _historyList.Clear();
                _historyPos      = -1;
                _reasonList      = new List <string>();
                _transactStarted = false;
            }
        }
Ejemplo n.º 5
0
        private static void DeserializeTargetNode(NodeDiff diff, Node result, Node refNode)
        {
            var diffPath  = AttributeData.RelativeReferencePath(result, refNode);
            var destDiff  = diff;
            var pathItems = diffPath.Split(':');
            var destNode  = result;

            foreach (var item in pathItems)
            {
                if (string.IsNullOrEmpty(item))
                {
                    destNode = destNode.Parent;
                    destDiff = destDiff.Parent;
                }
                else
                {
                    var index = Convert.ToInt32(item);
                    if (!destDiff.Children.ContainsKey(index))
                    {
                        return;
                    }
                    destNode = destNode.Children[index];
                    destDiff = destDiff.Children[index];
                }
            }
            ModifyNodeWithDiff(destDiff, destNode);
        }
Ejemplo n.º 6
0
 private void AddUndoRedoDiffs(string reason, NodeDiff undo)
 {
     _reasonList.Add(reason);
     foreach (var removedNodeId in undo.RemovedNodes)
     {
         undo.Children.Remove(removedNodeId);
     }
     _historyList.Add(undo);
 }
Ejemplo n.º 7
0
        /// <summary>
        ///   Apply a specific diff to a tree
        /// </summary>
        /// <param name = "treeNode"></param>
        /// <param name = "diff">The diff data that needs to be applied</param>
        /// <returns>Undo diff tree</returns>
        public static NodeDiff ApplyDiffToSerializedNode(SerializedNode treeNode, NodeDiff diff)
        {
            var returnValue = new NodeDiff(null);

            foreach (var modifiedNode in diff.Children.Keys)
            {
                if (treeNode.Children.ContainsKey(modifiedNode))
                {
                    continue;
                }
                treeNode.Children[modifiedNode] = new SerializedNode(modifiedNode);
                returnValue.RemovedNodes.Add(modifiedNode);
            }

            foreach (var removedNode in diff.RemovedNodes)
            {
                returnValue.Children[removedNode] = ReflectTreeAsDiff(treeNode.Children[removedNode]);
                treeNode.Children.Remove(removedNode);
            }

            foreach (var modifiedNode in diff.Children.Keys)
            {
                var childDiff = diff.Children[modifiedNode];
                if (!treeNode.Children.ContainsKey(modifiedNode))
                {
                    continue;
                }
                var childNode = treeNode.Children[modifiedNode];

                var undoDiffChildNode = ApplyDiffToSerializedNode(childNode, childDiff);
                if (undoDiffChildNode.Empty == false)
                {
                    returnValue.Children[modifiedNode] = undoDiffChildNode;
                }
            }

            foreach (var modifiedAttr in diff.ModifiedAttributeData)
            {
                if (!treeNode.Interpreters.ContainsKey(modifiedAttr.Key))
                {
                    returnValue.RemovedAttributes.Add(modifiedAttr.Key);
                }
                else
                {
                    returnValue.ModifiedAttributeData[modifiedAttr.Key] = treeNode.Interpreters[modifiedAttr.Key];
                }
                treeNode.Interpreters[modifiedAttr.Key] = modifiedAttr.Value;
            }

            foreach (var removedAttr in diff.RemovedAttributes)
            {
                returnValue.ModifiedAttributeData[removedAttr] = treeNode.Interpreters[removedAttr];
                treeNode.Interpreters.Remove(removedAttr);
            }
            return(returnValue);
        }
Ejemplo n.º 8
0
        private static NodeDiff ReflectTreeAsDiff(SerializedNode node)
        {
            var result = new NodeDiff(null);

            ReflectTreeAttributesToDiff(node, result);
            foreach (var child in node.Children.Values)
            {
                result.Children[child.Index]        = ReflectTreeAsDiff(child);
                result.Children[child.Index].Parent = result;
            }

            return(result);
        }
 private void SetByDiff(NodeDiff value)
 {
     Clear();
     foreach (var child in value.Children)
     {
         Children[child.Key] = new SerializedNode(child.Key)
         {
             Diff = child.Value
         };
     }
     foreach (var interpreter in value.ModifiedAttributeData)
     {
         Interpreters[interpreter.Key] = interpreter.Value;
     }
 }
        private NodeDiff CreateDiff()
        {
            var result = new NodeDiff(null);

            foreach (var child in Children)
            {
                var childDiff = child.Value.Diff;
                result.Children[child.Key] = childDiff;
            }
            foreach (var interpreter in Interpreters)
            {
                result.ModifiedAttributeData[interpreter.Key] = interpreter.Value;
            }
            return(result);
        }
Ejemplo n.º 11
0
        /// <summary>
        ///   Save a file from a specific location as XML content
        /// </summary>
        /// <param name = "fileName">Filename location</param>
        public bool LoadFromXml(string fileName)
        {
            try
            {
                var oldTree = _treeMirror;
                _treeMirror = XmlHelper.LoadFromXml(fileName);
                if (_treeMirror == null)
                {
                    _treeMirror = oldTree;
                    NaroMessage.Show("Invalid NaroXML file. NaroCAD cannot open this file");
                    return(false);
                }
                Transact();
                var undo = new NodeDiff(null);
                var redo = new NodeDiff(null);
                var currentTreeMirror = ReflectTreeMirror(Root);

                NodeDiff.ComputeDiff(currentTreeMirror, _treeMirror, undo, redo);
                try
                {
                    NodeDiff.ApplyDiff(Root, redo);
                }
                catch (Exception ex)
                {
                    Log.Info(string.Format("Exception loading file: {0} with message: {1} with stack: {2}", fileName,
                                           ex.Message, ex.StackTrace));
                    NaroMessage.Show(string.Format("Cannot load file {0}", fileName));

                    var brokenTreeMirror = ReflectTreeMirror(Root);
                    NodeDiff.ComputeDiff(brokenTreeMirror, currentTreeMirror, undo, redo);
                    NodeDiff.ApplyDiff(Root, undo);
                }

                Commit("Loaded file: " + fileName);
                return(true);
            }
            catch (Exception e)
            {
                Revert();
                Log.Info("Error on loading xml: " + e.Message + Environment.NewLine + "Stack: " + e.StackTrace);
                return(false);
            }
        }
Ejemplo n.º 12
0
        /// <summary>
        ///   Goes to next Transact call in a history list
        /// </summary>
        public void Redo()
        {
            if (_historyPos < -1 || _historyPos >= _historyList.Count - 1)
            {
                return;
            }
            var redoDiff = GetHistoryItem(_historyPos + 1);

            NodeDiff.ApplyDiff(Root, redoDiff);

            var redo = new NodeDiff(null);

            redo.ComputeMarkingDiff(_treeMirror, Root);

            var undo = NodeDiff.ApplyDiffToSerializedNode(_treeMirror, redoDiff);

            SetHistoryItem(_historyPos + 1, undo);
            _historyPos++;
            NotifyChanges("Redo");
        }
Ejemplo n.º 13
0
 private static void ComputeDiffChild(SerializedNode fromTree, SerializedNode toTree, NodeDiff diff)
 {
     ProcessNodeDifferences(fromTree, toTree, diff);
     //compute the difference between attributes
     ProcessAttributesNodeDifferences(toTree, fromTree, diff);
     foreach (var toNode in fromTree.Children.Values)
     {
         if (!toTree.Children.ContainsKey(toNode.Index))
         {
             continue;
         }
         var subUndoDiff = new NodeDiff(diff);
         ComputeDiffChild(fromTree.Children[toNode.Index], toTree.Children[toNode.Index], subUndoDiff);
         if (!DiffContainsChanges(subUndoDiff))
         {
             continue;
         }
         diff.Children[toNode.Index]        = subUndoDiff;
         diff.Children[toNode.Index].Parent = diff;
     }
 }
Ejemplo n.º 14
0
        private static bool DiffContainsChanges(NodeDiff diff)
        {
            var nodeChanged = (diff.RemovedAttributes.Count != 0) || (diff.RemovedNodes.Count != 0) ||
                              (diff.ModifiedAttributeData.Count != 0);

            if (nodeChanged)
            {
                return(true);
            }

            foreach (var childDiff in diff.Children.Values)
            {
                var subDiffChanged = DiffContainsChanges(childDiff);
                if (subDiffChanged)
                {
                    return(true);
                }
            }

            return(false);
        }
 public void ApplyOnNode(Node node)
 {
     NodeDiff.ApplyDiff(node, Diff);
 }
Ejemplo n.º 16
0
 public NodeDiff(NodeDiff parent)
 {
     InitialSetup();
     Parent = parent;
 }
Ejemplo n.º 17
0
 private void SetHistoryItem(int position, NodeDiff nodeDiff)
 {
     _historyList[position] = nodeDiff;
     //nodeDiff.Pack();
 }
Ejemplo n.º 18
0
 private static void ProcessNodeDifferences(SerializedNode fromTree, SerializedNode toTree, NodeDiff diff)
 {
     foreach (var sourceChild in fromTree.Children)
     {
         if (toTree.Children.ContainsKey(sourceChild.Key))
         {
             continue;
         }
         diff.Children[sourceChild.Key]        = ReflectTreeAsDiff(sourceChild.Value);
         diff.Children[sourceChild.Key].Parent = diff;
     }
     foreach (var destChild in toTree.Children)
     {
         if (!fromTree.Children.ContainsKey(destChild.Key))
         {
             diff.RemovedNodes.Add(destChild.Key);
         }
     }
 }
Ejemplo n.º 19
0
 public static void ComputeDiff(SerializedNode fromTree, SerializedNode toTree, NodeDiff diff, NodeDiff redoDiff)
 {
     ComputeDiffChild(fromTree, toTree, diff);
     ComputeDiffChild(toTree, fromTree, redoDiff);
 }
Ejemplo n.º 20
0
        public void ComputeMarkingDiff(SerializedNode fromTree, Node toTree)
        {
            //compute the difference between attributes
            var fromInterpreters = fromTree.Interpreters;
            var toInterpreters   = toTree.Interpreters;

            foreach (var attributeNameId in fromInterpreters.Keys)
            {
                if (false == toInterpreters.ContainsKey(attributeNameId))
                {
                    RemovedAttributes.Add(attributeNameId);
                }
                else
                {
                    var fromData = GetSerializedAttribute(fromTree, attributeNameId);
                    var toData   = toTree.Interpreters[attributeNameId].Serialize();

                    if (false == fromData.IsSame(toData))
                    {
                        ModifiedAttributeData[attributeNameId] = toData;
                    }
                }
            }
            foreach (var attributeNameId in toInterpreters.Keys)
            {
                if (fromTree.Interpreters.ContainsKey(attributeNameId))
                {
                    continue;
                }
                var toData = toTree.Interpreters[attributeNameId].Serialize();
                ModifiedAttributeData[attributeNameId] = toData;
            }

            if (toTree.Markings == null)
            {
                return;
            }
            foreach (var childIndex in toTree.Markings.Keys)
            {
                if (!toTree.Children.ContainsKey(childIndex))
                {
                    if (fromTree.Children.ContainsKey(childIndex))
                    {
                        RemovedNodes.Add(childIndex);
                    }
                }
                else if (!fromTree.Children.ContainsKey(childIndex))
                {
                    if (toTree.Children.ContainsKey(childIndex))
                    {
                        Children[childIndex] = ReflectTreeAsDiff(Document.ReflectTreeMirror(toTree.Children[childIndex]));
                    }
                }
                else
                {
                    var childRedoDiff = new NodeDiff(this);

                    childRedoDiff.ComputeMarkingDiff(
                        fromTree.Children[childIndex],
                        toTree.Children[childIndex]);
                    if (!childRedoDiff.Empty)
                    {
                        Children[childIndex] = childRedoDiff;
                    }
                }
            }
            toTree.ClearMarkings();
        }
Ejemplo n.º 21
0
        private static void ModifyNodeWithDiff(NodeDiff diff, Node result)
        {
            if (diff.Applied)
            {
                return;
            }
            diff.Applied = true;

            foreach (var removedNode in diff.RemovedNodes)
            {
                if (diff.Children.ContainsKey(removedNode))
                {
                    diff.Children.Remove(removedNode);
                }
                result.Remove(removedNode);
            }

            foreach (var modifiedNode in diff.Children.Keys)
            {
                var childDiff = diff.Children[modifiedNode];
                if (!result.Children.ContainsKey(modifiedNode))
                {
                    result.AddChild(modifiedNode);
                }
                var childNode = result.Children[modifiedNode];

                ModifyNodeWithDiff(childDiff, childNode);
            }
            AttributeInterpreterBase functionInterpreter = null;
            AttributeData            attrData            = null;

            foreach (var modifiedAttr in diff.ModifiedAttributeData)
            {
                AttributeInterpreterBase interpreter;
                var key = AttributeInterpreterFactory.GetTypeId(modifiedAttr.Value.Name);
                if (!result.Interpreters.ContainsKey(key))
                {
                    interpreter = AttributeInterpreterFactory.GetInterpreter(key, result);
                    result.Interpreters[key] = interpreter;
                }
                else
                {
                    interpreter = result.Interpreters[modifiedAttr.Key];
                }
                try
                {
                    if (modifiedAttr.Value.Name == "Function")
                    {
                        functionInterpreter = interpreter;
                        attrData            = modifiedAttr.Value;
                        continue;
                    }
                    if (modifiedAttr.Key == typeof(ReferenceInterpreter).GetHashCode())
                    {
                        interpreter.Disable();
                        interpreter.Deserialize(modifiedAttr.Value);
                        var refNode = result.Get <ReferenceInterpreter>().Node;
                        DeserializeTargetNode(diff, result, refNode);
                        interpreter.Enable();
                    }

                    if (modifiedAttr.Key == typeof(ReferenceListInterpreter).GetHashCode())
                    {
                        interpreter.Disable();
                        interpreter.Deserialize(modifiedAttr.Value);
                        var refNodes = new List <SceneSelectedEntity>();
                        foreach (var refnode in result.Get <ReferenceListInterpreter>().Nodes)
                        {
                            refNodes.Add(refnode);
                        }

                        foreach (var refNode in refNodes)
                        {
                            DeserializeTargetNode(diff, result, refNode.Node);
                        }
                        interpreter.Enable();
                    }
                    interpreter.Deserialize(modifiedAttr.Value);
                }
                catch (Exception ex)
                {
                    var path            = AttributeData.RelativeReferencePath(result.Root, result);
                    var interpreterName = AttributeInterpreterFactory.GetName(modifiedAttr.Key);
                    Log.Info("Error on node: (" + path + ") interpreter: " + interpreterName
                             + Environment.NewLine + " Message: " + ex.Message
                             + Environment.NewLine + " Stack: " + ex.StackTrace);
                    //   throw;
                }
            }

            if (functionInterpreter != null)
            {
                functionInterpreter.Deserialize(attrData);
            }

            foreach (var removedAttr in diff.RemovedAttributes)
            {
                result.RemoveInterpreter(removedAttr);
            }
        }
Ejemplo n.º 22
0
 public static void ApplyDiff(Node fromTree, NodeDiff diff)
 {
     ModifyNodeWithDiff(diff, fromTree);
 }