Exemplo n.º 1
0
        /// <summary>
        ///     Deserialize a function definition from a given path.  A side effect of this function is that
        ///     the node is added to the dictionary of loadedNodes.  
        /// </summary>
        /// <param name="funcDefGuid">The function guid we're currently loading</param>
        /// <param name="controller">Reference to the calling controller</param>
        /// <param name="def">The resultant function definition</param>
        /// <returns></returns>
        private bool GetDefinitionFromPath(Guid funcDefGuid, out FunctionDefinition def)
        {
            var controller = dynSettings.Controller;

            try
            {
                var xmlPath = GetNodePath(funcDefGuid);

                #region read xml file

                var xmlDoc = new XmlDocument();
                xmlDoc.Load(xmlPath);

                string funName = null;
                string category = "";
                double cx = 0;
                double cy = 0;
                string description = "";
                string version = "";

                double zoom = 1.0;
                string id = "";

                // load the header

                // handle legacy workspace nodes called dynWorkspace
                // and new workspaces without the dyn prefix
                XmlNodeList workspaceNodes = xmlDoc.GetElementsByTagName("Workspace");
                if(workspaceNodes.Count == 0)
                    workspaceNodes = xmlDoc.GetElementsByTagName("dynWorkspace");

                foreach (XmlNode node in workspaceNodes)
                {
                    foreach (XmlAttribute att in node.Attributes)
                    {
                        if (att.Name.Equals("X"))
                            cx = double.Parse(att.Value, CultureInfo.InvariantCulture);
                        else if (att.Name.Equals("Y"))
                            cy = double.Parse(att.Value, CultureInfo.InvariantCulture);
                        else if (att.Name.Equals("zoom"))
                            zoom = double.Parse(att.Value, CultureInfo.InvariantCulture);
                        else if (att.Name.Equals("Name"))
                            funName = att.Value;
                        else if (att.Name.Equals("Category"))
                            category = att.Value;
                        else if (att.Name.Equals("Description"))
                            description = att.Value;
                        else if (att.Name.Equals("ID"))
                            id = att.Value;
                        else if (att.Name.Equals("Version"))
                            version = att.Value;
                    }
                }

                // we have a dyf and it lacks an ID field, we need to assign it
                // a deterministic guid based on its name.  By doing it deterministically,
                // files remain compatible
                if (string.IsNullOrEmpty(id) && !string.IsNullOrEmpty(funName))
                {
                    id = GuidUtility.Create(GuidUtility.UrlNamespace, funName).ToString();
                }

                #endregion

                //DynamoCommands.WriteToLogCmd.Execute("Loading node definition for \"" + funName + "\" from: " + xmlPath);
                dynSettings.Controller.DynamoModel.WriteToLog("Loading node definition for \"" + funName + "\" from: " + xmlPath);

                var ws = new CustomNodeWorkspaceModel(
                    funName, category.Length > 0
                    ? category
                    : "Custom Nodes", description, cx, cy)
                {
                    WatchChanges = false,
                    FileName = xmlPath,
                    Zoom = zoom
                };

                def = new FunctionDefinition(Guid.Parse(id))
                {
                    WorkspaceModel = ws
                };

                // load a dummy version, so any nodes depending on this node
                // will find an (empty) identifier on compilation
                FScheme.Expression dummyExpression = FScheme.Expression.NewNumber_E(0);
                controller.FSchemeEnvironment.DefineSymbol(def.FunctionId.ToString(), dummyExpression);

                // set the node as loaded
                this.LoadedCustomNodes.Add(def.FunctionId, def);

                XmlNodeList elNodes = xmlDoc.GetElementsByTagName("Elements");
                XmlNodeList cNodes = xmlDoc.GetElementsByTagName("Connectors");
                XmlNodeList nNodes = xmlDoc.GetElementsByTagName("Notes");

                if (elNodes.Count == 0)
                    elNodes = xmlDoc.GetElementsByTagName("dynElements");
                if (cNodes.Count == 0)
                    cNodes = xmlDoc.GetElementsByTagName("dynConnectors");
                if (nNodes.Count == 0)
                    nNodes = xmlDoc.GetElementsByTagName("dynNotes");

                XmlNode elNodesList = elNodes[0];
                XmlNode cNodesList = cNodes[0];
                XmlNode nNodesList = nNodes[0];

                #region instantiate nodes

                var badNodes = new List<Guid>();

                foreach (XmlNode elNode in elNodesList.ChildNodes)
                {
                    XmlAttribute typeAttrib = elNode.Attributes["type"];
                    XmlAttribute guidAttrib = elNode.Attributes["guid"];
                    XmlAttribute nicknameAttrib = elNode.Attributes["nickname"];
                    XmlAttribute xAttrib = elNode.Attributes["x"];
                    XmlAttribute yAttrib = elNode.Attributes["y"];
                    XmlAttribute lacingAttrib = elNode.Attributes["lacing"];
                    XmlAttribute isVisAttrib = elNode.Attributes["isVisible"];
                    XmlAttribute isUpstreamVisAttrib = elNode.Attributes["isUpstreamVisible"];

                    string typeName = typeAttrib.Value;

                    //test the GUID to confirm that it is non-zero
                    //if it is zero, then we have to fix it
                    //this will break the connectors, but it won't keep
                    //propagating bad GUIDs
                    var guid = new Guid(guidAttrib.Value);
                    if (guid == Guid.Empty)
                    {
                        guid = Guid.NewGuid();
                    }

                    string nickname = nicknameAttrib.Value;

                    double x = double.Parse(xAttrib.Value, CultureInfo.InvariantCulture);
                    double y = double.Parse(yAttrib.Value, CultureInfo.InvariantCulture);

                    bool isVisible = true;
                    if (isVisAttrib != null)
                        isVisible = isVisAttrib.Value == "true" ? true : false;

                    bool isUpstreamVisible = true;
                    if (isUpstreamVisAttrib != null)
                        isUpstreamVisible = isUpstreamVisAttrib.Value == "true" ? true : false;

                    typeName = Dynamo.Nodes.Utilities.PreprocessTypeName(typeName);
                    System.Type type = Dynamo.Nodes.Utilities.ResolveType(typeName);
                    if (null == type)
                    {
                        badNodes.Add(guid);
                        continue;
                    }

                    NodeModel el = dynSettings.Controller.DynamoModel.CreateNodeInstance(type, nickname, guid);

                    if (lacingAttrib != null)
                    {
                        LacingStrategy lacing = LacingStrategy.First;
                        Enum.TryParse(lacingAttrib.Value, out lacing);
                        el.ArgumentLacing = lacing;
                    }

                    el.IsVisible = isVisible;
                    el.IsUpstreamVisible = isUpstreamVisible;

                    ws.Nodes.Add(el);
                    el.WorkSpace = ws;
                    var node = el;

                    node.X = x;
                    node.Y = y;

                    if (el == null)
                        return false;

                    el.DisableReporting();

                    el.Load(
                        elNode,
                        string.IsNullOrEmpty(version)
                            ? new Version(0, 0, 0, 0)
                            : new Version(version));
                }

                #endregion

                #region instantiate connectors

                foreach (XmlNode connector in cNodesList.ChildNodes)
                {
                    XmlAttribute guidStartAttrib = connector.Attributes[0];
                    XmlAttribute intStartAttrib = connector.Attributes[1];
                    XmlAttribute guidEndAttrib = connector.Attributes[2];
                    XmlAttribute intEndAttrib = connector.Attributes[3];
                    XmlAttribute portTypeAttrib = connector.Attributes[4];

                    var guidStart = new Guid(guidStartAttrib.Value);
                    var guidEnd = new Guid(guidEndAttrib.Value);
                    int startIndex = Convert.ToInt16(intStartAttrib.Value);
                    int endIndex = Convert.ToInt16(intEndAttrib.Value);
                    PortType portType = ((PortType)Convert.ToInt16(portTypeAttrib.Value));

                    //find the elements to connect
                    NodeModel start = null;
                    NodeModel end = null;

                    if (badNodes.Contains(guidStart) || badNodes.Contains(guidEnd))
                        continue;

                    foreach (NodeModel e in ws.Nodes)
                    {
                        if (e.GUID == guidStart)
                        {
                            start = e;
                        }
                        else if (e.GUID == guidEnd)
                        {
                            end = e;
                        }
                        if (start != null && end != null)
                        {
                            break;
                        }
                    }

                    try
                    {
                        var newConnector = ConnectorModel.Make(
                            start, end,
                            startIndex, endIndex,
                            portType);
                        if (newConnector != null)
                            ws.Connectors.Add(newConnector);
                    }
                    catch
                    {
                        //DynamoCommands.WriteToLogCmd.Execute(string.Format("ERROR : Could not create connector between {0} and {1}.", start.NickName, end.NickName));
                        dynSettings.Controller.DynamoModel.WriteToLog(string.Format("ERROR : Could not create connector between {0} and {1}.", start.NickName, end.NickName));
                    }
                }

                #endregion

                #region instantiate notes

                if (nNodesList != null)
                {
                    foreach (XmlNode note in nNodesList.ChildNodes)
                    {
                        XmlAttribute textAttrib = note.Attributes[0];
                        XmlAttribute xAttrib = note.Attributes[1];
                        XmlAttribute yAttrib = note.Attributes[2];

                        string text = textAttrib.Value;
                        double x = Convert.ToDouble(xAttrib.Value, CultureInfo.InvariantCulture);
                        double y = Convert.ToDouble(yAttrib.Value, CultureInfo.InvariantCulture);

                        Guid guid = Guid.NewGuid();
                        var command = new DynCmd.CreateNoteCommand(guid, text, x, y, false);
                        dynSettings.Controller.DynamoModel.AddNoteInternal(command, ws);
                    }
                }

                #endregion

                foreach (var e in ws.Nodes)
                    e.EnableReporting();

                def.CompileAndAddToEnvironment(controller.FSchemeEnvironment);

                ws.WatchChanges = true;

                this.OnGetDefinitionFromPath(def);

            }
            catch (Exception ex)
            {
                dynSettings.Controller.DynamoModel.WriteToLog("There was an error opening the workbench.");
                dynSettings.Controller.DynamoModel.WriteToLog(ex);

                if (DynamoController.IsTestMode)
                    Assert.Fail(ex.Message);

                def = null;
                return false;
            }

            return true;
        }
