예제 #1
0
        protected override void Run(List <NodeModel> topElements, FScheme.Expression runningExpression)
        {
            var model = (DynamoRevitViewModel)DynamoViewModel;

            //If we are not running in debug...
            if (!DynamoViewModel.RunInDebug)
            {
                //Do we need manual transaction control?
                bool manualTrans = topElements.Any(CheckManualTransaction.TraverseUntilAny);

                //Can we avoid running everything in the Revit Idle thread?
                bool noIdleThread = manualTrans ||
                                    !topElements.Any(CheckRequiresTransaction.TraverseUntilAny);

                //If we don't need to be in the idle thread...
                if (noIdleThread || IsTestMode)
                {
                    //DynamoLogger.Instance.Log("Running expression in evaluation thread...");
                    TransMode = TransactionMode.Manual; //Manual transaction control

                    if (IsTestMode)
                    {
                        TransMode = TransactionMode.Automatic;
                    }

                    InIdleThread = false;                     //Not in idle thread at the moment
                    base.Run(topElements, runningExpression); //Just run the Run Delegate
                }
                else //otherwise...
                {
                    //DynamoLogger.Instance.Log("Running expression in Revit's Idle thread...");
                    TransMode = TransactionMode.Automatic; //Automatic transaction control

                    Debug.WriteLine("Adding a run to the idle stack.");
                    InIdleThread = true; //Now in the idle thread.
                    IdlePromise.ExecuteOnIdle(
                        () => base.Run(topElements, runningExpression),
                        false); //Execute the Run Delegate in the Idle thread.
                }
            }
            else //If we are in debug mode...
            {
                TransMode    = TransactionMode.Debug; //Debug transaction control
                InIdleThread = true; //Everything will be evaluated in the idle thread.

                DynamoLogger.Instance.Log("Running expression in debug.");

                //Execute the Run Delegate.
                base.Run(topElements, runningExpression);
            }
        }
예제 #2
0
        protected override void Run(IEnumerable <dynNodeModel> topElements, FScheme.Expression runningExpression)
        {
            //If we are not running in debug...
            if (!this.DynamoViewModel.RunInDebug)
            {
                //Do we need manual transaction control?
                bool manualTrans = topElements.Any((DynamoViewModel as DynamoRevitViewModel).CheckManualTransaction.TraverseUntilAny);

                //Can we avoid running everything in the Revit Idle thread?
                bool noIdleThread = manualTrans ||
                                    !topElements.Any((DynamoViewModel as DynamoRevitViewModel).CheckRequiresTransaction.TraverseUntilAny);

                //If we don't need to be in the idle thread...
                if (noIdleThread || this.Testing)
                {
                    DynamoLogger.Instance.Log("Running expression in evaluation thread...");
                    (DynamoViewModel as DynamoRevitViewModel).TransMode = DynamoRevitViewModel.TransactionMode.Manual; //Manual transaction control

                    if (this.Testing)
                    {
                        (DynamoViewModel as DynamoRevitViewModel).TransMode = DynamoRevitViewModel.TransactionMode.Automatic;
                    }

                    this.InIdleThread = false;                //Not in idle thread at the moment
                    base.Run(topElements, runningExpression); //Just run the Run Delegate
                }
                else //otherwise...
                {
                    DynamoLogger.Instance.Log("Running expression in Revit's Idle thread...");
                    (DynamoViewModel as DynamoRevitViewModel).TransMode = DynamoRevitViewModel.TransactionMode.Automatic; //Automatic transaction control

                    Debug.WriteLine("Adding a run to the idle stack.");
                    this.InIdleThread = true; //Now in the idle thread.
                    IdlePromise.ExecuteOnIdle(new Action(
                                                  () => base.Run(topElements, runningExpression)),
                                              false); //Execute the Run Delegate in the Idle thread.
                }
            }
            else //If we are in debug mode...
            {
                (DynamoViewModel as DynamoRevitViewModel).TransMode = DynamoRevitViewModel.TransactionMode.Debug; //Debug transaction control
                this.InIdleThread = true; //Everything will be evaluated in the idle thread.

                dynSettings.Controller.DynamoViewModel.Log("Running expression in debug.");

                //Execute the Run Delegate.
                base.Run(topElements, runningExpression);
            }
        }
