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)); } }
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); }
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()) ); } }