Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 4759 was 4759, checked in by epitzer, 13 years ago

navigate execution contexts show active scopes (#47)

File size: 10.7 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      toolTip.SetToolTip(operationTextBox, null);
132      if (atomicOperation != null && atomicOperation.Operator != null) {
133        operationTextBox.Text = string.Format("Atomic {0}", atomicOperation.Operator.Name);
134        toolTip.SetToolTip(operationTextBox, TypeName(atomicOperation.Operator));
135      }
136      OperationCollection operationCollection = operation as OperationCollection;
137      if (operationCollection != null)
138        operationTextBox.Text = string.Format("Collection {0}", operationCollection.Count);
139      IExecutionContext context = operation as IExecutionContext;
140      IScope scope = null;
141      if (context != null) {
142        scope = context.Scope;
143        while (scope != null && scope.Parent != null)
144          scope = scope.Parent;
145      }
146      UpdateScope(scope);
147      if (context != null)
148        parentButton.Enabled = context.Parent != null;
149      scopeTreeView.Tag = context;
150    }
151
152    private void UpdateExecutionStack() {
153      executionStackTreeView.BeginUpdate();
154      executionStackTreeView.Nodes.Clear();
155      AddOperations(executionStackTreeView.Nodes, Content.ExecutionStack.ToArray());
156      executionStackTreeView.ExpandAll();
157      if (executionStackTreeView.Nodes.Count > 0)
158        executionStackTreeView.TopNode = executionStackTreeView.Nodes[0];
159      executionStackTreeView.EndUpdate();
160    }
161
162    private void UpdateScope(IScope scope) {
163      scopeTreeView.BeginUpdate();
164      scopeTreeView.Nodes.Clear();
165      if (scope != null) {
166        AddScope(scopeTreeView.Nodes, scope);
167      }
168      scopeTreeView.ExpandAll();
169      if (scopeTreeView.Nodes.Count > 0)
170        scopeTreeView.TopNode = scopeTreeView.Nodes[0];
171      scopeTreeView.EndUpdate();
172    }
173
174    private string TypeName(object obj) {
175      if (obj == null)
176        return "null";
177      return TypeNameParser.Parse(obj.GetType().ToString()).GetTypeNameInCode(true);
178    }
179
180    private void AddOperations(TreeNodeCollection nodes, IEnumerable<IOperation> operations) {
181      foreach (IOperation op in operations) {
182        if (op is IAtomicOperation) {
183          IAtomicOperation atom = op as IAtomicOperation;
184          TreeNode node = nodes.Add(atom.Operator.Name);
185          node.Tag = atom;
186          node.ToolTipText = TypeName(atom);
187          node.ImageKey = "AtomicOperation";
188          if (atom.Operator.Breakpoint)
189            node.ForeColor = Color.Red;
190          foreach (var param in atom.Operator.Parameters) {
191            string typeName = "null";
192            TreeNode paramNode = node.Nodes.Add(string.Format("Param {0} = {1}", param.Name, GetApproximateValue(param, ref typeName)));
193            paramNode.Tag = param;
194            paramNode.ToolTipText = string.Format("{0} = {1}", TypeName(param), typeName);
195            paramNode.ImageKey = "Parameter";
196          }
197        } else if (op is OperationCollection) {
198          OperationCollection ops = op as OperationCollection;
199          TreeNode node = executionStackTreeView.Nodes.Add(string.Format("{0} Operations", ops.Count));
200          node.Tag = op;
201          node.ToolTipText = TypeName(ops);
202          node.ImageKey = "OperationCollection";
203          AddOperations(node.Nodes, ops);
204        }
205      }
206    }
207
208    private string GetApproximateValue(IParameter param, ref string typeName) {
209      string valueString = "<none>";
210      IExecutionContext context = Content.CurrentOperation as IExecutionContext;
211      IExecutionContext originalContext = param.ExecutionContext;
212      object value = null;
213      try {
214        try {
215          param.ExecutionContext = context;
216          value = param.ActualValue;
217        } finally {
218          param.ExecutionContext = originalContext;
219        }
220      } catch (Exception) { }
221      if (value != null) {
222        valueString = value.ToString();
223        if (context != originalContext)
224          valueString = " ~ " + valueString;
225        typeName = TypeName(value);
226      }
227      return valueString;
228    }
229
230    private void AddScope(TreeNodeCollection nodes, IScope scope) {
231      TreeNode node = nodes.Add(scope.Name);
232      if (Content.CurrentOperation != null && Content.CurrentOperation.Scope == scope) {
233        node.ForeColor = Color.Red;
234        node.BackColor = Color.LightGray;
235      }
236      foreach (var var in scope.Variables) {
237        TreeNode varNode = node.Nodes.Add(string.Format("{0}={1}", var.Name, var.Value.ToString()));
238        varNode.Tag = var.Value;
239        varNode.ToolTipText = TypeName(var.Value);
240      }
241      foreach (var subScope in scope.SubScopes) {
242        AddScope(node.Nodes, subScope);
243      }
244    }
245
246    private void stepButton_Click(object sender, EventArgs e) {
247      Content.Step();
248      UpdateView();
249    }
250
251    private void executionStackTreeView_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e) {
252      if (e.Node != null) {
253        IAtomicOperation op = e.Node.Tag as IAtomicOperation;
254        if (op != null) {
255          op.Operator.Breakpoint = !op.Operator.Breakpoint;
256          if (op.Operator.Breakpoint) {
257            e.Node.ForeColor = Color.Red;
258          } else {
259            e.Node.ForeColor = Color.Black;
260          }
261          executionStackTreeView.SelectedNode = null;
262        }
263        IParameter param = e.Node.Tag as IParameter;
264        if (param != null)
265          MainFormManager.MainForm.ShowContent(param);
266      }
267    }
268
269    private void updateButton_Click(object sender, EventArgs e) {
270      UpdateView();
271    }
272
273    private void scopeTreeView_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e) {
274      if (e.Node.Tag != null)
275        MainFormManager.MainForm.ShowContent((IItem)e.Node.Tag);
276    }
277
278    private void parentButton_Click(object sender, EventArgs e) {
279      IExecutionContext context = scopeTreeView.Tag as IExecutionContext;
280      if (context != null) {
281        SetOperation(context.Parent as IOperation);
282      }
283    }
284  }
285}
Note: See TracBrowser for help on using the repository browser.