예제 #3
0
 public void Log(FScheme.Expression expression)
 {
     Log(FScheme.printExpression("\t", expression));
 }
예제 #4
0
        protected virtual void Run(List <dynNodeModel> topElements, FScheme.Expression runningExpression)
        {
            //Print some stuff if we're in debug mode
            if (DynamoViewModel.RunInDebug)
            {
                if (dynSettings.Controller.UIDispatcher != null)
                {
                    foreach (string exp in topElements.Select(node => node.PrintExpression()))
                    {
                        DynamoLogger.Instance.Log("> " + exp);
                    }
                }
            }

            try
            {
                DynamoLogger.Instance.Log("Evaluating the expression...");

                //Evaluate the expression
                FScheme.Value expr = FSchemeEnvironment.Evaluate(runningExpression);

                if (dynSettings.Controller.UIDispatcher != null)
                {
                    //Print some more stuff if we're in debug mode
                    if (DynamoViewModel.RunInDebug && expr != null)
                    {
                        DynamoLogger.Instance.Log(FScheme.print(expr));
                    }
                }
            }
            catch (CancelEvaluationException ex)
            {
                /* Evaluation was cancelled */

                OnRunCancelled(false);
                RunCancelled = false;
                if (ex.Force)
                {
                    runAgain = false;
                }
            }
            catch (Exception ex)
            {
                /* Evaluation failed due to error */

                if (dynSettings.Controller.UIDispatcher != null)
                {
                    //Print unhandled exception
                    if (ex.Message.Length > 0)
                    {
                        dynSettings.Controller.DispatchOnUIThread(() => DynamoLogger.Instance.Log(ex));
                    }
                }

                OnRunCancelled(true);
                RunCancelled = true;
                runAgain     = false;

                //If we are testing, we need to throw an exception here
                //which will, in turn, throw an Assert.Fail in the
                //Evaluation thread.
                if (Testing)
                {
                    throw new Exception(ex.Message);
                }
            }

            OnEvaluationCompleted();
        }
예제 #5
0
        protected virtual void EvaluationThread(object s, DoWorkEventArgs args)
        {
            //Get our entry points (elements with nothing connected to output)
            List <dynNodeModel> topElements = DynamoViewModel.Model.HomeSpace.GetTopMostNodes().ToList();

            //Mark the topmost as dirty/clean
            foreach (dynNodeModel topMost in topElements)
            {
                topMost.MarkDirty();
            }

            //TODO: Flesh out error handling
            try
            {
                var topNode   = new BeginNode(new List <string>());
                int i         = 0;
                var buildDict = new Dictionary <dynNodeModel, Dictionary <int, INode> >();
                foreach (dynNodeModel topMost in topElements)
                {
                    string inputName = i.ToString();
                    topNode.AddInput(inputName);
                    topNode.ConnectInput(inputName, topMost.BuildExpression(buildDict));

                    i++;

                    DynamoLogger.Instance.Log(topMost);
                }

                FScheme.Expression runningExpression = topNode.Compile();

                Run(topElements, runningExpression);

                // inform any objects that a run has happened

                DynamoLogger.Instance.Log(runningExpression);
            }
            catch (CancelEvaluationException ex)
            {
                /* Evaluation was cancelled */

                OnRunCancelled(false);
                //this.CancelRun = false; //Reset cancel flag
                RunCancelled = false;

                //If we are forcing this, then make sure we don't run again either.
                if (ex.Force)
                {
                    runAgain = false;
                }

                OnRunCompleted(this, false);
            }
            catch (Exception ex)
            {
                /* Evaluation has an error */

                //Catch unhandled exception
                if (ex.Message.Length > 0)
                {
                    DynamoLogger.Instance.Log(ex);
                }

                OnRunCancelled(true);

                //Reset the flags
                runAgain     = false;
                RunCancelled = false;

                OnRunCompleted(this, false);

                if (Testing)
                {
                    Assert.Fail(ex.Message + ":" + ex.StackTrace);
                }
            }
            finally
            {
                /* Post-evaluation cleanup */

                DynamoViewModel.RunEnabled = true;

                //No longer running
                Running = false;

                foreach (FunctionDefinition def in dynSettings.FunctionWasEvaluated)
                {
                    def.RequiresRecalc = false;
                }


                //If we should run again...
                if (runAgain)
                {
                    //DynamoLogger.Instance.Log("Running again.");

                    //Reset flag
                    runAgain = false;

                    RunExpression(_showErrors);
                }
                else
                {
                    //DynamoLogger.Instance.Log("Run completed.");
                    OnRunCompleted(this, true);
                }
            }
        }
