Exemple #1
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.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);
        }
Exemple #2
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);
            }
        }