public bool RecordConnection(PortData portData1, PortData portData2) { if (!portData1.connections.Contains(portData2)) { portData1.connections.Add(portData2); } if (!portData2.connections.Contains(portData1)) { portData2.connections.Add(portData1); } if (!connections.Exists((ConnectionData conData) => conData.isPart(portData1) && conData.isPart(portData2))) { // Connection hasn't already been recorded ConnectionData conData = new ConnectionData(portData1, portData2); connections.Add(conData); return(true); } return(false); }
/// <summary> /// Converts the simplified CanvasData back to a proper NodeCanvas /// </summary> internal static NodeCanvas ConvertToNodeCanvas(CanvasData canvasData) { if (canvasData == null) { return(null); } NodeCanvas nodeCanvas = NodeCanvas.CreateCanvas(canvasData.type); nodeCanvas.name = nodeCanvas.saveName = canvasData.name; nodeCanvas.nodes.Clear(); NodeEditor.BeginEditingCanvas(nodeCanvas); foreach (NodeData nodeData in canvasData.nodes.Values) { // Read all nodes Node node = Node.Create(nodeData.typeID, nodeData.nodePos, null, true, false); if (!string.IsNullOrEmpty(nodeData.name)) { node.name = nodeData.name; } if (node == null) { continue; } foreach (ConnectionPortDeclaration portDecl in ConnectionPortManager.GetPortDeclarationEnumerator(node)) { // Find stored ports for each node port declaration PortData portData = nodeData.connectionPorts.Find((PortData data) => data.name == portDecl.portField.Name); if (portData != null) // Stored port has been found, record { portData.port = (ConnectionPort)portDecl.portField.GetValue(node); } } foreach (PortData portData in nodeData.connectionPorts.Where(port => port.dynamic)) { // Find stored dynamic connection ports if (portData.port != null) // Stored port has been recreated { portData.port.body = node; node.dynamicConnectionPorts.Add(portData.port); } } foreach (VariableData varData in nodeData.variables) { // Restore stored variable to node FieldInfo field = node.GetType().GetField(varData.name); if (field != null) { field.SetValue(node, varData.refObject != null ? varData.refObject.data : varData.value); } } } foreach (ConnectionData conData in canvasData.connections) { // Restore all connections if (conData.port1.port == null || conData.port2.port == null) { // Not all ports where saved in canvasData LogMgr.Log("Incomplete connection " + conData.port1.name + " and " + conData.port2.name + "!"); continue; } conData.port1.port.TryApplyConnection(conData.port2.port, true); } foreach (GroupData groupData in canvasData.groups) { // Recreate groups NodeGroup group = new NodeGroup(); group.title = groupData.name; group.rect = groupData.rect; group.color = groupData.color; nodeCanvas.groups.Add(group); } nodeCanvas.editorStates = new NodeEditorState[canvasData.editorStates.Length]; for (int i = 0; i < canvasData.editorStates.Length; i++) { // Read all editorStates EditorStateData stateData = canvasData.editorStates[i]; NodeEditorState state = ScriptableObject.CreateInstance <NodeEditorState>(); state.selectedNode = stateData.selectedNode == null ? null : canvasData.FindNode(stateData.selectedNode.nodeID).node; state.panOffset = stateData.panOffset; state.zoom = stateData.zoom; state.canvas = nodeCanvas; state.name = "EditorState"; nodeCanvas.editorStates[i] = state; } NodeEditor.EndEditingCanvas(); return(nodeCanvas); }
/// <summary> /// Converts the NodeCanvas to a simplified CanvasData /// </summary> internal static CanvasData ConvertToCanvasData(NodeCanvas canvas) { if (canvas == null) { return(null); } // Validate canvas and create canvas data for it canvas.Validate(); CanvasData canvasData = new CanvasData(canvas); // Store Lookup-Table for all ports Dictionary <ConnectionPort, PortData> portDatas = new Dictionary <ConnectionPort, PortData>(); foreach (Node node in canvas.nodes) { // Create node data NodeData nodeData = new NodeData(node); canvasData.nodes.Add(nodeData.nodeID, nodeData); foreach (ConnectionPortDeclaration portDecl in ConnectionPortManager.GetPortDeclarationEnumerator(node)) { // Fetch all static connection port declarations and record them ConnectionPort port = (ConnectionPort)portDecl.portField.GetValue(node); PortData portData = new PortData(nodeData, port, portDecl.portField.Name); nodeData.connectionPorts.Add(portData); portDatas.Add(port, portData); } foreach (ConnectionPort port in node.dynamicConnectionPorts) { // Fetch all dynamic connection ports and record them PortData portData = new PortData(nodeData, port); nodeData.connectionPorts.Add(portData); portDatas.Add(port, portData); } // Fetch all serialized node variables specific to each node's implementation FieldInfo[] serializedFields = ReflectionUtility.getSerializedFields(node.GetType(), typeof(Node)); foreach (FieldInfo field in serializedFields) { // Create variable data and enter the if (field.FieldType.IsSubclassOf(typeof(ConnectionPort))) { continue; } VariableData varData = new VariableData(field); nodeData.variables.Add(varData); object varValue = field.GetValue(node); if (field.FieldType.IsValueType) // Store value of the object { varData.value = varValue; } else // Store reference to the object { varData.refObject = canvasData.ReferenceObject(varValue); } } } foreach (PortData portData in portDatas.Values) { // Record the connections of this port foreach (ConnectionPort conPort in portData.port.connections) { PortData conPortData; // Get portData associated with the connection port if (portDatas.TryGetValue(conPort, out conPortData)) { canvasData.RecordConnection(portData, conPortData); } } } foreach (NodeGroup group in canvas.groups) { // Record all groups canvasData.groups.Add(new GroupData(group)); } canvasData.editorStates = new EditorStateData[canvas.editorStates.Length]; for (int i = 0; i < canvas.editorStates.Length; i++) { // Record all editorStates NodeEditorState state = canvas.editorStates[i]; NodeData selected = state.selectedNode == null ? null : canvasData.FindNode(state.selectedNode); canvasData.editorStates[i] = new EditorStateData(selected, state.panOffset, state.zoom); } return(canvasData); }
public bool isPart(PortData port) { return(port1 == port || port2 == port); }
public ConnectionData(PortData Port1, PortData Port2) { port1 = Port1; port2 = Port2; }
public override CanvasData ImportData(params object[] args) { if (args == null || args.Length != 1 || args[0].GetType() != typeof(string)) { throw new ArgumentException("Location Arguments"); } string path = (string)args[0]; using (FileStream fs = new FileStream(path, FileMode.Open)) { XmlDocument data = new XmlDocument(); data.Load(fs); // CANVAS string canvasName = Path.GetFileNameWithoutExtension(path); XmlElement xmlCanvas = (XmlElement)data.SelectSingleNode("//NodeCanvas"); Type canvasType = NodeCanvasManager.GetCanvasTypeData(xmlCanvas.GetAttribute("type")).CanvasType; if (canvasType == null) { throw new XmlException("Could not find NodeCanvas of type '" + xmlCanvas.GetAttribute("type") + "'!"); } CanvasData canvasData = new CanvasData(canvasType, canvasName); Dictionary <int, PortData> ports = new Dictionary <int, PortData>(); // OBJECTS IEnumerable <XmlElement> xmlObjects = xmlCanvas.SelectNodes("Objects/Object").OfType <XmlElement>(); foreach (XmlElement xmlObject in xmlObjects) { int refID = GetIntegerAttribute(xmlObject, "refID"); string typeName = xmlObject.GetAttribute("type"); Type type = Type.GetType(typeName, true); object obj = DeserializeObjectFromXML(xmlObject, type); ObjectData objData = new ObjectData(refID, obj); canvasData.objects.Add(refID, objData); } // NODES IEnumerable <XmlElement> xmlNodes = xmlCanvas.SelectNodes("Nodes/Node").OfType <XmlElement>(); foreach (XmlElement xmlNode in xmlNodes) { string name = xmlNode.GetAttribute("name"); int nodeID = GetIntegerAttribute(xmlNode, "ID"); string typeID = xmlNode.GetAttribute("type"); Vector2 nodePos = GetVectorAttribute(xmlNode, "pos"); // Record NodeData node = new NodeData(name, typeID, nodeID, nodePos); canvasData.nodes.Add(nodeID, node); // NODE PORTS IEnumerable <XmlElement> xmlConnectionPorts = xmlNode.SelectNodes("Port").OfType <XmlElement>(); foreach (XmlElement xmlPort in xmlConnectionPorts) { int portID = GetIntegerAttribute(xmlPort, "ID"); string portName = xmlPort.GetAttribute("name"); if (string.IsNullOrEmpty(portName)) // Fallback to old save { portName = xmlPort.GetAttribute("varName"); } bool dynamic = GetBooleanAttribute(xmlPort, "dynamic", false); PortData portData; if (!dynamic) // Record static port { portData = new PortData(node, portName, portID); } else { // Deserialize dynamic port string typeName = xmlPort.GetAttribute("type"); Type portType = Type.GetType(typeName, true); if (portType != typeof(ConnectionPort) && !portType.IsSubclassOf(typeof(ConnectionPort))) { continue; // Invalid type stored } ConnectionPort port = (ConnectionPort)ScriptableObject.CreateInstance(portType); port.name = portName; foreach (XmlElement portVar in xmlPort.ChildNodes.OfType <XmlElement>()) { DeserializeFieldFromXML(portVar, port); } portData = new PortData(node, port, portID); } node.connectionPorts.Add(portData); ports.Add(portID, portData); } // NODE VARIABLES foreach (XmlElement variable in xmlNode.ChildNodes.OfType <XmlElement>()) { // Deserialize all value-type variables if (variable.Name != "Variable" && variable.Name != "Port") { string varName = variable.GetAttribute("name"); object varValue = DeserializeFieldFromXML(variable, node.type, null); VariableData varData = new VariableData(varName); varData.value = varValue; node.variables.Add(varData); } } IEnumerable <XmlElement> xmlVariables = xmlNode.SelectNodes("Variable").OfType <XmlElement>(); foreach (XmlElement xmlVariable in xmlVariables) { // Deserialize all reference-type variables (and also value type variables in old save files) string varName = xmlVariable.GetAttribute("name"); VariableData varData = new VariableData(varName); if (xmlVariable.HasAttribute("refID")) { // Read reference-type variables from objects int refID = GetIntegerAttribute(xmlVariable, "refID"); ObjectData objData; if (canvasData.objects.TryGetValue(refID, out objData)) { varData.refObject = objData; } } else { // Read value-type variable (old save file only) TODO: Remove string typeName = xmlVariable.GetAttribute("type"); Type type = Type.GetType(typeName, true); varData.value = DeserializeObjectFromXML(xmlVariable, type); } node.variables.Add(varData); } } // CONNECTIONS IEnumerable <XmlElement> xmlConnections = xmlCanvas.SelectNodes("Connections/Connection").OfType <XmlElement>(); foreach (XmlElement xmlConnection in xmlConnections) { int port1ID = GetIntegerAttribute(xmlConnection, "port1ID"); int port2ID = GetIntegerAttribute(xmlConnection, "port2ID"); PortData port1, port2; if (ports.TryGetValue(port1ID, out port1) && ports.TryGetValue(port2ID, out port2)) { canvasData.RecordConnection(port1, port2); } } // GROUPS IEnumerable <XmlElement> xmlGroups = xmlCanvas.SelectNodes("Groups/Group").OfType <XmlElement>(); foreach (XmlElement xmlGroup in xmlGroups) { string name = xmlGroup.GetAttribute("name"); Rect rect = GetRectAttribute(xmlGroup, "rect"); Color color = GetColorAttribute(xmlGroup, "color"); canvasData.groups.Add(new GroupData(name, rect, color)); } // EDITOR STATES IEnumerable <XmlElement> xmlEditorStates = xmlCanvas.SelectNodes("EditorStates/EditorState").OfType <XmlElement>(); List <EditorStateData> editorStates = new List <EditorStateData>(); foreach (XmlElement xmlEditorState in xmlEditorStates) { Vector2 pan = GetVectorAttribute(xmlEditorState, "pan"); float zoom; if (!float.TryParse(xmlEditorState.GetAttribute("zoom"), out zoom)) { zoom = 1; } // Selected Node NodeData selectedNode = null; int selectedNodeID; if (int.TryParse(xmlEditorState.GetAttribute("selected"), out selectedNodeID)) { selectedNode = canvasData.FindNode(selectedNodeID); } // Create state editorStates.Add(new EditorStateData(selectedNode, pan, zoom)); } canvasData.editorStates = editorStates.ToArray(); return(canvasData); } }