예제 #6
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);
        }
예제 #7
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, DynamoController controller, out FunctionDefinition def)
        {
            try
            {
                var xmlPath = GetNodePath(funcDefGuid);

                #region read xml file

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

                string funName     = null;
                string category    = "";
                string description = "";
                double cx          = DynamoView.CANVAS_OFFSET_X;
                double cy          = DynamoView.CANVAS_OFFSET_Y;
                double zoom        = 1.0;
                string id          = "";

                // load the header
                foreach (XmlNode node in xmlDoc.GetElementsByTagName("dynWorkspace"))
                {
                    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;
                        }
                    }
                }

                // 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);

                var ws = new FuncWorkspace(
                    funName, category.Length > 0
                    ? category
                    : BuiltinNodeCategories.SCRIPTING_CUSTOMNODES, description, cx, cy)
                {
                    WatchChanges = false
                };

                ws.Zoom = zoom;

                def = new FunctionDefinition(Guid.Parse(id))
                {
                    Workspace = 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);
                this.loadedNodes.Add(def.FunctionId, def);

                XmlNodeList elNodes = xmlDoc.GetElementsByTagName("dynElements");
                XmlNodeList cNodes  = xmlDoc.GetElementsByTagName("dynConnectors");
                XmlNodeList 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;

                    const string oldNamespace = "Dynamo.Elements.";
                    if (typeName.StartsWith(oldNamespace))
                    {
                        typeName = "Dynamo.Nodes." + typeName.Remove(0, oldNamespace.Length);
                    }

                    //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;
                    }

                    //Type t = Type.GetType(typeName);
                    TypeLoadData tData;
                    Type         t;

                    if (!controller.BuiltInTypesByName.TryGetValue(typeName, out tData))
                    {
                        //try and get a system type by this name
                        t = Type.GetType(typeName);

                        //if we still can't find the type, try the also known as attributes
                        if (t == null)
                        {
                            //try to get the also known as values
                            foreach (KeyValuePair <string, TypeLoadData> kvp in controller.BuiltInTypesByName)
                            {
                                var akaAttribs = kvp.Value.Type.GetCustomAttributes(typeof(AlsoKnownAsAttribute), false);
                                if (akaAttribs.Any())
                                {
                                    if ((akaAttribs[0] as AlsoKnownAsAttribute).Values.Contains(typeName))
                                    {
                                        controller.DynamoViewModel.Log(string.Format("Found matching node for {0} also known as {1}", kvp.Key, typeName));
                                        t = kvp.Value.Type;
                                    }
                                }
                            }
                        }

                        if (t == null)
                        {
                            controller.DynamoViewModel.Log("Could not load node of type: " + typeName);
                            controller.DynamoViewModel.Log("Loading will continue but nodes might be missing from your workflow.");

                            //return false;
                            badNodes.Add(guid);
                            continue;
                        }
                    }
                    else
                    {
                        t = tData.Type;
                    }

                    dynNodeModel el = dynSettings.Controller.DynamoViewModel.CreateNodeInstance(t, nickname, guid);

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

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

                    // note - this is because the connectors fail to be created if there's not added
                    // to the canvas
                    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); // inject the node properties from the xml

                    // moved this logic to LoadNode in dynFunction --SJE

                    //if (el is dynFunction)
                    //{
                    //    var fun = el as dynFunction;

                    //    // we've found a custom node, we need to attempt to load its guid.
                    //    // if it doesn't exist (i.e. its a legacy node), we need to assign it one,
                    //    // deterministically
                    //    Guid funId;
                    //    try
                    //    {
                    //        funId = Guid.Parse(fun.Symbol);
                    //    }
                    //    catch
                    //    {
                    //        funId = GuidUtility.Create(GuidUtility.UrlNamespace, nicknameAttrib.Value);
                    //        fun.Symbol = funId.ToString();
                    //    }

                    //    // if it's not a recurisve node and it's not yet loaded, load it
                    //    if (funcDefGuid != funId && !this.loadedNodes.ContainsKey(funId))
                    //    {
                    //        dynSettings.Controller.CustomNodeLoader.GetFunctionDefinition(funId);
                    //        fun.Definition = this.loadedNodes[funId];
                    //    }
                    //    else if ( this.loadedNodes.ContainsKey(funId ))
                    //    {
                    //        fun.Definition = this.loadedNodes[funId];
                    //    }

                    //}
                }

                #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);
                    int portType   = Convert.ToInt16(portTypeAttrib.Value);

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

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

                    foreach (dynNodeModel 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 = dynConnectorModel.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));
                    }
                }

                #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);
                        double y    = Convert.ToDouble(yAttrib.Value);

                        //dynNoteView n = Bench.AddNote(text, x, y, ws);
                        //Bench.AddNote(text, x, y, ws);

                        var paramDict = new Dictionary <string, object>();
                        paramDict.Add("x", x);
                        paramDict.Add("y", y);
                        paramDict.Add("text", text);
                        paramDict.Add("workspace", ws);
                        dynSettings.Controller.DynamoViewModel.AddNoteCommand.Execute(paramDict);
                    }
                }

                #endregion

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

                ws.FilePath = xmlPath;

                var expression = CompileFunction(def);
                controller.FSchemeEnvironment.DefineSymbol(def.FunctionId.ToString(), expression);

                ws.WatchChanges = true;
            }
            catch (Exception ex)
            {
                DynamoCommands.WriteToLogCmd.Execute("There was an error opening the workbench.");
                DynamoCommands.WriteToLogCmd.Execute(ex);

                if (controller.Testing)
                {
                    Assert.Fail(ex.Message);
                }

                def = null;
                return(false);
            }

            return(true);
        }
