Пример #1
0
 /// <summary>
 /// Exports the given simplified canvas data to the location specified in the args (usually string[1] containing the path)
 /// </summary>
 public abstract void ExportData(CanvasData data, params object[] locationArgs);
Пример #2
0
        public override void Export(NodeCanvas canvas, params object[] locationArgs)
        {
            CanvasData data = ImportExportManager.ConvertToCanvasData(canvas);

            ExportData(data, locationArgs);
        }
Пример #3
0
        public override void ExportData(CanvasData data, params object[] args)
        {
            if (args == null || args.Length != 1 || args[0].GetType() != typeof(string))
            {
                throw new ArgumentException("Location Arguments");
            }
            string path = (string)args[0];

            XmlDocument    saveDoc = new XmlDocument();
            XmlDeclaration decl    = saveDoc.CreateXmlDeclaration("1.0", "UTF-8", null);

            saveDoc.InsertBefore(decl, saveDoc.DocumentElement);

            // CANVAS

            XmlElement canvas = saveDoc.CreateElement("NodeCanvas");

            canvas.SetAttribute("type", data.type.FullName);
            saveDoc.AppendChild(canvas);

            // EDITOR STATES

            XmlElement editorStates = saveDoc.CreateElement("EditorStates");

            canvas.AppendChild(editorStates);
            foreach (EditorStateData stateData in data.editorStates)
            {
                XmlElement editorState = saveDoc.CreateElement("EditorState");
                editorState.SetAttribute("selected", stateData.selectedNode != null ? stateData.selectedNode.nodeID.ToString() : "");
                editorState.SetAttribute("pan", stateData.panOffset.x + "," + stateData.panOffset.y);
                editorState.SetAttribute("zoom", stateData.zoom.ToString());
                editorStates.AppendChild(editorState);
            }

            // GROUPS

            XmlElement groups = saveDoc.CreateElement("Groups");

            canvas.AppendChild(groups);
            foreach (GroupData groupData in data.groups)
            {
                XmlElement group = saveDoc.CreateElement("Group");
                group.SetAttribute("name", groupData.name);
                group.SetAttribute("rect", groupData.rect.x + "," + groupData.rect.y + "," + groupData.rect.width + "," + groupData.rect.height);
                group.SetAttribute("color", groupData.color.r + "," + groupData.color.g + "," + groupData.color.b + "," + groupData.color.a);
                groups.AppendChild(group);
            }

            // NODES

            XmlElement nodes = saveDoc.CreateElement("Nodes");

            canvas.AppendChild(nodes);
            foreach (NodeData nodeData in data.nodes.Values)
            {
                XmlElement node = saveDoc.CreateElement("Node");
                node.SetAttribute("name", nodeData.name);
                node.SetAttribute("ID", nodeData.nodeID.ToString());
                node.SetAttribute("type", nodeData.typeID);
                node.SetAttribute("pos", nodeData.nodePos.x + "," + nodeData.nodePos.y);
                nodes.AppendChild(node);

                // NODE PORTS

                foreach (PortData portData in nodeData.connectionPorts)
                {
                    XmlElement port = saveDoc.CreateElement("Port");
                    port.SetAttribute("ID", portData.portID.ToString());
                    port.SetAttribute("name", portData.name);
                    port.SetAttribute("dynamic", portData.dynamic.ToString());
                    if (portData.dynamic)
                    {                     // Serialize dynamic port
                        port.SetAttribute("type", portData.dynaType.AssemblyQualifiedName);
                        foreach (string fieldName in portData.port.AdditionalDynamicKnobData())
                        {
                            SerializeFieldToXML(port, portData.port, fieldName);                             // Serialize all dynamic knob variables
                        }
                    }
                    node.AppendChild(port);
                }

                // NODE VARIABLES

                foreach (VariableData varData in nodeData.variables)
                {                 // Serialize all node variables
                    if (varData.refObject != null)
                    {             // Serialize reference-type variables as 'Variable' element
                        XmlElement variable = saveDoc.CreateElement("Variable");
                        variable.SetAttribute("name", varData.name);
                        variable.SetAttribute("refID", varData.refObject.refID.ToString());
                        node.AppendChild(variable);
                    }
                    else                     // Serialize value-type fields in-line
                    {
                        XmlElement serializedValue = SerializeObjectToXML(node, varData.value);
                        if (serializedValue != null)
                        {
                            serializedValue.SetAttribute("name", varData.name);
                        }
                    }
                }
            }

            // CONNECTIONS

            XmlElement connections = saveDoc.CreateElement("Connections");

            canvas.AppendChild(connections);
            foreach (ConnectionData connectionData in data.connections)
            {
                XmlElement connection = saveDoc.CreateElement("Connection");
                connection.SetAttribute("port1ID", connectionData.port1.portID.ToString());
                connection.SetAttribute("port2ID", connectionData.port2.portID.ToString());
                connections.AppendChild(connection);
            }

            // OBJECTS

            XmlElement objects = saveDoc.CreateElement("Objects");

            canvas.AppendChild(objects);
            foreach (ObjectData objectData in data.objects.Values)
            {
                XmlElement obj = saveDoc.CreateElement("Object");
                obj.SetAttribute("refID", objectData.refID.ToString());
                obj.SetAttribute("type", objectData.data.GetType().FullName);
                if (SerializeObjectToXML(obj, objectData.data) != null)
                {
                    objects.AppendChild(obj);
                }
            }

            // WRITE

            Directory.CreateDirectory(Path.GetDirectoryName(path));
            using (XmlTextWriter writer = new XmlTextWriter(path, Encoding.UTF8))
            {
                writer.Formatting  = Formatting.Indented;
                writer.Indentation = 1;
                writer.IndentChar  = '\t';
                saveDoc.Save(writer);
            }
        }
Пример #4
0
        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);
            }
        }
Пример #5
0
        /// <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, nodeCanvas, 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, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
                    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
                    Debug.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);
        }
Пример #6
0
        /// <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);
        }