/// <summary> /// Clones this instance. /// </summary> /// <returns></returns> public override ExperimentNode Clone() { var clone = new ExperimentDecisionNode(); clone.CopyFrom(this); return(clone); }
/// <summary> /// Performs operation of adding the new scope to the given decision. /// </summary> /// <param name="sender">The sender.</param> /// <param name="e">The <see cref="System.Windows.Input.ExecutedRoutedEventArgs"/> instance containing the event data.</param> protected void ExecuteAddScopeToDecision(object sender, ExecutedRoutedEventArgs e) { GraphSharp.Controls.VertexControl vertexControl = e.Parameter as GraphSharp.Controls.VertexControl; if (vertexControl != null) { ExperimentDecisionNode decisionNode = vertexControl.Vertex as ExperimentDecisionNode; if (decisionNode != null) { ExitDecisionNode exitDecisionNode = null; IEditableExperiment experiment = decisionNode.Owner as IEditableExperiment; double rightmostX = decisionNode.Data.X; HashSet <string> currentLabels = new HashSet <string>(); //iterate through outgoing scopes and find the scope with right border located most to the right among all scopes //also locate among outgoing edges reference to exit IEnumerable <ExperimentNodeConnection> outEdges; if (experiment.TryGetOutEdges(decisionNode, out outEdges)) { foreach (ExperimentNodeConnection connection in outEdges) { ScopeNode scope = connection.Target as ScopeNode; if (scope != null) { double candidateRightMostX = scope.DataWithSize.X + scope.DataWithSize.Width / 2; if (candidateRightMostX > rightmostX) { rightmostX = candidateRightMostX; } //also collect labels currentLabels.Add(scope.Data.Metadata.Label); } else if (exitDecisionNode == null) { //try find exit decision node exitDecisionNode = connection.Target as ExitDecisionNode; } } } double xPosition = rightmostX + 100; double yPosition = decisionNode.Data.Y + 120; string finalLabel = DetermineNewScopeLabel(currentLabels); //check if deicion node is not null. In old decision nodes without scopes, there were no associated exit node, //thus the scope cannot be added for these decisions. if (exitDecisionNode != null) { ComponentFactory.AddScopeToDecision(finalLabel, xPosition, yPosition, decisionNode, exitDecisionNode, experiment); } } } }
/// <summary> /// Adds a new decision node at the specified coordinates /// </summary> public ExperimentDecisionNode AddDecisionToExperiment(Experiment experiment, double positionX, double positionY) { ExperimentDecisionNode newNode = null; SerializedVertexData data = new SerializedVertexData(); data.X = positionX; data.Y = positionY; data.Metadata = new DecisionMetadata("Decision"); newNode = new ExperimentDecisionNode(Guid.NewGuid().ToString(), data); experiment.AddVertex(newNode); return(newNode); }
/// <summary> /// Determines whether the given decision is an old version decision. /// Previously decisions were independent nodes without scopes and corresponding exit node. /// Thus for old decisions we want to choose another template. /// </summary> /// <param name="decisionNode">The decision node.</param> /// <returns> /// <c>true</c> if the specified decision node is old decision; otherwise, <c>false</c>. /// </returns> private static bool IsGotoDecision(ExperimentDecisionNode decisionNode) { IEditableExperiment experiment = decisionNode.Owner as IEditableExperiment; IEnumerable <ExperimentNodeConnection> outEdges; if (experiment.TryGetOutEdges(decisionNode, out outEdges)) { foreach (ExperimentNodeConnection connection in outEdges) { if (connection.Target is ExitDecisionNode) { return(false); } } } return(true); }
/// <summary> /// Compiles the code of the single decision node or loop scope node. It handles DecisionNode and LoopScopeNode slightly differently. /// Method. /// </summary> /// <param name="node">The node.</param> /// <param name="experiment">The experiment.</param> /// <param name="workspaceTypesDirectories">The workspace types directories.</param> /// <param name="loggerNameRoot">The logger name root.</param> public static void CompileDecision(ExperimentNode node, IExperiment experiment, List <string> workspaceTypesDirectories, LoggerNameRoot loggerNameRoot) { ExperimentDecisionNode decisionNode = node as ExperimentDecisionNode; if (decisionNode != null) { Dictionary <string, string> successorNodeLabelIdLookup = PrepareSuccessorNodesLabelIdLookup(node, experiment); CompileDecisionInternal(decisionNode, experiment, workspaceTypesDirectories, loggerNameRoot, successorNodeLabelIdLookup); } else { LoopScopeNode loopScopeNode = node as LoopScopeNode; if (loopScopeNode != null) { //loop scope does not need successor nodes lookups, so pass in empty dictionary Dictionary <string, string> successorNodeLabelIdLookup = new Dictionary <string, string>(); CompileDecisionInternal(loopScopeNode, experiment, workspaceTypesDirectories, loggerNameRoot, successorNodeLabelIdLookup); } } }
/// <summary> /// Clones this instance. /// </summary> /// <returns></returns> public override ExperimentNode Clone() { var clone = new ExperimentDecisionNode(); clone.CopyFrom(this); return clone; }
/// <summary> /// Selects the template based on the given vertex control type /// </summary> /// <param name="item">The data object for which to select the template.</param> /// <param name="container">The data-bound object.</param> /// <returns> /// Returns a <see cref="T:System.Windows.DataTemplate"/> or null. The default value is null. /// </returns> public override DataTemplate SelectTemplate(object item, DependencyObject container) { var control = container as FrameworkElement; var node = item as VertexControl; DataTemplate template = null; if (control != null) { if (node != null) { if (node.Vertex is TraceLab.Core.Experiments.ExperimentStartNode) { template = (DataTemplate)control.TryFindResource("StartNodeControl"); } else if (node.Vertex is TraceLab.Core.Experiments.ExperimentEndNode) { template = (DataTemplate)control.TryFindResource("EndNodeControl"); } else if (node.Vertex is TraceLab.Core.Experiments.ComponentNode) { template = (DataTemplate)control.TryFindResource("ComponentNodeControl"); } else if (node.Vertex is TraceLab.Core.Experiments.ExperimentDecisionNode) { ExperimentDecisionNode decisionNode = (ExperimentDecisionNode)node.Vertex; if (IsGotoDecision(decisionNode)) { template = (DataTemplate)control.TryFindResource("GotoDecisionNodeControl"); } else { template = (DataTemplate)control.TryFindResource("DecisionNodeControl"); } } else if (node.Vertex is TraceLab.Core.Experiments.ScopeNode) { //scope node must be checked before CompositeComponentNode, as it extends CompositeComponentNode template = (DataTemplate)control.TryFindResource("ScopeNodeControl"); } else if (node.Vertex is TraceLab.Core.Experiments.LoopScopeNode) { template = (DataTemplate)control.TryFindResource("LoopScopeNodeControl"); } else if (node.Vertex is TraceLab.Core.Experiments.CompositeComponentNode) { template = (DataTemplate)control.TryFindResource("CompositeComponentNodeControl"); } else if (node.Vertex is TraceLab.Core.Experiments.ExitDecisionNode) { template = (DataTemplate)control.TryFindResource("ExitDecisionNodeControl"); } } if (template == null) { template = (DataTemplate)control.TryFindResource("DefaultNodeControl"); } } return(template); }
/// <summary> /// If the given decision node is not null, the method updates its code by replacing templateNodeLabel with replacementNodeLabel /// of all Select(" label ") statements in the decision code. /// </summary> /// <param name="templateNodeLabel">The template node label.</param> /// <param name="replacementNodeLabel">The replacement node label.</param> /// <param name="decisionNode">The decision node.</param> private static void FixDecisionCode(string templateNodeLabel, string replacementNodeLabel, ExperimentDecisionNode decisionNode) { if (decisionNode != null) { string decisionCode = ((DecisionMetadata)decisionNode.Data.Metadata).DecisionCode; string selectStatementOldLabel = string.Format("Select(\"{0}\")", templateNodeLabel); if (decisionCode.Contains(selectStatementOldLabel)) { //replace old label with new label of Select("...") statements; string selectStatementNewLabel = string.Format("Select(\"{0}\")", replacementNodeLabel); decisionCode = decisionCode.Replace(selectStatementOldLabel, selectStatementNewLabel); ((DecisionMetadata)decisionNode.Data.Metadata).DecisionCode = decisionCode; } } }