예제 #8
0
        public static FScheme.Expression CompileFunction(FunctionDefinition definition, ref IEnumerable <string> inputNames, ref IEnumerable <string> outputNames)
        {
            if (definition == null)
            {
                return(null);
            }

            // Get the internal nodes for the function
            dynWorkspaceModel functionWorkspace = definition.Workspace;

            #region Find outputs

            // Find output elements for the node
            List <dynOutput> outputs = functionWorkspace.Nodes.OfType <dynOutput>().ToList();

            var topMost = new List <Tuple <int, dynNodeModel> >();

            // if we found output nodes, add select their inputs
            // these will serve as the function output
            if (outputs.Any())
            {
                topMost.AddRange(
                    outputs.Where(x => x.HasInput(0)).Select(x => x.Inputs[0]));

                outputNames = outputs.Select(x => x.Symbol);
            }
            else
            {
                // if there are no explicitly defined output nodes
                // get the top most nodes and set THEM as the output
                IEnumerable <dynNodeModel> topMostNodes = functionWorkspace.GetTopMostNodes();

                var outNames = new List <string>();

                foreach (dynNodeModel topNode in topMostNodes)
                {
                    foreach (int output in Enumerable.Range(0, topNode.OutPortData.Count))
                    {
                        if (!topNode.HasOutput(output))
                        {
                            topMost.Add(Tuple.Create(output, topNode));
                            outNames.Add(topNode.OutPortData[output].NickName);
                        }
                    }
                }

                outputNames = outNames;
            }

            #endregion

            // color the node to define its connectivity
            foreach (var ele in topMost)
            {
                ele.Item2.ValidateConnections();
            }

            //Find function entry point, and then compile the function and add it to our environment
            IEnumerable <dynNodeModel> variables = functionWorkspace.Nodes.Where(x => x is dynSymbol);
            inputNames = variables.Select(x => (x as dynSymbol).Symbol);

            INode top;
            var   buildDict = new Dictionary <dynNodeModel, Dictionary <int, INode> >();

            if (topMost.Count > 1)
            {
                InputNode node = new ExternalFunctionNode(FScheme.Value.NewList);

                int i = 0;
                foreach (var topNode in topMost)
                {
                    string inputName = i.ToString();
                    node.AddInput(inputName);
                    node.ConnectInput(inputName, new BeginNode());
                    try
                    {
                        var exp = topNode.Item2.Build(buildDict, topNode.Item1);
                        node.ConnectInput(inputName, exp);
                    }
                    catch
                    {
                    }

                    i++;
                }

                top = node;
            }
            else if (topMost.Count == 1)
            {
                top = topMost[0].Item2.BuildExpression(buildDict);
            }
            else
            {
                // if the custom node is empty, it will initially be an empty begin
                top = new BeginNode();
            }

            // if the node has any outputs, we create a BeginNode in order to evaluate all of them
            // sequentially (begin evaluates a list of expressions)
            if (outputs.Any())
            {
                var beginNode = new BeginNode();
                List <dynNodeModel> hangingNodes = functionWorkspace.GetHangingNodes().ToList();

                foreach (var tNode in hangingNodes.Select((x, index) => new { Index = index, Node = x }))
                {
                    beginNode.AddInput(tNode.Index.ToString());
                    beginNode.ConnectInput(tNode.Index.ToString(), tNode.Node.Build(buildDict, 0));
                }

                beginNode.AddInput(hangingNodes.Count.ToString());
                beginNode.ConnectInput(hangingNodes.Count.ToString(), top);

                top = beginNode;
            }

            // make the anonymous function
            FScheme.Expression expression = Utils.MakeAnon(variables.Select(x => x.GUID.ToString()),
                                                           top.Compile());

            return(expression);
        }
