Exemple #1
0
        static BaseNode Dekey(BaseKeyedNode keyedNode)
        {
            var kids = new IVTree[keyedNode.kids.Length];

            for (var i = 0; i < kids.Length; i++)
            {
                kids[i] = keyedNode.GetKids()[i];
            }

            var attrs = new List <IAttribute>();

            foreach (var kv in keyedNode.attrs.attrs)
            {
                attrs.Add(kv.Value);
            }

            if (keyedNode is ITypedNode typedNode)
            {
                var genericNodeType = typeof(Node <>).MakeGenericType(typedNode.GetComponentType());
                return((BaseNode)System.Activator.CreateInstance(genericNodeType, new object[] { keyedNode.tag, attrs.ToArray(), kids }));
            }
            else
            {
                return(new Node(keyedNode.tag, attrs.ToArray(), kids));
            }
        }
Exemple #2
0
        static void DiffKeyedNodes(
            BaseKeyedNode x,
            BaseKeyedNode y,
            ref List <IPatch> patches,
            int index
            )
        {
            if (x.tag != y.tag)
            {
                PushPatch(ref patches, new Redraw(index, y));
                return;
            }

            CheckAttributes(x.attrs, y.attrs, ref patches, index);

            DiffKeyedKids(x, y, ref patches, index);
        }
Exemple #3
0
        static void DiffKeyedKids(BaseKeyedNode xParent, BaseKeyedNode yParent, ref List <IPatch> patches, int rootIndex)
        {
            var localPatches = new List <IPatch>();

            var changes = new Dictionary <string, Entry>();
            var inserts = new List <Reorder.Insert>();

            var xKids = xParent.kids;
            var yKids = yParent.kids;
            var xLen  = xKids.Length;
            var yLen  = yKids.Length;

            var xIndex = 0;
            var yIndex = 0;

            var index = rootIndex;

            while (xIndex < xLen && yIndex < yLen)
            {
                var(xKey, xNode) = xKids[xIndex];
                var(yKey, yNode) = yKids[yIndex];

                var newMatch = false;
                var oldMatch = false;

                if (xKey == yKey)
                {
                    index++;
                    Helper(xNode, yNode, ref localPatches, index);
                    index += xNode.GetDescendantsCount();

                    xIndex++;
                    yIndex++;
                    continue;
                }

                var(xNextKey, xNextNode) = xIndex + 1 < xKids.Length ? xKids[xIndex + 1] : ("", null);
                var(yNextKey, yNextNode) = yIndex + 1 < yKids.Length ? yKids[yIndex + 1] : ("", null);

                oldMatch = yKey == xNextKey;
                newMatch = xKey == yNextKey;

                if (newMatch && oldMatch)
                {
                    index++;
                    Helper(xNode, yNextNode, ref localPatches, index);
                    InsertNode(ref changes, ref localPatches, xKey, yNode, yIndex, ref inserts);
                    index += xNode.GetDescendantsCount();

                    index++;
                    RemoveNode(ref changes, ref localPatches, xKey, xNextNode, index);
                    index += xNextNode.GetDescendantsCount();

                    xIndex += 2;
                    yIndex += 2;
                    continue;
                }

                if (newMatch)
                {
                    index++;
                    InsertNode(ref changes, ref localPatches, yKey, yNode, yIndex, ref inserts);
                    Helper(xNode, yNextNode, ref localPatches, index);
                    index += xNode.GetDescendantsCount();

                    xIndex += 1;
                    yIndex += 2;
                    continue;
                }

                if (oldMatch)
                {
                    index++;
                    RemoveNode(ref changes, ref localPatches, xKey, xNode, index);
                    index += xNode.GetDescendantsCount();

                    index++;
                    Helper(xNextNode, yNode, ref localPatches, index);
                    index += xNextNode.GetDescendantsCount();

                    xIndex += 2;
                    yIndex += 1;
                    continue;
                }

                if (xNextKey != "" && xNextNode != null && xNextKey == yNextKey)
                {
                    index++;
                    RemoveNode(ref changes, ref localPatches, xKey, xNode, index);
                    InsertNode(ref changes, ref localPatches, yKey, yNode, yIndex, ref inserts);
                    index += xNode.GetDescendantsCount();

                    index++;
                    Helper(xNextNode, yNextNode, ref localPatches, index);
                    index += xNextNode.GetDescendantsCount();

                    xIndex += 2;
                    yIndex += 2;
                    continue;
                }

                break;
            }

            while (xIndex < xLen)
            {
                index++;
                var(xKey, xNode) = xKids[xIndex];
                RemoveNode(ref changes, ref localPatches, xKey, xNode, index);
                index += xNode.GetDescendantsCount();
                xIndex++;
            }

            var endInserts = new List <Reorder.Insert>();

            while (yIndex < yLen)
            {
                var(yKey, yNode) = yKids[yIndex];
                InsertNode(ref changes, ref localPatches, yKey, yNode, -1, ref endInserts);
                yIndex++;
            }

            if (localPatches.Count > 0 || inserts.Count > 0 || endInserts.Count > 0)
            {
                PushPatch(
                    ref patches,
                    new Reorder(rootIndex, localPatches.ToArray(), inserts.ToArray(), endInserts.ToArray())
                    );
            }
        }