Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.DebugEngine/DebugEngineView.cs @ 4791

Last change on this file since 4791 was 4765, checked in by epitzer, 14 years ago

Show parameters of active execution context in DebugEngine (#47)

File size: 10.8 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
24using System.Drawing;
25using System.Windows.Forms;
26using HeuristicLab.Common.Resources;
27using HeuristicLab.Core;
28using HeuristicLab.Core.Views;
29using HeuristicLab.MainForm;
30using HeuristicLab.Persistence.Auxiliary;
31namespace HeuristicLab.DebugEngine {
32  /// <summary>
33  /// Base class for editors of engines.
34  /// </summary>
35  [View("DebugEngine View")]
36  [Content(typeof(DebugEngine), true)]
37  public partial class DebugEngineView : ItemView {
38    /// <summary>
39    /// Gets or sets the current engine.
40    /// </summary>
41    /// <remarks>Uses property <see cref="ViewBase.Item"/> of base class <see cref="EditorBase"/>.</remarks>
42    public new DebugEngine Content {
43      get { return (DebugEngine)base.Content; }
44      set { base.Content = value; }
45    }
46
47    /// <summary>
48    /// Initializes a new instance of <see cref="EngineBaseEditor"/>.
49    /// </summary>
50    public DebugEngineView() {
51      InitializeComponent();
52      updateButton.Image = VS2008ImageLibrary.Refresh;
53      stepButton.Image = VS2008ImageLibrary.MoveNext;
54      parentButton.Image = VS2008ImageLibrary.ArrowUp;
55    }
56
57    /// <summary>
58    /// Removes the event handlers from the underlying <see cref="IEngine"/>.
59    /// </summary>
60    /// <remarks>Calls <see cref="ViewBase.RemoveItemEvents"/> of base class <see cref="ViewBase"/>.</remarks>
61    protected override void DeregisterContentEvents() {
62      Content.ExecutionTimeChanged -= new EventHandler(Content_ExecutionTimeChanged);
63      Content.ExecutionStateChanged -= new EventHandler(Content_ExecutionStateChanged);
64      base.DeregisterContentEvents();
65    }
66
67    /// <summary>
68    /// Adds event handlers to the underlying <see cref="IEngine"/>.
69    /// </summary>
70    /// <remarks>Calls <see cref="ViewBase.AddItemEvents"/> of base class <see cref="ViewBase"/>.</remarks>
71    protected override void RegisterContentEvents() {
72      base.RegisterContentEvents();
73      Content.ExecutionTimeChanged += new EventHandler(Content_ExecutionTimeChanged);
74      Content.ExecutionStateChanged += new EventHandler(Content_ExecutionStateChanged);
75    }
76
77    /// <summary>
78    /// Updates all controls with the latest data of the model.
79    /// </summary>
80    /// <remarks>Calls <see cref="EditorBase.UpdateControls"/> of base class <see cref="EditorBase"/>.</remarks>
81    protected override void OnContentChanged() {
82      base.OnContentChanged();
83      if (Content == null) {
84        logView.Content = null;
85        executionTimeTextBox.Text = "-";
86      } else {
87        logView.Content = Content.Log;
88        executionTimeTextBox.Text = Content.ExecutionTime.ToString();
89      }
90    }
91
92    protected override void SetEnabledStateOfControls() {
93      base.SetEnabledStateOfControls();
94      if (Content == null) {
95        logView.Enabled = false;
96        executionTimeTextBox.Enabled = false;
97      } else {
98        logView.Enabled = true;
99        executionTimeTextBox.Enabled = true;
100      }
101    }
102
103    protected virtual void Content_ExecutionTimeChanged(object sender, EventArgs e) {
104      if (InvokeRequired)
105        Invoke(new EventHandler(Content_ExecutionTimeChanged), sender, e);
106      else
107        executionTimeTextBox.Text = Content == null ? "-" : Content.ExecutionTime.ToString();
108    }
109
110    void Content_ExecutionStateChanged(object sender, EventArgs e) {
111      switch (Content.ExecutionState) {
112        case ExecutionState.Paused:
113        case ExecutionState.Stopped:
114        case ExecutionState.Prepared:
115          UpdateView(); break;
116      }
117    }
118
119    protected virtual void UpdateView() {
120      if (InvokeRequired) {
121        Invoke(new Action(UpdateView));
122      } else {
123        UpdateExecutionStack();
124        SetOperation(Content.CurrentOperation);
125      }
126    }
127
128    private void SetOperation(IOperation operation) {
129      IAtomicOperation atomicOperation = operation as IAtomicOperation;
130      operationTextBox.Text = "<none>";
131      parameterCollectionView.Content = null;
132      toolTip.SetToolTip(operationTextBox, null);
133      if (atomicOperation != null && atomicOperation.Operator != null) {
134        operationTextBox.Text = string.Format("Atomic {0}", atomicOperation.Operator.Name);
135        toolTip.SetToolTip(operationTextBox, TypeName(atomicOperation.Operator));
136      }
137      OperationCollection operationCollection = operation as OperationCollection;
138      if (operationCollection != null)
139        operationTextBox.Text = string.Format("Collection {0}", operationCollection.Count);
140      IExecutionContext context = operation as IExecutionContext;
141      IScope scope = null;
142      if (context != null) {
143        parameterCollectionView.Content = context.Parameters;
144        scope = context.Scope;
145        while (scope != null && scope.Parent != null)
146          scope = scope.Parent;
147      }
148      UpdateScope(scope);
149      if (context != null)
150        parentButton.Enabled = context.Parent != null;
151      scopeTreeView.Tag = context;
152    }
153
154    private void UpdateExecutionStack() {
155      executionStackTreeView.BeginUpdate();
156      executionStackTreeView.Nodes.Clear();
157      AddOperations(executionStackTreeView.Nodes, Content.ExecutionStack.ToArray());
158      executionStackTreeView.ExpandAll();
159      if (executionStackTreeView.Nodes.Count > 0)
160        executionStackTreeView.TopNode = executionStackTreeView.Nodes[0];
161      executionStackTreeView.EndUpdate();
162    }
163
164    private void UpdateScope(IScope scope) {
165      scopeTreeView.BeginUpdate();
166      scopeTreeView.Nodes.Clear();
167      if (scope != null) {
168        AddScope(scopeTreeView.Nodes, scope);
169      }
170      scopeTreeView.ExpandAll();
171      if (scopeTreeView.Nodes.Count > 0)
172        scopeTreeView.TopNode = scopeTreeView.Nodes[0];
173      scopeTreeView.EndUpdate();
174    }
175
176    private string TypeName(object obj) {
177      if (obj == null)
178        return "null";
179      return TypeNameParser.Parse(obj.GetType().ToString()).GetTypeNameInCode(true);
180    }
181
182    private void AddOperations(TreeNodeCollection nodes, IEnumerable<IOperation> operations) {
183      foreach (IOperation op in operations) {
184        if (op is IAtomicOperation) {
185          IAtomicOperation atom = op as IAtomicOperation;
186          TreeNode node = nodes.Add(atom.Operator.Name);
187          node.Tag = atom;
188          node.ToolTipText = TypeName(atom);
189          node.ImageKey = "AtomicOperation";
190          if (atom.Operator.Breakpoint)
191            node.ForeColor = Color.Red;
192          foreach (var param in atom.Operator.Parameters) {
193            string typeName = "null";
194            TreeNode paramNode = node.Nodes.Add(string.Format("Param {0} = {1}", param.Name, GetApproximateValue(param, ref typeName)));
195            paramNode.Tag = param;
196            paramNode.ToolTipText = string.Format("{0} = {1}", TypeName(param), typeName);
197            paramNode.ImageKey = "Parameter";
198          }
199        } else if (op is OperationCollection) {
200          OperationCollection ops = op as OperationCollection;
201          TreeNode node = executionStackTreeView.Nodes.Add(string.Format("{0} Operations", ops.Count));
202          node.Tag = op;
203          node.ToolTipText = TypeName(ops);
204          node.ImageKey = "OperationCollection";
205          AddOperations(node.Nodes, ops);
206        }
207      }
208    }
209
210    private string GetApproximateValue(IParameter param, ref string typeName) {
211      string valueString = "<none>";
212      IExecutionContext context = Content.CurrentOperation as IExecutionContext;
213      IExecutionContext originalContext = param.ExecutionContext;
214      object value = null;
215      try {
216        try {
217          param.ExecutionContext = context;
218          value = param.ActualValue;
219        } finally {
220          param.ExecutionContext = originalContext;
221        }
222      } catch (Exception) { }
223      if (value != null) {
224        valueString = value.ToString();
225        if (context != originalContext)
226          valueString = " ~ " + valueString;
227        typeName = TypeName(value);
228      }
229      return valueString;
230    }
231
232    private void AddScope(TreeNodeCollection nodes, IScope scope) {
233      TreeNode node = nodes.Add(scope.Name);
234      if (Content.CurrentOperation != null && Content.CurrentOperation.Scope == scope) {
235        node.ForeColor = Color.Red;
236        node.BackColor = Color.LightGray;
237      }
238      foreach (var var in scope.Variables) {
239        TreeNode varNode = node.Nodes.Add(string.Format("{0}={1}", var.Name, var.Value.ToString()));
240        varNode.Tag = var.Value;
241        varNode.ToolTipText = TypeName(var.Value);
242      }
243      foreach (var subScope in scope.SubScopes) {
244        AddScope(node.Nodes, subScope);
245      }
246    }
247
248    private void stepButton_Click(object sender, EventArgs e) {
249      Content.Step();
250      UpdateView();
251    }
252
253    private void executionStackTreeView_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e) {
254      if (e.Node != null) {
255        IAtomicOperation op = e.Node.Tag as IAtomicOperation;
256        if (op != null) {
257          op.Operator.Breakpoint = !op.Operator.Breakpoint;
258          if (op.Operator.Breakpoint) {
259            e.Node.ForeColor = Color.Red;
260          } else {
261            e.Node.ForeColor = Color.Black;
262          }
263          executionStackTreeView.SelectedNode = null;
264        }
265        IParameter param = e.Node.Tag as IParameter;
266        if (param != null)
267          MainFormManager.MainForm.ShowContent(param);
268      }
269    }
270
271    private void updateButton_Click(object sender, EventArgs e) {
272      UpdateView();
273    }
274
275    private void scopeTreeView_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e) {
276      if (e.Node.Tag != null)
277        MainFormManager.MainForm.ShowContent((IItem)e.Node.Tag);
278    }
279
280    private void parentButton_Click(object sender, EventArgs e) {
281      IExecutionContext context = scopeTreeView.Tag as IExecutionContext;
282      if (context != null) {
283        SetOperation(context.Parent as IOperation);
284      }
285    }
286  }
287}
Note: See TracBrowser for help on using the repository browser.