예제 #9
0
        public FScheme.Expression Compile()
        {
            IEnumerable <string> inputNames  = null;
            IEnumerable <string> outputNames = null;

            // Get the internal nodes for the function
            WorkspaceModel functionWorkspace = this.WorkspaceModel;

            #region Find outputs

            // Find output elements for the node
            List <Output> outputs = functionWorkspace.Nodes.OfType <Output>().ToList();

            var topMost = new List <Tuple <int, NodeModel> >();

            // if we found output nodes, add select their inputs
            // these will serve as the function output
            if (outputs.Any())
            {
                topMost.AddRange(
                    outputs.Where(x => x.HasInput(0)).Select(x => x.Inputs[0]));

                outputNames = outputs.Select(x => x.Symbol);
            }
            else
            {
                // if there are no explicitly defined output nodes
                // get the top most nodes and set THEM as the output
                IEnumerable <NodeModel> topMostNodes = functionWorkspace.GetTopMostNodes();

                NodeModel infinite = null;

                var outNames = new List <string>();

                foreach (NodeModel topNode in topMostNodes)
                {
                    if (topNode is Function && (topNode as Function).Definition == this)
                    {
                        infinite = topNode;
                        continue;
                    }

                    foreach (int output in Enumerable.Range(0, topNode.OutPortData.Count))
                    {
                        if (!topNode.HasOutput(output))
                        {
                            topMost.Add(Tuple.Create(output, topNode));
                            outNames.Add(topNode.OutPortData[output].NickName);
                        }
                    }
                }

                if (infinite != null && outNames.Count == 0)
                {
                    topMost.Add(Tuple.Create(0, infinite));
                    outNames.Add("∞");
                }

                outputNames = outNames;
            }

            #endregion

            // color the node to define its connectivity
            foreach (var ele in topMost)
            {
                ele.Item2.ValidateConnections();
            }

            //Find function entry point, and then compile
            var variables = functionWorkspace.Nodes.OfType <Symbol>().ToList();
            inputNames = variables.Select(x => x.InputSymbol);

            //Update existing function nodes which point to this function to match its changes
            dynSettings.Controller.DynamoModel.AllNodes
            .OfType <Function>()
            .Where(el => el.Definition != null && el.Definition.FunctionId == this.FunctionId)
            .ToList()
            .ForEach(node =>
            {
                node.SetInputs(inputNames);
                node.SetOutputs(outputNames);
                node.RegisterAllPorts();
            });

            //Call OnSave for all saved elements
            functionWorkspace.Nodes.ToList().ForEach(x => x.onSave());

            INode top;
            var   buildDict = new Dictionary <NodeModel, Dictionary <int, INode> >();

            if (topMost.Count > 1)
            {
                InputNode node = new ExternalFunctionNode(FScheme.Value.NewList);

                int i = 0;
                foreach (var topNode in topMost)
                {
                    string inputName = i.ToString(CultureInfo.InvariantCulture);
                    node.AddInput(inputName);
                    node.ConnectInput(inputName, new BeginNode());
                    try
                    {
                        var exp = topNode.Item2.Build(buildDict, topNode.Item1);
                        node.ConnectInput(inputName, exp);
                    }
                    catch
                    {
                    }

                    i++;
                }

                top = node;
            }
            else if (topMost.Count == 1)
            {
                top = topMost[0].Item2.Build(buildDict, topMost[0].Item1);
            }
            else
            {
                // if the custom node is empty, it will initially be an empty begin
                top = new BeginNode();
            }

            // if the node has any outputs, we create a BeginNode in order to evaluate all of them
            // sequentially (begin evaluates a list of expressions)
            if (outputs.Any())
            {
                var beginNode = new BeginNode();
                List <NodeModel> hangingNodes = functionWorkspace.GetHangingNodes().ToList();

                foreach (var tNode in hangingNodes.Select((x, index) => new { Index = index, Node = x }))
                {
                    beginNode.AddInput(tNode.Index.ToString(CultureInfo.InvariantCulture));
                    beginNode.ConnectInput(
                        tNode.Index.ToString(CultureInfo.InvariantCulture),
                        tNode.Node.Build(buildDict, 0));
                }

                beginNode.AddInput(hangingNodes.Count.ToString(CultureInfo.InvariantCulture));
                beginNode.ConnectInput(hangingNodes.Count.ToString(CultureInfo.InvariantCulture), top);

                top = beginNode;
            }

            // make the anonymous function
            FScheme.Expression expression = Utils.MakeAnon(
                variables.Select(x => x.GUID.ToString()),
                top.Compile());

            return(expression);
        }
