Example #1
0
        internal static void ConvertNodesToCodeInternal(this WorkspaceModel workspace, EngineController engineController,
                                                        INamingProvider namingProvider)
        {
            var selectedNodes = DynamoSelection.Instance
                                .Selection
                                .OfType <NodeModel>()
                                .Where(n => n.IsConvertible);

            if (!selectedNodes.Any())
            {
                return;
            }

            var cliques        = NodeToCodeCompiler.GetCliques(selectedNodes).Where(c => !(c.Count == 1 && c.First() is CodeBlockNodeModel));
            var codeBlockNodes = new List <CodeBlockNodeModel>();

            //UndoRedo Action Group----------------------------------------------
            NodeToCodeUndoHelper undoHelper = new NodeToCodeUndoHelper();

            foreach (var nodeList in cliques)
            {
                //Create two dictionarys to store the details of the external connections that have to
                //be recreated after the conversion
                var externalInputConnections  = new Dictionary <ConnectorModel, string>();
                var externalOutputConnections = new Dictionary <ConnectorModel, string>();

                //Also collect the average X and Y co-ordinates of the different nodes
                int nodeCount = nodeList.Count;

                var nodeToCodeResult = engineController.ConvertNodesToCode(workspace.Nodes, nodeList, namingProvider);

                #region Step I. Delete all nodes and their connections

                double totalX = 0, totalY = 0;

                foreach (var node in nodeList)
                {
                    #region Step I.A. Delete the connections for the node

                    foreach (var connector in node.AllConnectors.ToList())
                    {
                        if (!IsInternalNodeToCodeConnection(nodeList, connector))
                        {
                            //If the connector is an external connector, the save its details
                            //for recreation later
                            var startNode = connector.Start.Owner;
                            int index     = startNode.OutPorts.IndexOf(connector.Start);
                            //We use the varibleName as the connection between the port of the old Node
                            //to the port of the new node.
                            var variableName = startNode.GetAstIdentifierForOutputIndex(index).Value;

                            //Store the data in the corresponding dictionary
                            if (startNode == node)
                            {
                                if (nodeToCodeResult.OutputMap.ContainsKey(variableName))
                                {
                                    variableName = nodeToCodeResult.OutputMap[variableName];
                                }
                                externalOutputConnections.Add(connector, variableName);
                            }
                            else
                            {
                                if (nodeToCodeResult.InputMap.ContainsKey(variableName))
                                {
                                    variableName = nodeToCodeResult.InputMap[variableName];
                                }
                                externalInputConnections.Add(connector, variableName);
                            }
                        }

                        //Delete the connector
                        undoHelper.RecordDeletion(connector);
                        connector.Delete();
                    }
                    #endregion

                    #region Step I.B. Delete the node
                    totalX += node.X;
                    totalY += node.Y;
                    undoHelper.RecordDeletion(node);
                    workspace.RemoveAndDisposeNode(node);
                    #endregion
                }
                #endregion

                #region Step II. Create the new code block node
                var outputVariables = externalOutputConnections.Values;
                var newResult       = NodeToCodeCompiler.ConstantPropagationForTemp(nodeToCodeResult, outputVariables);

                // Rewrite the AST using the shortest unique name in case of namespace conflicts
                NodeToCodeCompiler.ReplaceWithShortestQualifiedName(
                    engineController.LibraryServices.LibraryManagementCore.ClassTable, newResult.AstNodes, workspace.ElementResolver);
                var codegen = new ProtoCore.CodeGenDS(newResult.AstNodes);
                var code    = codegen.GenerateCode();

                var codeBlockNode = new CodeBlockNodeModel(
                    code,
                    System.Guid.NewGuid(),
                    totalX / nodeCount,
                    totalY / nodeCount, engineController.LibraryServices, workspace.ElementResolver);
                undoHelper.RecordCreation(codeBlockNode);

                workspace.AddAndRegisterNode(codeBlockNode, false);
                codeBlockNodes.Add(codeBlockNode);
                #endregion

                #region Step III. Recreate the necessary connections
                var newInputConnectors = ReConnectInputConnections(externalInputConnections, codeBlockNode, workspace);
                foreach (var connector in newInputConnectors)
                {
                    undoHelper.RecordCreation(connector);
                }

                var newOutputConnectors = ReConnectOutputConnections(externalOutputConnections, codeBlockNode);
                foreach (var connector in newOutputConnectors)
                {
                    undoHelper.RecordCreation(connector);
                }
                #endregion
            }

            undoHelper.ApplyActions(workspace.UndoRecorder);

            DynamoSelection.Instance.ClearSelection();
            DynamoSelection.Instance.Selection.AddRange(codeBlockNodes);

            Debug.WriteLine(string.Format("Workspace has {0} nodes and {1} connectors after N2C operation.", workspace.Nodes.Count(), workspace.Connectors.Count()));
            workspace.RequestRun();
        }