Exemplo n.º 2
0
        /// <summary>
        ///     Deserialize a function definition from a given path.  A side effect of this function is that
        ///     the node is added to the dictionary of loadedNodes.
        /// </summary>
        /// <param name="funcDefGuid">The function guid we're currently loading</param>
        /// <param name="controller">Reference to the calling controller</param>
        /// <param name="def">The resultant function definition</param>
        /// <returns></returns>
        private bool GetDefinitionFromPath(Guid funcDefGuid, out FunctionDefinition def)
        {
            var controller = dynSettings.Controller;

            try
            {
                var xmlPath = GetNodePath(funcDefGuid);

                #region read xml file

                var xmlDoc = new XmlDocument();
                xmlDoc.Load(xmlPath);

                string funName     = null;
                string category    = "";
                double cx          = 0;
                double cy          = 0;
                string description = "";
                string version     = "";

                double zoom = 1.0;
                string id   = "";

                // load the header

                // handle legacy workspace nodes called dynWorkspace
                // and new workspaces without the dyn prefix
                XmlNodeList workspaceNodes = xmlDoc.GetElementsByTagName("Workspace");
                if (workspaceNodes.Count == 0)
                {
                    workspaceNodes = xmlDoc.GetElementsByTagName("dynWorkspace");
                }

                foreach (XmlNode node in workspaceNodes)
                {
                    foreach (XmlAttribute att in node.Attributes)
                    {
                        if (att.Name.Equals("X"))
                        {
                            cx = double.Parse(att.Value, CultureInfo.InvariantCulture);
                        }
                        else if (att.Name.Equals("Y"))
                        {
                            cy = double.Parse(att.Value, CultureInfo.InvariantCulture);
                        }
                        else if (att.Name.Equals("zoom"))
                        {
                            zoom = double.Parse(att.Value, CultureInfo.InvariantCulture);
                        }
                        else if (att.Name.Equals("Name"))
                        {
                            funName = att.Value;
                        }
                        else if (att.Name.Equals("Category"))
                        {
                            category = att.Value;
                        }
                        else if (att.Name.Equals("Description"))
                        {
                            description = att.Value;
                        }
                        else if (att.Name.Equals("ID"))
                        {
                            id = att.Value;
                        }
                        else if (att.Name.Equals("Version"))
                        {
                            version = att.Value;
                        }
                    }
                }

                // we have a dyf and it lacks an ID field, we need to assign it
                // a deterministic guid based on its name.  By doing it deterministically,
                // files remain compatible
                if (string.IsNullOrEmpty(id) && !string.IsNullOrEmpty(funName))
                {
                    id = GuidUtility.Create(GuidUtility.UrlNamespace, funName).ToString();
                }

                #endregion

                //DynamoCommands.WriteToLogCmd.Execute("Loading node definition for \"" + funName + "\" from: " + xmlPath);
                dynSettings.Controller.DynamoModel.WriteToLog("Loading node definition for \"" + funName + "\" from: " + xmlPath);

                var ws = new CustomNodeWorkspaceModel(
                    funName, category.Length > 0
                    ? category
                    : "Custom Nodes", description, cx, cy)
                {
                    WatchChanges = false,
                    FileName     = xmlPath,
                    Zoom         = zoom
                };

                def = new FunctionDefinition(Guid.Parse(id))
                {
                    WorkspaceModel = ws
                };

                // load a dummy version, so any nodes depending on this node
                // will find an (empty) identifier on compilation
                FScheme.Expression dummyExpression = FScheme.Expression.NewNumber_E(0);
                controller.FSchemeEnvironment.DefineSymbol(def.FunctionId.ToString(), dummyExpression);

                // set the node as loaded
                this.LoadedCustomNodes.Add(def.FunctionId, def);

                XmlNodeList elNodes = xmlDoc.GetElementsByTagName("Elements");
                XmlNodeList cNodes  = xmlDoc.GetElementsByTagName("Connectors");
                XmlNodeList nNodes  = xmlDoc.GetElementsByTagName("Notes");

                if (elNodes.Count == 0)
                {
                    elNodes = xmlDoc.GetElementsByTagName("dynElements");
                }
                if (cNodes.Count == 0)
                {
                    cNodes = xmlDoc.GetElementsByTagName("dynConnectors");
                }
                if (nNodes.Count == 0)
                {
                    nNodes = xmlDoc.GetElementsByTagName("dynNotes");
                }

                XmlNode elNodesList = elNodes[0];
                XmlNode cNodesList  = cNodes[0];
                XmlNode nNodesList  = nNodes[0];

                #region instantiate nodes

                var badNodes = new List <Guid>();

                foreach (XmlNode elNode in elNodesList.ChildNodes)
                {
                    XmlAttribute typeAttrib          = elNode.Attributes["type"];
                    XmlAttribute guidAttrib          = elNode.Attributes["guid"];
                    XmlAttribute nicknameAttrib      = elNode.Attributes["nickname"];
                    XmlAttribute xAttrib             = elNode.Attributes["x"];
                    XmlAttribute yAttrib             = elNode.Attributes["y"];
                    XmlAttribute lacingAttrib        = elNode.Attributes["lacing"];
                    XmlAttribute isVisAttrib         = elNode.Attributes["isVisible"];
                    XmlAttribute isUpstreamVisAttrib = elNode.Attributes["isUpstreamVisible"];

                    string typeName = typeAttrib.Value;

                    //test the GUID to confirm that it is non-zero
                    //if it is zero, then we have to fix it
                    //this will break the connectors, but it won't keep
                    //propagating bad GUIDs
                    var guid = new Guid(guidAttrib.Value);
                    if (guid == Guid.Empty)
                    {
                        guid = Guid.NewGuid();
                    }

                    string nickname = nicknameAttrib.Value;

                    double x = double.Parse(xAttrib.Value, CultureInfo.InvariantCulture);
                    double y = double.Parse(yAttrib.Value, CultureInfo.InvariantCulture);

                    bool isVisible = true;
                    if (isVisAttrib != null)
                    {
                        isVisible = isVisAttrib.Value == "true" ? true : false;
                    }

                    bool isUpstreamVisible = true;
                    if (isUpstreamVisAttrib != null)
                    {
                        isUpstreamVisible = isUpstreamVisAttrib.Value == "true" ? true : false;
                    }

                    typeName = Dynamo.Nodes.Utilities.PreprocessTypeName(typeName);
                    System.Type type = Dynamo.Nodes.Utilities.ResolveType(typeName);
                    if (null == type)
                    {
                        badNodes.Add(guid);
                        continue;
                    }

                    NodeModel el = dynSettings.Controller.DynamoModel.CreateNodeInstance(type, nickname, guid);

                    if (lacingAttrib != null)
                    {
                        LacingStrategy lacing = LacingStrategy.First;
                        Enum.TryParse(lacingAttrib.Value, out lacing);
                        el.ArgumentLacing = lacing;
                    }

                    el.IsVisible         = isVisible;
                    el.IsUpstreamVisible = isUpstreamVisible;

                    ws.Nodes.Add(el);
                    el.WorkSpace = ws;
                    var node = el;

                    node.X = x;
                    node.Y = y;

                    if (el == null)
                    {
                        return(false);
                    }

                    el.DisableReporting();

                    el.Load(
                        elNode,
                        string.IsNullOrEmpty(version)
                            ? new Version(0, 0, 0, 0)
                            : new Version(version));
                }

                #endregion

                #region instantiate connectors

                foreach (XmlNode connector in cNodesList.ChildNodes)
                {
                    XmlAttribute guidStartAttrib = connector.Attributes[0];
                    XmlAttribute intStartAttrib  = connector.Attributes[1];
                    XmlAttribute guidEndAttrib   = connector.Attributes[2];
                    XmlAttribute intEndAttrib    = connector.Attributes[3];
                    XmlAttribute portTypeAttrib  = connector.Attributes[4];

                    var      guidStart  = new Guid(guidStartAttrib.Value);
                    var      guidEnd    = new Guid(guidEndAttrib.Value);
                    int      startIndex = Convert.ToInt16(intStartAttrib.Value);
                    int      endIndex   = Convert.ToInt16(intEndAttrib.Value);
                    PortType portType   = ((PortType)Convert.ToInt16(portTypeAttrib.Value));

                    //find the elements to connect
                    NodeModel start = null;
                    NodeModel end   = null;

                    if (badNodes.Contains(guidStart) || badNodes.Contains(guidEnd))
                    {
                        continue;
                    }

                    foreach (NodeModel e in ws.Nodes)
                    {
                        if (e.GUID == guidStart)
                        {
                            start = e;
                        }
                        else if (e.GUID == guidEnd)
                        {
                            end = e;
                        }
                        if (start != null && end != null)
                        {
                            break;
                        }
                    }

                    try
                    {
                        var newConnector = ConnectorModel.Make(
                            start, end,
                            startIndex, endIndex,
                            portType);
                        if (newConnector != null)
                        {
                            ws.Connectors.Add(newConnector);
                        }
                    }
                    catch
                    {
                        //DynamoCommands.WriteToLogCmd.Execute(string.Format("ERROR : Could not create connector between {0} and {1}.", start.NickName, end.NickName));
                        dynSettings.Controller.DynamoModel.WriteToLog(string.Format("ERROR : Could not create connector between {0} and {1}.", start.NickName, end.NickName));
                    }
                }

                #endregion

                #region instantiate notes

                if (nNodesList != null)
                {
                    foreach (XmlNode note in nNodesList.ChildNodes)
                    {
                        XmlAttribute textAttrib = note.Attributes[0];
                        XmlAttribute xAttrib    = note.Attributes[1];
                        XmlAttribute yAttrib    = note.Attributes[2];

                        string text = textAttrib.Value;
                        double x    = Convert.ToDouble(xAttrib.Value, CultureInfo.InvariantCulture);
                        double y    = Convert.ToDouble(yAttrib.Value, CultureInfo.InvariantCulture);

                        Guid guid    = Guid.NewGuid();
                        var  command = new DynCmd.CreateNoteCommand(guid, text, x, y, false);
                        dynSettings.Controller.DynamoModel.AddNoteInternal(command, ws);
                    }
                }

                #endregion

                foreach (var e in ws.Nodes)
                {
                    e.EnableReporting();
                }

                def.CompileAndAddToEnvironment(controller.FSchemeEnvironment);

                ws.WatchChanges = true;

                this.OnGetDefinitionFromPath(def);
            }
            catch (Exception ex)
            {
                dynSettings.Controller.DynamoModel.WriteToLog("There was an error opening the workbench.");
                dynSettings.Controller.DynamoModel.WriteToLog(ex);

                if (DynamoController.IsTestMode)
                {
                    Assert.Fail(ex.Message);
                }

                def = null;
                return(false);
            }

            return(true);
        }