예제 #10
0
 /// <summary>
 /// Log an expression
 /// </summary>
 /// <param name="expression"></param>
 public void Log(FScheme.Expression expression)
 {
     Instance.Log(FScheme.printExpression("\t", expression), LogLevel.Console);
 }
예제 #11
0
        protected internal virtual void Run(bool runInDebug, IEnumerable <dynNodeModel> topElements, FScheme.Expression runningExpression)
        {
            //Print some stuff if we're in debug mode
            if (runInDebug)
            {
// NOPE
                //if (dynSettings.Bench != null)
                //{
                //    //string exp = FScheme.print(runningExpression);
                //    //dynSettings.Bench.Dispatcher.Invoke(new Action(
                //    //                            delegate
                //    //                            {
                //    //                                foreach (dynNodeModel node in topElements)
                //    //                                {
                //    //                                    string exp = node.PrintExpression();
                //    //                                    dynSettings.Controller.DynamoViewModel.Log("> " + exp);
                //    //                                }
                //    //                            }
                //    //                            ));
                //}
            }

            try
            {
                //Evaluate the expression
                FScheme.Value expr = this.FSchemeEnv.Evaluate(runningExpression);

                if (dynSettings.Bench != null)
                {
                    //Print some more stuff if we're in debug mode
                    if (runInDebug && expr != null)
                    {
// NOPE
                        //dynSettings.Bench.Dispatcher.Invoke(new Action(
                        //                            () =>
                        //                            dynSettings.Controller.DynamoViewModel.Log(FScheme.print(expr))
                        //                            ));
                    }
                }
            }
            catch (CancelEvaluationException ex)
            {
                /* Evaluation was cancelled */

                OnRunCancelled(false);
                //this.RunCancelled = false;
                if (ex.Force)
                {
                    runAgain = false;
                }
            }
            catch (Exception ex)
            {
                /* Evaluation failed due to error */
// NOPE
                //if (dynSettings.Bench != null)
                //{
                //    //Print unhandled exception
                //    if (ex.Message.Length > 0)
                //    {
                //        dynSettings.Bench.Dispatcher.Invoke(new Action(
                //                                    delegate { dynSettings.Controller.DynamoViewModel.Log(ex); }
                //                                    ));
                //    }
                //}

                OnRunCancelled(true);
                RunCancelled = true;
                runAgain     = false;
            }

            OnEvaluationCompleted();
        }
