protected override bool UpdateValueCore(string name, string value, UndoRedoRecorder recorder) { if (name != "Code") { return(base.UpdateValueCore(name, value, recorder)); } //Remove the UpdateValue's recording recorder.PopFromUndoGroup(); value = CodeBlockUtils.FormatUserText(value); //Since an empty Code Block Node should not exist, this checks for such instances. // If an empty Code Block Node is found, it is deleted. Since the creation and deletion of // an empty Code Block Node should not be recorded, this method also checks and removes // any unwanted recordings if (value == "") { Code = ""; } else { if (!value.Equals(Code)) { SetCodeContent(value, recorder); } } return(true); }
protected override bool UpdateValueCore(UpdateValueParams updateValueParams) { string name = updateValueParams.PropertyName; string value = updateValueParams.PropertyValue; ElementResolver workspaceElementResolver = updateValueParams.ElementResolver; if (name != "Code") { return(base.UpdateValueCore(updateValueParams)); } value = CodeBlockUtils.FormatUserText(value); //Since an empty Code Block Node should not exist, this checks for such instances. // If an empty Code Block Node is found, it is deleted. Since the creation and deletion of // an empty Code Block Node should not be recorded, this method also checks and removes // any unwanted recordings if (value == "") { Code = ""; } else { if (!value.Equals(Code)) { SetCodeContent(value, workspaceElementResolver); } } return(true); }
private Statement GetStatementForOutput(int portIndex) { if (State == ElementState.Error) { return(null); } // Here the "portIndex" is back mapped to the corresponding "Statement" // object. However, not all "Statement" objects produce an output port, // so "portIndex" cannot be used directly to index into "codeStatements" // list. This loop goes through "codeStatements", decrementing "portIndex" // along the way to determine the right "Statement" object matching the // port index. // Statement statement = null; var svs = CodeBlockUtils.GetStatementVariables(codeStatements, true); for (int stmt = 0, port = 0; stmt < codeStatements.Count; stmt++) { if (CodeBlockUtils.DoesStatementRequireOutputPort(svs, stmt)) { if (port == portIndex) { statement = codeStatements[stmt]; break; } port = port + 1; } } return(statement); }
private void SetInputPorts() { // Generate input port data list from the unbound identifiers. var inportData = CodeBlockUtils.GenerateInputPortData(inputIdentifiers); foreach (var portData in inportData) { InPortData.Add(portData); } }
/// <summary> /// For code block nodes, each output identifier of an output port is mapped. /// For an example, "p = 1" would have its internal identifier renamed to /// "pXXXX", where "XXXX" is the GUID of the code block node. This mapping is /// done to ensure the uniqueness of the output variable name. /// </summary> /// <param name="portIndex">Output port index</param> /// <param name="forRawName">Set this parameter to true to retrieve the /// original identifier name "p". If this parameter is false, the mapped /// identifer name "pXXXX" is returned instead.</param> /// <returns></returns> private IdentifierNode GetAstIdentifierForOutputIndexInternal(int portIndex, bool forRawName) { if (State == ElementState.Error) { return(null); } // Here the "portIndex" is back mapped to the corresponding "Statement" // object. However, not all "Statement" objects produce an output port, // so "portIndex" cannot be used directly to index into "codeStatements" // list. This loop goes through "codeStatements", decrementing "portIndex" // along the way to determine the right "Statement" object matching the // port index. // Statement statement = null; var svs = CodeBlockUtils.GetStatementVariables(codeStatements, true); for (int stmt = 0, port = 0; stmt < codeStatements.Count; stmt++) { if (CodeBlockUtils.DoesStatementRequireOutputPort(svs, stmt)) { if (port == portIndex) { statement = codeStatements[stmt]; break; } port = port + 1; } } if (statement == null) { return(null); } var binExprNode = statement.AstNode as BinaryExpressionNode; if (binExprNode == null || (binExprNode.LeftNode == null)) { return(null); } var identNode = binExprNode.LeftNode as IdentifierNode; var mappedIdent = NodeUtils.Clone(identNode); if (!forRawName) { MapIdentifiers(mappedIdent); } return(mappedIdent as IdentifierNode); }
protected override void DeserializeCore(XmlElement nodeElement, SaveContext context) { base.DeserializeCore(nodeElement, context); var helper = new XmlElementHelper(nodeElement); shouldFocus = helper.ReadBoolean("ShouldFocus"); code = helper.ReadString("CodeText"); // Lookup namespace resolution map if available and initialize new instance of ElementResolver var resolutionMap = CodeBlockUtils.DeserializeElementResolver(nodeElement); ElementResolver = new ElementResolver(resolutionMap); ProcessCodeDirect(); }
protected override void DeserializeCore(XmlElement nodeElement, SaveContext context) { base.DeserializeCore(nodeElement, context); foreach (var subNode in nodeElement.ChildNodes.Cast <XmlNode>() .Where(subNode => subNode.Name == "Symbol")) { InputSymbol = subNode.Attributes[0].Value; } ArgumentLacing = LacingStrategy.Disabled; var resolutionMap = CodeBlockUtils.DeserializeElementResolver(nodeElement); elementResolver = new ElementResolver(resolutionMap); }
/// <summary> /// Returns the corresponding output port index for a given defined variable /// </summary> /// <param name="variableName"></param> /// <returns></returns> public int GetOutportIndex(string variableName) { var svs = CodeBlockUtils.GetStatementVariables(codeStatements, true); for (int i = 0; i < codeStatements.Count; i++) { Statement s = codeStatements[i]; if (CodeBlockUtils.DoesStatementRequireOutputPort(svs, i)) { List <string> varNames = Statement.GetDefinedVariableNames(s, true); if (varNames.Contains(variableName)) { return(i); } } } return(-1); }
protected override bool UpdateValueCore(string name, string value) { if (name == "Code") { //Remove the UpdateValue's recording this.Workspace.UndoRecorder.PopFromUndoGroup(); //Since an empty Code Block Node should not exist, this checks for such instances. // If an empty Code Block Node is found, it is deleted. Since the creation and deletion of // an empty Code Block Node should not be recorded, this method also checks and removes // any unwanted recordings value = CodeBlockUtils.FormatUserText(value); if (value == "") { if (this.Code == "") { this.Workspace.UndoRecorder.PopFromUndoGroup(); Dynamo.Selection.DynamoSelection.Instance.Selection.Remove(this); this.Workspace.Nodes.Remove(this); } else { this.Workspace.RecordAndDeleteModels(new System.Collections.Generic.List <ModelBase>() { this }); } } else { if (!value.Equals(this.Code)) { Code = value; } } return(true); } return(base.UpdateValueCore(name, value)); }
private void SetOutputPorts() { var allDefs = CodeBlockUtils.GetDefinitionLineIndexMap(codeStatements); if (allDefs.Any() == false) { return; } double prevPortBottom = 0.0; foreach (var def in allDefs) { var logicalIndex = def.Value - 1; string tooltip = def.Key; if (tempVariables.Contains(def.Key)) { tooltip = Formatting.TOOL_TIP_FOR_TEMP_VARIABLE; } double portCoordsY = Formatting.INITIAL_MARGIN; portCoordsY += logicalIndex * Configurations.CodeBlockPortHeightInPixels; OutPortData.Add(new PortData(string.Empty, tooltip) { VerticalMargin = portCoordsY - prevPortBottom, Height = Configurations.CodeBlockPortHeightInPixels }); // Since we compute the "delta" between the top of the current // port to the bottom of the previous port, we need to record // down the bottom coordinate value before proceeding to the next // port. // prevPortBottom = portCoordsY + Configurations.CodeBlockPortHeightInPixels; } }
private void SetOutputPorts() { var allDefs = CodeBlockUtils.GetDefinitionLineIndexMap(codeStatements); if (allDefs.Any() == false) { return; } foreach (var def in allDefs) { string tooltip = def.Key; if (tempVariables.Contains(def.Key)) { tooltip = Formatting.TOOL_TIP_FOR_TEMP_VARIABLE; } OutPortData.Add(new PortData(string.Empty, tooltip) { LineIndex = def.Value - 1, // Logical line index. Height = Configurations.CodeBlockPortHeightInPixels }); } }
private void SetOutputPorts() { // Get all defined variables and their locations var definedVars = codeStatements.Select(s => new KeyValuePair <Variable, int>(s.FirstDefinedVariable, s.StartLine)) .Where(pair => pair.Key != null) .Select(pair => new KeyValuePair <string, int>(pair.Key.Name, pair.Value)) .OrderBy(pair => pair.Key) .GroupBy(pair => pair.Key); // Calc each variable's last location of definition var locationMap = new Dictionary <string, int>(); foreach (var defs in definedVars) { var name = defs.FirstOrDefault().Key; var loc = defs.Select(p => p.Value).Max <int>(); locationMap[name] = loc; } // Create output ports var allDefs = locationMap.OrderBy(p => p.Value); if (allDefs.Any() == false) { return; } double prevPortBottom = 0.0; var map = CodeBlockUtils.MapLogicalToVisualLineIndices(code); foreach (var def in allDefs) { // Map the given logical line index to its corresponding visual // line index. Do note that "def.Value" here is the line number // supplied by the paser, which uses 1-based line indexing so we // have to remove one from the line index. // var logicalIndex = def.Value - 1; var visualIndex = map.ElementAt(logicalIndex); string tooltip = def.Key; if (tempVariables.Contains(def.Key)) { tooltip = Formatting.TOOL_TIP_FOR_TEMP_VARIABLE; } double portCoordsY = Formatting.INITIAL_MARGIN; portCoordsY += visualIndex * Configurations.CodeBlockPortHeightInPixels; OutPortData.Add(new PortData(string.Empty, tooltip) { VerticalMargin = portCoordsY - prevPortBottom, Height = Configurations.CodeBlockPortHeightInPixels }); // Since we compute the "delta" between the top of the current // port to the bottom of the previous port, we need to record // down the bottom coordinate value before proceeding to the next // port. // prevPortBottom = portCoordsY + Configurations.CodeBlockPortHeightInPixels; } }
private void ProcessCode(ref string errorMessage, ref string warningMessage) { code = CodeBlockUtils.FormatUserText(code); codeStatements.Clear(); if (string.IsNullOrEmpty(Code)) { previewVariable = null; } try { var parseParam = new ParseParam(GUID, code); if (CompilerUtils.PreCompileCodeBlock(libraryServices.LibraryManagementCore, ref parseParam)) { if (parseParam.ParsedNodes != null) { // Create an instance of statement for each code statement written by the user foreach (var parsedNode in parseParam.ParsedNodes) { // Create a statement variable from the generated nodes codeStatements.Add(Statement.CreateInstance(parsedNode)); } SetPreviewVariable(parseParam.ParsedNodes); } } if (parseParam.Errors != null && parseParam.Errors.Any()) { errorMessage = string.Join("\n", parseParam.Errors.Select(m => m.Message)); ProcessError(); CreateInputOutputPorts(); return; } if (parseParam.Warnings != null) { // Unbound identifiers in CBN will have input slots. // // To check function redefinition, we need to check other // CBN to find out if it has been defined yet. Now just // skip this warning. var warnings = parseParam.Warnings.Where( w => w.ID != WarningID.kIdUnboundIdentifier && w.ID != WarningID.kFunctionAlreadyDefined); if (warnings.Any()) { warningMessage = string.Join("\n", warnings.Select(m => m.Message)); } } if (parseParam.UnboundIdentifiers != null) { inputIdentifiers = new List <string>(parseParam.UnboundIdentifiers); } else { inputIdentifiers.Clear(); } } catch (Exception e) { errorMessage = e.Message; previewVariable = null; ProcessError(); return; } // Set the input and output ports based on the statements CreateInputOutputPorts(); }