static void RemoveNode( ref Dictionary <string, Entry> changes, ref List <IPatch> localPatches, string key, IVTree vTree, int index ) { if (!changes.ContainsKey(key)) { var patch = PushPatch(ref localPatches, new Remove(index)); changes[key] = new Entry(Entry.Type.Remove, vTree, index); changes[key].data = patch; return; } var entry = changes[key]; if (entry.tag == Entry.Type.Insert) { entry.tag = Entry.Type.Remove; var subPatches = new List <IPatch>(); Helper(vTree, entry.vTree, ref subPatches, index); PushPatch(ref localPatches, new Remove(index, subPatches.ToArray(), entry)); return; } RemoveNode(ref changes, ref localPatches, key + "UniVDOM", vTree, index); }
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 Helper(IVTree x, IVTree y, ref List <IPatch> patches, int index) { // TODO: Implement `Equals` method on each node // if (x.Equals(y)) // { // return; // } if (x.GetNodeType() != y.GetNodeType()) { if (x is BaseNode && y is BaseKeyedNode) { switch (y) { case KeyedNode <Component> typedNode: y = Dekey(typedNode); break; case KeyedNode keyedNode: y = Dekey(keyedNode); break; } } else { PushPatch(ref patches, new Redraw(index, y)); return; } } switch (y) { case BaseNode yNode: if (x is BaseNode xNode) { DiffNodes(xNode, yNode, ref patches, index); } return; case BaseKeyedNode yKeyedVNode: if (x is BaseKeyedNode xKeyedNode) { DiffKeyedNodes(xKeyedNode, yKeyedVNode, ref patches, index); } return; case Widget yWidget: if (x is Widget xWidget) { DiffWidget(xWidget, yWidget, ref patches, index); } return; default: throw new Exception("Invalid VTree type"); } }
public static IPatch[] Calc(IVTree x, IVTree y) { var patches = new List <IPatch>(); Helper(x, y, ref patches, 0); return(patches.ToArray()); }
private static void AttachComponent(UnityEngine.GameObject go, IVTree tree, bool isUGUI) { if (!(tree is ITypedNode node)) { return; } go.AddComponent(node.GetComponentType()); }
static IPatch CheckComponentType(IVTree x, IVTree y, int index) { if (x is ITypedNode xNode && y is ITypedNode yNode && xNode.GetComponentType() != yNode.GetComponentType()) { return(new Attach(index, xNode.GetComponentType(), yNode.GetComponentType())); } return(null); }
public VeautyObject(UnityEngine.GameObject rootObj, System.Func <IVTree> renderFunc, bool isUGUI = false) { this.mounter = rootObj; this.renderFunc = renderFunc; this.oldTree = renderFunc(); this.isUGUI = isUGUI; Render(); }
private static void ApplyAttrs(UnityEngine.GameObject go, IVTree tree) { if (!(tree is NodeBase node)) { return; } foreach (var attr in node.attrs.attrs) { attr.Value.Apply(go); } }
private static void RenderKids(UnityEngine.GameObject go, IVTree tree, bool isUGUI) { if (!(tree is IParent parent)) { return; } foreach (var kid in parent.GetKids()) { AppendChild(go, Render(kid, isUGUI)); } }
static void InsertNode( ref Dictionary <string, Entry> changes, ref List <IPatch> localPatches, string key, IVTree vTree, int yIndex, ref List <Reorder.Insert> inserts ) { if (!changes.ContainsKey(key)) { var newEntry = new Entry(Entry.Type.Insert, vTree, yIndex); inserts.Add(new Reorder.Insert { index = yIndex, entry = newEntry }); changes[key] = newEntry; return; } var entry = changes[key]; if (entry.tag == Entry.Type.Remove) { inserts.Add(new Reorder.Insert { index = yIndex, entry = entry }); entry.tag = Entry.Type.Move; var subPatches = new List <IPatch>(); Helper(entry.vTree, vTree, ref subPatches, entry.index); entry.index = yIndex; entry.data = new { patches = subPatches, entry = entry }; return; } InsertNode(ref changes, ref localPatches, key + "UniVDOM", vTree, yIndex, ref inserts); }
public static UnityEngine.GameObject Render(IVTree vTree, bool isUGUI) { UnityEngine.GameObject go = null; switch (vTree) { case NodeBase vNode: go = CreateGameObject(vNode.tag, isUGUI); AttachComponent(go, vNode, isUGUI); ApplyAttrs(go, vNode); RenderKids(go, vNode, isUGUI); return(go); case Widget widget: return(RenderWidget(widget, isUGUI)); default: throw new Exception("Invalid node type"); } }
public Redraw(int index, IVTree vTree) { this.index = index; this.vTree = vTree; this.gameObject = null; }
public static UnityEngine.GameObject Apply(UnityEngine.GameObject rootGameObject, IVTree oldVTree, IPatch[] patches, bool isUGUI) { if (patches.Length == 0) { return(rootGameObject); } AddGameObjectNodes(rootGameObject, oldVTree, ref patches); return(Helper(rootGameObject, patches, isUGUI)); }