예제 #12
0
        protected virtual void EvaluationThread(object s, DoWorkEventArgs args)
        {
            /* Execution Thread */

            //Get our entry points (elements with nothing connected to output)
            IEnumerable <dynNodeModel> topElements = DynamoModel.HomeSpace.GetTopMostNodes();

            //Mark the topmost as dirty/clean
            foreach (dynNodeModel topMost in topElements)
            {
                topMost.MarkDirty();
            }

            //TODO: Flesh out error handling
            try
            {
                var topNode   = new BeginNode(new List <string>());
                var buildDict = new Dictionary <dynNodeModel, Dictionary <int, INode> >();
                foreach (var topMost in topElements.Select((node, index) => new { node, index }))
                {
                    string inputName = topMost.index.ToString();
                    topNode.AddInput(inputName);
                    topNode.ConnectInput(inputName, topMost.node.BuildExpression(buildDict));
                }

                FScheme.Expression runningExpression = topNode.Compile();

                Run(DynamoModel.RunInDebug, topElements, runningExpression);
            }
            catch (CancelEvaluationException ex)
            {
                /* Evaluation was cancelled */

                OnRunCancelled(false);
                //this.CancelRun = false; //Reset cancel flag
                RunCancelled = true;

                //If we are forcing this, then make sure we don't run again either.
                if (ex.Force)
                {
                    runAgain = false;
                }

                OnRunCompleted(this, false);
            }
            catch (Exception ex)
            {
                /* Evaluation has an error */

                //Catch unhandled exception
                if (ex.Message.Length > 0)
                {
                    dynSettings.Controller.DynamoViewModel.Log(ex);
                }

                OnRunCancelled(true);

                //Reset the flags
                runAgain     = false;
                RunCancelled = true;

                OnRunCompleted(this, false);
            }
            finally
            {
                /* Post-evaluation cleanup */

                DynamoModel.RunEnabled = true;

                //No longer running
                Running = false;

                foreach (FunctionDefinition def in dynSettings.FunctionWasEvaluated)
                {
                    def.RequiresRecalc = false;
                }

                //If we should run again...
                if (runAgain)
                {
                    //Reset flag
                    runAgain = false;

                    if (dynSettings.Bench != null)
                    {
                        //Run this method again from the main thread
                        dynSettings.Bench.Dispatcher.BeginInvoke(
                            new Action(() => RunExpression(_showErrors)));
                    }
                }
                else
                {
                    OnRunCompleted(this, true);
                }
            }
        }