Example #2
0
        internal void ConvertNodesToCodeInternal(Guid nodeId, EngineController engineController, bool verboseLogging)
        {
            IEnumerable <NodeModel> selectedNodes =
                DynamoSelection.Instance.Selection.OfType <NodeModel>().Where(n => n.IsConvertible);

            if (!selectedNodes.Any())
            {
                return;
            }

            Dictionary <string, string> variableNameMap;
            string code = engineController.ConvertNodesToCode(selectedNodes, out variableNameMap, verboseLogging);

            CodeBlockNodeModel codeBlockNode;

            //UndoRedo Action Group----------------------------------------------
            using (UndoRecorder.BeginActionGroup())
            {
                #region Step I. Delete all nodes and their connections
                //Create two dictionarys to store the details of the external connections that have to
                //be recreated after the conversion
                var externalInputConnections  = new Dictionary <ConnectorModel, string>();
                var externalOutputConnections = new Dictionary <ConnectorModel, string>();

                //Also collect the average X and Y co-ordinates of the different nodes
                var    nodeList = selectedNodes.ToList();
                int    nodeCount = nodeList.Count;
                double totalX = 0, totalY = 0;

                foreach (var node in nodeList)
                {
                    #region Step I.A. Delete the connections for the node

                    foreach (var connector in node.AllConnectors.ToList())
                    {
                        if (!IsInternalNodeToCodeConnection(connector))
                        {
                            //If the connector is an external connector, the save its details
                            //for recreation later
                            var startNode = connector.Start.Owner;
                            int index     = startNode.OutPorts.IndexOf(connector.Start);
                            //We use the varibleName as the connection between the port of the old Node
                            //to the port of the new node.
                            var variableName = startNode.GetAstIdentifierForOutputIndex(index).Value;
                            if (variableNameMap.ContainsKey(variableName))
                            {
                                variableName = variableNameMap[variableName];
                            }

                            //Store the data in the corresponding dictionary
                            if (startNode == node)
                            {
                                externalOutputConnections.Add(connector, variableName);
                            }
                            else
                            {
                                externalInputConnections.Add(connector, variableName);
                            }
                        }

                        //Delete the connector
                        UndoRecorder.RecordDeletionForUndo(connector);
                        connector.Delete();
                    }
                    #endregion

                    #region Step I.B. Delete the node
                    totalX += node.X;
                    totalY += node.Y;
                    UndoRecorder.RecordDeletionForUndo(node);
                    Nodes.Remove(node);
                    #endregion
                }
                #endregion

                #region Step II. Create the new code block node
                codeBlockNode = new CodeBlockNodeModel(
                    code,
                    nodeId,
                    totalX / nodeCount,
                    totalY / nodeCount, engineController.LibraryServices);
                UndoRecorder.RecordCreationForUndo(codeBlockNode);
                Nodes.Add(codeBlockNode);
                #endregion

                #region Step III. Recreate the necessary connections
                ReConnectInputConnections(externalInputConnections, codeBlockNode);
                ReConnectOutputConnections(externalOutputConnections, codeBlockNode);
                #endregion
            }
            //End UndoRedo Action Group------------------------------------------

            // select node

            DynamoSelection.Instance.ClearSelection();
            DynamoSelection.Instance.Selection.Add(codeBlockNode);

            OnAstUpdated();
        }