/// <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 == typeof(ConnectionPort) || field.FieldType.IsSubclassOf(typeof(ConnectionPort))) { continue; } VariableData varData = new VariableData(field); nodeData.variables.Add(varData); object varValue = field.GetValue(node); if (field.FieldType.IsValueType || field.FieldType == typeof(string)) // 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 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); } }