TreeGraphNode DeserializeNode(TreeNodeData data) { NodeInfo info = serializedNameToInfo.TryGetValue(data.nodeTypeSerializableName) ?? throw new Exception($"Unexpected serialized name {data.nodeTypeSerializableName}"); TreeGraphNode node = graphView.CreateNewNode(info, data.position, data.parameters); node.GUID = data.GUID; //Children TreeGraphNode child = null; for (int i = 0; i < data.children.Length; i++) { child = DeserializeNode(allData[data.children[i]]); graphView.AddElement(child.ParentPort.ConnectTo(node.ChildrenPort)); } child?.RecalculateOrder(); //This will calculate the order of its siblings too return(node); }
int SerializeNode(TreeGraphNode node) { var data = new TreeNodeData { position = node.GetPosition().position, //Position nodeTypeSerializableName = node.Info.serializedName, //Node type name parameters = node.Parameters //Parameters }; //Children if (node.ChildrenPort == null || !node.ChildrenPort.connected) { data.children = Array.Empty <int>(); } else { var childIndices = new List <int>(); foreach (Edge connection in node.ChildrenPort.connections) { if (!(connection.input.node is TreeGraphNode child)) { continue; } while (child.Order >= childIndices.Count) { childIndices.Add(-1); } childIndices[child.Order] = SerializeNode(child); } data.children = childIndices.ToArray(); } //Finalize data.GUID = allData.Count; allData.Add(data); return(data.GUID); }
/// <summary> /// Recalculate this node's order in parent. /// If <paramref name="propagateToSiblings"/> is true, then the order of all its siblings will be recalculated too /// </summary> public void RecalculateOrder(bool propagateToSiblings = true) { Port parentInputPort = ParentPort?.connections?.FirstOrDefault()?.output; if (parentInputPort == null || parentInputPort.capacity == Port.Capacity.Single) { SetEmpty(); } else { TreeGraphNode parentNode = (TreeGraphNode)parentInputPort.node; if (GraphView.IsRemovingElement(this)) { if (propagateToSiblings) { //Loop through all parent's children connections foreach (Edge edge in parentNode.ChildrenPort.connections) { if (edge.input.node is TreeGraphNode node && node != this) { node.RecalculateOrder(false); //Important false to avoid infinite recursion } } } SetEmpty(); return; } int order = 0; float y = GetPositionImmediate().y; //Loop through all parent's children connections foreach (Edge edge in parentNode.ChildrenPort.connections) { if (!(edge.input.node is TreeGraphNode node) || node == this) { continue; } if (node.GetPositionImmediate().y < y && !GraphView.IsRemovingElement(node)) { order++; } if (propagateToSiblings) { node.RecalculateOrder(false); //NOTE: This false is really important to avoid infinite recursions! } } orderLabel.text = order.ToString(); //This looks better than "Order 1", however if it gets too difficult to understand we can change it back Order = order; } void SetEmpty() { if (orderLabel != null) { orderLabel.text = ""; } Order = 0; } }