Free cookie consent management tool by TermsFeed Policy Generator

source: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Views/PushDebuggerView.cs @ 14914

Last change on this file since 14914 was 14914, checked in by pkimmesw, 7 years ago

#2665 Added Dictionary of stacks to interperter, clear all stacks

File size: 7.9 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Drawing;
4using System.Linq;
5using System.Windows.Forms;
6
7namespace HeuristicLab.Problems.ProgramSynthesis.Push.Views {
8  using Configuration;
9  using Core.Views;
10  using Expressions;
11  using Interpreter;
12  using MainForm;
13  using Problem;
14  using Stack;
15
16  public partial class PushDebuggerView : ItemView {
17    private readonly IDictionary<StackTypes, ListBox> debugControlDict = new Dictionary<StackTypes, ListBox>();
18
19    private PooledPushInterpreter interpreter;
20    private PooledPushInterpreter interpreter2; // used to determine noops
21    private PushInterpreterPool pool;
22
23    private const string GroupBoxTextStringFormat = "{0}[{1}]";
24
25    public event EventHandler<IPushInterpreter> OnReset;
26
27    public PushDebuggerView() {
28      InitializeComponent();
29      InitEvents();
30    }
31
32    ~PushDebuggerView() {
33      interpreter.Dispose();
34      interpreter2.Dispose();
35    }
36
37    public new PushSolution Content
38    {
39      get { return (PushSolution)base.Content; }
40      set
41      {
42        base.Content = value;
43      }
44    }
45
46    protected override void OnContentChanged() {
47      if (Content == null) return;
48
49      Name = "Push Debugger";
50      pool = new PushInterpreterPool(Content.Config);
51
52      if (interpreter != null) {
53        interpreter.Dispose();
54        interpreter2.Dispose();
55      }
56
57      interpreter = pool.Create(Content.Random);
58      interpreter2 = pool.Create(Content.Random);
59
60
61      InitDebugLists(Content.Config);
62      ClearDebugLists();
63      UpdateExecList();
64      UpdateDebugLists();
65      ResetDebugging();
66    }
67
68    private void InitEvents() {
69      runButton.Click += RunButtonClick;
70      resetButton.Click += ResetButtonClick;
71      stepButton.Click += StepButtonClick;
72      simplifyButton.Click += SimplifyButtonClick;
73    }
74
75    private void RunButtonClick(object sender, EventArgs e) {
76      if (interpreter == null)
77        return;
78
79      interpreter.Resume();
80
81      ResetDebugging();
82      UpdateExecList();
83      UpdateDebugLists();
84      CheckIfButtonsCanBeEnabled();
85    }
86
87    private void StepButtonClick(object sender, EventArgs e) {
88      if (interpreter == null || stepWidthBox.Value <= 0)
89        return;
90
91      var count = Math.Min(stepWidthBox.Value, interpreter.ExecStack.Count);
92
93      if (!interpreter.CanStep)
94        return;
95
96      // skip leading noops
97      if (interpreter2.ExecCounter == (Content.Program.IsProgram ? 1 : 0) &&
98          skipNoopsCheckBox.Checked &&
99          SkipNoops()) {
100        count = 0; // no entries left, cause all were noops
101      }
102
103      for (var i = 0; i < count; i++) {
104        if (skipNoopsCheckBox.Checked) {
105          interpreter.Step();
106
107          if (SkipNoops())
108            break;
109        } else {
110          interpreter.Step();
111          interpreter2.Step();
112        }
113      }
114
115      stepWidthBox.Maximum = Math.Max(1, interpreter.ExecStack.Count);
116
117      UpdateExecList();
118      UpdateDebugLists();
119      CheckIfButtonsCanBeEnabled();
120    }
121
122    private bool SkipNoops() {
123      var skipCount = 0;
124      bool isNoop;
125
126      do {
127        skipCount++;
128        isNoop = !interpreter2.Step();
129      } while (interpreter2.CanStep && isNoop);
130
131      if (isNoop) {
132        interpreter.Step(skipCount);
133      } else if (skipCount > 1) {
134        interpreter.Step(skipCount - 1);
135      }
136
137      return isNoop;
138    }
139
140    private void CheckIfButtonsCanBeEnabled() {
141      runButton.Enabled = interpreter != null && interpreter.CanStep;
142      stepButton.Enabled = interpreter != null && interpreter.CanStep;
143      stepWidthBox.Enabled = interpreter != null && interpreter.CanStep;
144    }
145
146    private void ResetButtonClick(object sender, EventArgs e) {
147      ResetDebugging();
148    }
149
150    private void SimplifyButtonClick(object sender, EventArgs e) {
151      var newContent = Content.Simplify();
152
153      MainFormManager.MainForm.ShowContent(newContent, GetType());
154    }
155
156    public void ResetDebugging() {
157      if (Content == null ||
158          pool == null ||
159          Content.Program == null)
160        return;
161
162      if (interpreter != null) {
163        interpreter.Reset();
164        interpreter2.Reset();
165      }
166
167      if (OnReset != null) {
168        OnReset(this, interpreter);
169        OnReset(this, interpreter2);
170      }
171
172      interpreter.Run(Content.Program, true);
173      interpreter2.Run(Content.Program, true);
174
175      stepWidthBox.Maximum = interpreter.ExecStack.Count;
176
177      UpdateDebugLists();
178      UpdateExecList();
179      CheckIfButtonsCanBeEnabled();
180    }
181
182    private void ClearDebugLists() {
183      foreach (var list in debugControlDict.Values) {
184        list.Items.Clear();
185      }
186    }
187
188    private void UpdateExecList() {
189      execList.Items.Clear();
190      var expressions = interpreter.ExecStack.AsEnumerable()
191        .Reverse()
192        .Select(e => e.StringRepresentation)
193        .ToArray();
194
195      execList.Items.AddRange(expressions);
196      execGroupBox.Text = string.Format(GroupBoxTextStringFormat, Enum.GetName(typeof(StackTypes), StackTypes.Exec), interpreter.ExecStack.Count);
197    }
198
199    private void InitDebugLists(IReadOnlyPushConfiguration config) {
200      debugControlDict.Clear();
201
202      // 2 = ExecList + EmptyColumn which is required to fill empty space
203      while (debugTableLayout.ColumnCount > 2) {
204        debugTableLayout.Controls.RemoveAt(1);
205        debugTableLayout.ColumnCount--;
206      }
207
208      foreach (StackTypes stackType in Enum.GetValues(typeof(StackTypes))) {
209        if (stackType != StackTypes.Exec &&
210            ExpressionTable.GetExpressionsByStackTypes(stackType).Intersect(config.EnabledExpressions).Any()) {
211          var list = CreateDebugList(stackType);
212          debugControlDict.Add(stackType, list);
213        }
214      }
215    }
216
217    private ListBox CreateDebugList(StackTypes type) {
218      var groupBox = new GroupBox {
219        Anchor = AnchorStyles.Bottom | AnchorStyles.Right | AnchorStyles.Left | AnchorStyles.Top,
220        AutoSize = true,
221        AutoSizeMode = AutoSizeMode.GrowAndShrink,
222        Text = Enum.GetName(typeof(StackTypes), type)
223      };
224
225      var list = new ListBox {
226        Dock = DockStyle.Fill,
227        DrawMode = DrawMode.OwnerDrawFixed
228      };
229
230      // align numbers right
231      var stackEntryType = type.GetStackEntryType();
232      if (stackEntryType == typeof(double) ||
233          stackEntryType == typeof(long)) {
234        list.DrawItem += (sender, e) => {
235          if (e.Index <= -1) return;
236          var item = list.Items[e.Index];
237
238          e.DrawBackground();
239          e.DrawFocusRectangle();
240
241          var brush = new SolidBrush(e.ForeColor);
242          var size = e.Graphics.MeasureString(item.ToString(), e.Font);
243
244          e.Graphics.DrawString(
245            item.ToString(),
246            e.Font,
247            brush,
248            e.Bounds.Right - size.Width,
249            e.Bounds.Top + (e.Bounds.Height / 2 - size.Height / 2));
250        };
251      }
252
253      groupBox.Controls.Add(list);
254
255      var columnWidth = stackEntryType == typeof(Expression) ? 250 : 150;
256
257      debugTableLayout.ColumnCount++;
258      debugTableLayout.ColumnStyles.Insert(1, new ColumnStyle(SizeType.Absolute, columnWidth));
259      debugTableLayout.Controls.Add(groupBox);
260      debugTableLayout.Controls.SetChildIndex(groupBox, 1);
261
262      return list;
263    }
264
265
266    private void UpdateDebugLists() {
267      ClearDebugLists();
268
269      if (Content == null || interpreter == null)
270        return;
271
272      foreach (var pair in debugControlDict) {
273        var stack = interpreter.Stacks[pair.Key];
274        var name = Enum.GetName(typeof(StackTypes), pair.Key);
275
276        pair.Value.Items.AddRange(stack.AsObjects().Reverse().ToArray());
277        ((GroupBox)pair.Value.Parent).Text = string.Format(GroupBoxTextStringFormat, name, pair.Value.Items.Count);
278      }
279    }
280
281  }
282}
Note: See TracBrowser for help on using the repository browser.