/// <summary> /// Guarda una actividad a disco. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void saveActivityMenuItem_Click(object sender, EventArgs e) { try { if (lstActivities.SelectedIndex != -1) { if (sdlgExportActivity.ShowDialog() == DialogResult.OK) { IFormatter formatter = new BinaryFormatter(); Stream stream = new FileStream(sdlgExportActivity.FileName, FileMode.Create, FileAccess.Write, FileShare.None); string activityName = lstActivities.SelectedItem.ToString(); ChartElementCollection activity = AlgorithmListDict[activityName]; var activityWithName = new KeyValuePair <string, ChartElementCollection>(activityName, activity); formatter.Serialize(stream, activityWithName); stream.Close(); UpdateActivityBuilder(); } } } catch (Exception ex) { MessageBox.Show("Error saving activity. Error message is: " + ex.Message); } }
private Thread t; // Hilo separado para ejecutar el interprete de instrucciones. #endregion Fields #region Constructors public FormMain() { InitializeComponent(); ChartElementCollection defaultAlgorithm = new ChartElementCollection(); algorithmList.Add("Main", defaultAlgorithm); CheckForIllegalCrossThreadCalls = false; // Esto permite modificar objetos creados en otro hilo de forma sencilla (suprime). }
public FormMain() { InitializeComponent(); ChartElementCollection defaultAlgorithm = new ChartElementCollection(); algorithmList.Add("Main", defaultAlgorithm); CheckForIllegalCrossThreadCalls = false; // Esto permite modificar objetos creados en otro hilo de forma sencilla (suprime). }
/// <summary> /// Inicializa el control. /// </summary> public FlowChartViewer() { InitializeComponent(); // El metodo SetStyle permite configurar aspectos de la ejecucion de un control en los momentos de visualizacion e interaccion. SetStyle(ControlStyles.OptimizedDoubleBuffer, true); // determina que se debe utilizar doble buffer para evitar el parpadeo durante las animaciones. SetStyle(ControlStyles.UserPaint, true); // determina que se debe disparar el evento Paint. SetStyle(ControlStyles.AllPaintingInWmPaint, true); // determina que todo el pintado sera establecido en el metodo OnPaint por lo que no se borra el fondo y evita parpadeo. // se crea una coleccion para almacenar los elementos del diagrama. this._Charts = new ChartElementCollection(); // se suscribe al evento que notifica el cambio en la coleccion y esto permite refrescar visualmente el control a cualquiera de estos cambios. //Charts.CollectionChanged += new EventHandler(Charts_CollectionChanged); AutoScroll = true; }
/// <summary> /// Cambia el ChartElementCollection a mostrar. /// </summary> /// <param name="charts">La coleccion de charts a mostrar.</param> public void ChangeCurrentChartCollection(ChartElementCollection charts) { this._Charts = charts; this.Invalidate(); }
/// <summary> /// Ejecuta un algoritmo determinado, dado por un ChartElementCollection. /// </summary> /// <param name="instructionCollection">El conjunto de instrucciones a ejecutar.</param> public void ExecuteAlgorithm(ChartElementCollection instructionCollection) { ChartElement current = null; try { ChartElement first = instructionCollection.First; // Obtiene el elemento "Begin" si existe. if (first == null || first.Connections == null) throw new Exception("Invalid algorithm to execute."); // Si no existe el "Begin", el algoritmo no es valido. foreach (var connection in first.Connections) if (connection.To != null) current = connection.To.ChartElement; // Obtiene la primera instruccion a ejecutar. while (!(current is EndChartElement) && !shouldStop) { if (current == null) throw new InvalidOperationException("Unconnected chart element. Check your chart connections."); if (current is ConditionalChartElement) { ConditionalChartElement conditionalChart = (ConditionalChartElement)current; if (conditionalChart.Condition == "") throw new InvalidOperationException("Invalid conditional chart."); string preExpression = ParseSensorData(conditionalChart.Condition).ToLower(); string evaluationResult = Evaluator.Evaluate(preExpression); bool found = false; foreach (var connection in current.Connections) { if (evaluationResult.Equals(connection.Label)) { if (connection.To != null) { current = connection.To.ChartElement; found = true; } else throw new Exception("Invalid connection"); break; } } if (!found) throw new InvalidOperationException("Invalid conditional expression."); } else { if (current is CommandChartElement) { ExecuteCommand((CommandChartElement)current); } else if (current is ActivityChartElement) { string activityName = ((ActivityChartElement)current).ActivityName; if (ActivityList.ContainsKey(activityName)) { ExecuteAlgorithm(ActivityList[activityName]); } else throw new InvalidOperationException("Invalid activity."); } else if (current is AssignationChartElement) { AssignationChartElement assignChart = (AssignationChartElement)current; if (assignChart.Name == "" || assignChart.Expression == "") throw new InvalidOperationException("Invalid assignation chart element."); string where = ParseSensorData(assignChart.Name); string preExpression = ParseSensorData(((AssignationChartElement)current).Expression).ToLower(); string what = Evaluator.Evaluate(preExpression); Evaluator.Assign(where, what); } foreach (var connection in current.Connections) { if (connection.To != null) current = connection.To.ChartElement; else throw new InvalidOperationException("Unconnected chart element. Check your chart connections."); break; } } } } catch (Exception exception) { if (!(exception is ThreadAbortException)) { OnError(exception); // Lanza el evento Error con el mensaje incluido. if (current != null) current.BackColor = Color.Red; // Cambia el color del chartElement actual para permitir al usuario conocer la fuente del error. Thread.CurrentThread.Abort(); // Termina la ejecucion del hilo actual. } } }
/// <summary> /// Ejecuta un algoritmo determinado, dado por un ChartElementCollection. /// </summary> /// <param name="instructionCollection">El conjunto de instrucciones a ejecutar.</param> public void ExecuteAlgorithm(ChartElementCollection instructionCollection) { ChartElement current = null; try { ChartElement first = instructionCollection.First; // Obtiene el elemento "Begin" si existe. if (first == null || first.Connections == null) { throw new Exception("Invalid algorithm to execute."); // Si no existe el "Begin", el algoritmo no es valido. } foreach (var connection in first.Connections) { if (connection.To != null) { current = connection.To.ChartElement; // Obtiene la primera instruccion a ejecutar. } } while (!(current is EndChartElement) && !shouldStop) { if (current == null) { throw new InvalidOperationException("Unconnected chart element. Check your chart connections."); } if (current is ConditionalChartElement) { ConditionalChartElement conditionalChart = (ConditionalChartElement)current; if (conditionalChart.Condition == "") { throw new InvalidOperationException("Invalid conditional chart."); } string preExpression = ParseSensorData(conditionalChart.Condition).ToLower(); string evaluationResult = Evaluator.Evaluate(preExpression); bool found = false; foreach (var connection in current.Connections) { if (evaluationResult.Equals(connection.Label)) { if (connection.To != null) { current = connection.To.ChartElement; found = true; } else { throw new Exception("Invalid connection"); } break; } } if (!found) { throw new InvalidOperationException("Invalid conditional expression."); } } else { if (current is CommandChartElement) { ExecuteCommand((CommandChartElement)current); } else if (current is ActivityChartElement) { string activityName = ((ActivityChartElement)current).ActivityName; if (ActivityList.ContainsKey(activityName)) { ExecuteAlgorithm(ActivityList[activityName]); } else { throw new InvalidOperationException("Invalid activity."); } } else if (current is AssignationChartElement) { AssignationChartElement assignChart = (AssignationChartElement)current; if (assignChart.Name == "" || assignChart.Expression == "") { throw new InvalidOperationException("Invalid assignation chart element."); } string where = ParseSensorData(assignChart.Name); string preExpression = ParseSensorData(((AssignationChartElement)current).Expression).ToLower(); string what = Evaluator.Evaluate(preExpression); Evaluator.Assign(where, what); } foreach (var connection in current.Connections) { if (connection.To != null) { current = connection.To.ChartElement; } else { throw new InvalidOperationException("Unconnected chart element. Check your chart connections."); } break; } } } } catch (Exception exception) { if (!(exception is ThreadAbortException)) { OnError(exception); // Lanza el evento Error con el mensaje incluido. if (current != null) { current.BackColor = Color.Red; // Cambia el color del chartElement actual para permitir al usuario conocer la fuente del error. } Thread.CurrentThread.Abort(); // Termina la ejecucion del hilo actual. } } }