예제 #1
0
        private void CompileToAstNodes(NodeModel node, List<AssociativeNode> resultList, CompilationContext context, bool verboseLogging)
        {

            var inputAstNodes = new List<AssociativeNode>();
            var inPortsCount = node.InPorts.Count;
            var inPortDataCount = node.InPortData.Count;

            //TODO: inputsCount should be removed in future. 
            // InPortData won't be used anymore, so we shouldn't take into account InPortData.Count.
            int inputsCount = inPortsCount > inPortDataCount ? inPortsCount : inPortDataCount;

            for (int index = 0; index < inputsCount; index++)
            {
                Tuple<int, NodeModel> inputTuple;

                if (node.TryGetInput(index, out inputTuple))
                {
                    int outputIndexOfInput = inputTuple.Item1;
                    NodeModel inputModel = inputTuple.Item2;
                    AssociativeNode inputNode = inputModel.GetAstIdentifierForOutputIndex(outputIndexOfInput);

#if DEBUG
                    Validity.Assert(inputNode != null,
                        "Shouldn't have null nodes in the AST list");
#endif
                    inputAstNodes.Add(inputNode);
                }
                else
                {
                    if (node.InPorts.Count > index)
                    {
                        var port = node.InPorts[index];
                        if (port.UsingDefaultValue && port.DefaultValueEnabled)
                        {
                            inputAstNodes.Add(port.DefaultValue);
                        }
                        else
                        {
                            inputAstNodes.Add(new NullNode());
                        }
                    }
                    else
                    {
                        Log("Node does not have InPortData at the requested index.");
                    }
                }
            }

            //TODO: This should do something more than just log a generic message. --SJE
            if (node.State == ElementState.Error)
                Log("Error in Node. Not sent for building and compiling");

            if (context == CompilationContext.DeltaExecution || context == CompilationContext.PreviewGraph)
                OnAstNodeBuilding(node.GUID);

#if DEBUG
            Validity.Assert(inputAstNodes.All(n => n != null), 
                "Shouldn't have null nodes in the AST list");
#endif

            var scopedNode = node as ScopedNodeModel;
            IEnumerable<AssociativeNode> astNodes = 
                scopedNode != null
                    ? scopedNode.BuildAstInScope(inputAstNodes, verboseLogging, this)
                    : node.BuildAst(inputAstNodes, context);

            if (verboseLogging)
            {
                foreach (var n in astNodes)
                {
                    Log(n.ToString());
                }
            }

            if(null == astNodes)
                resultList.AddRange(new AssociativeNode[0]);
            else if (context == CompilationContext.DeltaExecution || context == CompilationContext.PreviewGraph)
            {
                OnAstNodeBuilt(node.GUID, astNodes);
                resultList.AddRange(astNodes);
            }
            else if (context == CompilationContext.NodeToCode)
            {
                resultList.AddRange(astNodes);
            }
            else //Inside custom node compilation.
            {
                bool notified = false;
                foreach (var item in astNodes)
                {
                    if (item is FunctionDefinitionNode)
                    {
                        if (!notified)
                            OnAstNodeBuilding(node.GUID);
                        notified = true;
                        //Register the function node in global scope with Graph Sync data,
                        //so that we don't have a function definition inside the function def
                        //of custom node.
                        OnAstNodeBuilt(node.GUID, new[] { item });
                    }
                    else
                        resultList.Add(item);
                }
            }
        }
예제 #2
0
        private void _CompileToAstNodes(NodeModel node, List<AssociativeNode> resultList, bool isDeltaExecution)
        {

            var inputAstNodes = new List<AssociativeNode>();
            foreach (int index in Enumerable.Range(0, node.InPortData.Count))
            {
                Tuple<int, NodeModel> inputTuple;

                if (node.TryGetInput(index, out inputTuple))
                {
                    int outputIndexOfInput = inputTuple.Item1;
                    NodeModel inputModel = inputTuple.Item2;
                    AssociativeNode inputNode = inputModel.GetAstIdentifierForOutputIndex(outputIndexOfInput);

#if DEBUG
                    Validity.Assert(inputNode != null,
                        "Shouldn't have null nodes in the AST list");
#endif
                    inputAstNodes.Add(inputNode);
                }
                else
                {
                    PortData port = node.InPortData[index];
                    inputAstNodes.Add(
                        port.HasDefaultValue
                            ? AstFactory.BuildPrimitiveNodeFromObject(port.DefaultValue)
                            : new NullNode());
                }
            }

            //TODO: This should do something more than just log a generic message. --SJE
            if (node.State == ElementState.Error)
                dynSettings.DynamoLogger.Log("Error in Node. Not sent for building and compiling");

            if (isDeltaExecution)
                OnAstNodeBuilding(node.GUID);

#if DEBUG
            Validity.Assert(!inputAstNodes.Any((n) => n == null), 
                "Shouldn't have null nodes in the AST list");
#endif

            IEnumerable<AssociativeNode> astNodes = node.BuildAst(inputAstNodes);
            
            if (dynSettings.Controller.DebugSettings.VerboseLogging)
            {
                foreach (var n in astNodes)
                {
                    dynSettings.DynamoLogger.Log(n.ToString());
                }
            }

            if(null == astNodes)
                resultList.AddRange(new AssociativeNode[0]);
            else if (isDeltaExecution)
            {
                OnAstNodeBuilt(node.GUID, astNodes);
                resultList.AddRange(astNodes);
            }
            else //Inside custom node compilation.
            {
                bool notified = false;
                foreach (var item in astNodes)
                {
                    if (item is FunctionDefinitionNode)
                    {
                        if (!notified)
                            OnAstNodeBuilding(node.GUID);
                        notified = true;
                        //Register the function node in global scope with Graph Sync data,
                        //so that we don't have a function definition inside the function def
                        //of custom node.
                        OnAstNodeBuilt(node.GUID, new AssociativeNode[] { item });
                    }
                    else
                        resultList.Add(item);
                }
            }
        }
예제 #3
0
        /// <summary>
        /// Starts from the input node as root, do breadth-first and post-order
        /// traversal of the graph (inputs nodes as children nodes). Breadth-first
        /// traversal ensures all inputs nodes are visited in their input order 
        /// and post-order traversal ensures all upstream nodes are visited 
        /// firstly. 
        /// </summary>
        /// <param name="node">Root node</param>
        /// <param name="nodeFlags">Dictionary to record if a node has been visited or not</param>
        /// <param name="sortedNodes">Record all visited nodes</param>
        private static void BfsTraverse(
            NodeModel node, 
            Dictionary<NodeModel, MarkFlag> nodeFlags, 
            Queue<NodeModel> sortedNodes)
        {
            MarkFlag flag;
            if (!nodeFlags.TryGetValue(node, out flag))
            {
                flag = MarkFlag.NoMark;
                nodeFlags[node] = flag;
            }

            if (flag != MarkFlag.NoMark)
                return;

            nodeFlags[node] = MarkFlag.TempMark;

            for (int i = 0; i < node.InPortData.Count; ++i)
            {
                Tuple<int, NodeModel> t;
                if (!node.TryGetInput(i, out t))
                    continue;

                BfsTraverse(t.Item2, nodeFlags, sortedNodes);
            }

            sortedNodes.Enqueue(node);
            nodeFlags[node] = MarkFlag.Marked;
        }