Free cookie consent management tool by TermsFeed Policy Generator

source: branches/OKB/HeuristicLab.OKB.AlgorithmHost/AlgorithmHostView.cs @ 5404

Last change on this file since 5404 was 4311, checked in by swagner, 14 years ago

Integrated OKB clients for HL 3.3 (#1166)

File size: 15.0 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.ComponentModel;
4using System.Data;
5using System.Drawing;
6using System.Text;
7using System.Linq;
8using System.Windows.Forms;
9using HeuristicLab.Optimization.Views;
10using HeuristicLab.Core.Views;
11using HeuristicLab.MainForm;
12using HeuristicLab.Common;
13using HeuristicLab.Core;
14using HeuristicLab.PluginInfrastructure;
15using HeuristicLab.Optimization;
16using HeuristicLab.Common.Resources;
17using System.Collections.Specialized;
18using System.Threading;
19using HeuristicLab.BackgroundProcessing;
20using HeuristicLab.Collections;
21
22namespace HeuristicLab.OKB.AlgorithmHost {
23
24  [View("OKB Algorithm Host View")]
25  [Content(typeof(AlgorithmHost), true)]
26  public partial class AlgorithmHostView : NamedItemView {
27
28    protected WorkerMonitor workerMonitor;
29
30    public new AlgorithmHost Content {
31      get { return (AlgorithmHost)base.Content; }
32      set { base.Content = value; }
33    }
34
35    public AlgorithmHostView() {
36      InitializeComponent();
37      workerMonitor = new WorkerMonitor();
38      workerMonitor.BackgroundWorkerException += new ThreadExceptionEventHandler(workerMonitor_BackgroundWorkerException);
39      workerMonitor.CollectionChanged += new NotifyCollectionChangedEventHandler(workerMonitor_CollectionChanged);
40    }
41
42    void workerMonitor_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) {
43      if (InvokeRequired) {
44        Invoke(new NotifyCollectionChangedEventHandler(workerMonitor_CollectionChanged), sender, e);
45      } else {
46        switch (e.Action) {
47          case NotifyCollectionChangedAction.Add:
48            string name = ((ObservableBackgroundWorker)e.NewItems[0]).Name;
49            statusStrip.Items.Add(new ToolStripStatusLabel(name) {
50              Name = name,
51              BorderSides = ToolStripStatusLabelBorderSides.Left,
52              BorderStyle = Border3DStyle.Etched,
53            });
54            break;
55          case NotifyCollectionChangedAction.Remove:
56            statusStrip.Items.RemoveByKey(((ObservableBackgroundWorker)e.OldItems[0]).Name);
57            break;
58        }
59        progressBar.Visible = statusStrip.Items.Count > 0;
60        if (statusStrip.Items.Count > 0) {
61          okbTabPage.Text = "OKB*";
62        } else {
63          okbTabPage.Text = "OKB";
64        }
65      }
66    }
67
68    void workerMonitor_BackgroundWorkerException(object sender, ThreadExceptionEventArgs e) {
69      if (InvokeRequired) {
70        Invoke(new ThreadExceptionEventHandler(workerMonitor_BackgroundWorkerException), sender, e);
71      } else {
72        ErrorHandling.ShowErrorDialog(this, "Uncaught asynchronous exception", e.Exception);
73      }
74    }
75
76    protected override void OnInitialized(EventArgs e) {
77      // Set order of tab pages according to z order.
78      // NOTE: This is required due to a bug in the VS designer.
79      List<Control> tabPages = new List<Control>();
80      for (int i = 0; i < tabControl.Controls.Count; i++) {
81        tabPages.Add(tabControl.Controls[i]);
82      }
83      tabControl.Controls.Clear();
84      foreach (Control control in tabPages)
85        tabControl.Controls.Add(control);
86
87      runsView.ItemsListView.SelectedIndexChanged += new EventHandler(ItemsListView_SelectedIndexChanged);
88      base.OnInitialized(e);
89    }
90
91    void ItemsListView_SelectedIndexChanged(object sender, EventArgs e) {
92      submitButton.Enabled = runsView.ItemsListView.SelectedIndices.Count > 0;
93    }
94
95    protected override void DeregisterContentEvents() {
96      Content.ExceptionOccurred -= new EventHandler<EventArgs<Exception>>(Content_ExceptionOccurred);
97      Content.ExecutionStateChanged -= new EventHandler(Content_ExecutionStateChanged);
98      Content.ExecutionTimeChanged -= new EventHandler(Content_ExecutionTimeChanged);
99      Content.Prepared -= Content_Prepared;
100      Content.AlgorithmChanged -= Content_AlgorithmChanged;
101      Content.ProblemChanged -= Content_ProblemChanged;
102      Content.Runs.ItemsAdded -= Runs_ItemsAdded;
103      base.DeregisterContentEvents();
104    }
105
106    protected override void RegisterContentEvents() {
107      base.RegisterContentEvents();
108      Content.ExceptionOccurred += new EventHandler<EventArgs<Exception>>(Content_ExceptionOccurred);
109      Content.ExecutionStateChanged += new EventHandler(Content_ExecutionStateChanged);
110      Content.ExecutionTimeChanged += new EventHandler(Content_ExecutionTimeChanged);
111      Content.Prepared += Content_Prepared;
112      Content.AlgorithmChanged += Content_AlgorithmChanged;
113      Content.ProblemChanged += Content_ProblemChanged;
114      Content.Runs.ItemsAdded += Runs_ItemsAdded;
115    }
116
117    void Runs_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IRun> e) {
118      if (InvokeRequired) {
119        Invoke(new CollectionItemsChangedEventHandler<IRun>(Runs_ItemsAdded), sender, e);
120      } else {
121        if (autoSubmitCheckBox.Checked) {
122          foreach (IRun run in e.Items) {
123            SubmitRun(run, true);
124          }
125        }
126      }
127    }
128
129    void Content_ProblemChanged(object sender, EventArgs e) {
130      if (InvokeRequired)
131        Invoke(new EventHandler(Content_ProblemChanged), sender, e);
132      else {
133        problemParameterCollectionView.Content = Content.ProblemParameters;
134        SetEnableStateOfControls();
135        if (!Content.HasOKBProblem)
136          MessageBox.Show(ParentForm,
137            "Non-OKB problem selected: You will not be able to submit results with non-OKB problems",
138            "Non-OKB Problem Selected.", MessageBoxButtons.OK, MessageBoxIcon.Warning);
139      }
140    }
141
142    void Content_AlgorithmChanged(object sender, EventArgs e) {
143      if (InvokeRequired)
144        Invoke(new EventHandler(Content_AlgorithmChanged), sender, e);
145      else {
146        algorithmParameterCollectionView.Content = Content.Algorithm.Parameters;
147        resultsView.Content = Content.Algorithm.Results.AsReadOnly();
148        SetEnableStateOfControls();
149      }
150    }
151
152    protected override void OnContentChanged() {
153      base.OnContentChanged();
154      if (Content == null) {
155        algorithmParameterCollectionView.Content = null;
156        problemParameterCollectionView.Content = null;
157        resultsView.Content = null;
158        runsView.Content = null;
159        executionTimeTextBox.Text = "-";
160      } else {
161        algorithmParameterCollectionView.Content = Content.Parameters;
162        problemParameterCollectionView.Content = Content.ProblemParameters;
163        runsView.Content = Content.Runs;
164        executionTimeTextBox.Text = Content.ExecutionTime.ToString();
165        if (Content.StarterKit == null)
166          DownloadStarterKit();
167      }
168      SetEnableStateOfControls();
169    }
170
171    private void DownloadStarterKit() {
172      BackgroundWorker loader = new ObservableBackgroundWorker("Connecting...", workerMonitor);
173      loader.DoWork += (s, a) => {
174        var starterKit = Content.DownloadStarerKit();
175        Content.StarterKit = starterKit;
176      };
177      connectButton.Enabled = false;
178      SetEnableStateOfControls();
179      loader.RunWorkerCompleted += (s, a) => {
180        connectButton.Enabled = true;
181        SetEnableStateOfControls();
182      };
183      loader.RunWorkerAsync();
184    }
185
186    protected override void OnReadOnlyChanged() {
187      base.OnReadOnlyChanged();
188      SetEnableStateOfControls();
189    }
190
191    private void SetEnableStateOfControls() {
192      openAlgorithmButton.Enabled = Content != null && Content.StarterKit != null;
193      openProblemButton.Enabled = Content != null && Content.StarterKit != null;
194      algorithmParameterCollectionView.Enabled = Content != null && Content.Algorithm != null;
195      problemParameterCollectionView.Enabled = Content != null && Content.Problem != null;
196      resultsView.Enabled = Content != null;
197      runsView.Enabled = Content != null;
198      executionTimeTextBox.Enabled = Content != null;
199      viewAlgorithmButton.Enabled = Content != null && Content.Algorithm != null;
200      viewProblemButton.Enabled = Content != null && Content.Problem != null;
201      SetEnabledStateOfExecutableButtons();
202    }
203
204    protected override void OnClosed(FormClosedEventArgs e) {
205      if ((Content != null) && (Content.ExecutionState == ExecutionState.Started)) Content.Stop();
206      base.OnClosed(e);
207    }
208
209    #region Content Events
210    protected virtual void Content_Prepared(object sender, EventArgs e) {
211      if (InvokeRequired)
212        Invoke(new EventHandler(Content_Prepared), sender, e);
213      else
214        resultsView.Content = Content.Results.AsReadOnly();
215    }
216    protected virtual void Content_ExecutionStateChanged(object sender, EventArgs e) {
217      if (InvokeRequired)
218        Invoke(new EventHandler(Content_ExecutionStateChanged), sender, e);
219      else {
220        ReadOnly = Content.ExecutionState == ExecutionState.Started;
221        Locked = Content.ExecutionState == ExecutionState.Started;
222        SetEnabledStateOfExecutableButtons();
223      }
224    }
225    protected virtual void Content_ExecutionTimeChanged(object sender, EventArgs e) {
226      if (InvokeRequired)
227        Invoke(new EventHandler(Content_ExecutionTimeChanged), sender, e);
228      else
229        executionTimeTextBox.Text = Content.ExecutionTime.ToString();
230    }
231    protected virtual void Content_ExceptionOccurred(object sender, EventArgs<Exception> e) {
232      if (InvokeRequired)
233        Invoke(new EventHandler<EventArgs<Exception>>(Content_ExceptionOccurred), sender, e);
234      else
235        ErrorHandling.ShowErrorDialog(this, e.Value);
236    }
237    #endregion
238
239    #region Control Events
240    protected virtual void openAlgorithmButton_Click(object sender, EventArgs e) {
241      SelectItemDialog d = new SelectItemDialog();
242      foreach (var ac in Content.StarterKit.AlgorithmClasses) {
243        foreach (var a in ac.Algorithms) {
244          d.AddItem(a.Name, a.Description, ac.Name, a, VS2008ImageLibrary.ExecutableStopped);
245        }
246      }
247      if (d.ShowDialog(ParentForm) == DialogResult.OK) {
248        var loader = new ObservableBackgroundWorker("loading algorithm...", workerMonitor);
249        loader.DoWork += (s, a) => {
250          Content.OKBAlgorithm = d.Item as OKBRunner.Algorithm;
251        };
252        loader.RunWorkerAsync();
253      }
254    }
255    protected virtual void openProblemButton_Click(object sender, EventArgs e) {
256      SelectItemDialog d = new SelectItemDialog();
257      foreach (var pc in Content.StarterKit.ProblemClasses) {
258        foreach (var p in pc.Problems) {
259          d.AddItem(p.Name, p.Description, pc.Name, p, VS2008ImageLibrary.Type);
260        }
261      }
262      if (d.ShowDialog(ParentForm) == DialogResult.OK) {
263        var loader = new ObservableBackgroundWorker("loading problem...", workerMonitor);
264        loader.DoWork += (s, a) => {
265          Content.OKBProblem = d.Item as OKBRunner.Problem;
266        };
267        loader.RunWorkerAsync();
268      }
269    }
270    protected virtual void startButton_Click(object sender, EventArgs e) {
271      Content.Start();
272    }
273    protected virtual void pauseButton_Click(object sender, EventArgs e) {
274      Content.Pause();
275    }
276    protected virtual void stopButton_Click(object sender, EventArgs e) {
277      Content.Stop();
278    }
279    protected virtual void resetButton_Click(object sender, EventArgs e) {
280      Content.Prepare(false);
281    }
282    protected virtual void connectButton_Click(object sender, EventArgs e) {
283      DownloadStarterKit();
284    }
285    #endregion
286
287    #region Helpers
288    private void SetEnabledStateOfExecutableButtons() {
289      if (Content == null) {
290        startButton.Enabled = pauseButton.Enabled = stopButton.Enabled = resetButton.Enabled = false;
291      } else {
292        startButton.Enabled = (Content.ExecutionState == ExecutionState.Prepared) || (Content.ExecutionState == ExecutionState.Paused);
293        pauseButton.Enabled = Content.ExecutionState == ExecutionState.Started;
294        stopButton.Enabled = (Content.ExecutionState == ExecutionState.Started) || (Content.ExecutionState == ExecutionState.Paused);
295        resetButton.Enabled = Content.ExecutionState != ExecutionState.Started;
296      }
297    }
298    #endregion
299
300    private void submitButton_Click(object sender, EventArgs e) {
301      foreach (ListViewItem item in runsView.ItemsListView.SelectedItems) {
302        SubmitRun(item.Tag as IRun, false);
303      }
304    }
305
306    private void SubmitRun(IRun run, bool skipConfirmation) {
307      if (run == null) {
308        MessageBox.Show(this, "selected item is not an IRun :`(");
309      } else {
310        var worker = new ObservableBackgroundWorker("Preparing submission: " + run.Name, workerMonitor);
311        OKBRunner.ExperimentKit experimentKit = null;
312        worker.DoWork += (s, a) => {
313          experimentKit = Content.PrepareSubmission(run);
314        };
315        worker.RunWorkerCompleted += (s, a) => {
316          if (experimentKit == null)
317            return;
318          if (skipConfirmation || ConfirmSubmission(experimentKit)) {
319            var submitter = new ObservableBackgroundWorker("Submitting Run: " + run.Name, workerMonitor);
320            submitter.DoWork += (s1, a1) => { Content.SubmitRun(experimentKit); };
321            submitter.RunWorkerAsync();
322          }
323        };
324        worker.RunWorkerAsync();
325      }
326    }
327
328    private bool ConfirmSubmission(OKBRunner.ExperimentKit experimentKit) {
329      return MessageBox.Show(this,
330        AlgorithmHost.FormatSubmission(experimentKit),
331        "Submit Run?",
332        MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK;
333    }
334
335    private void viewAlgorithmButton_Click(object sender, EventArgs e) {
336      if (Content.Algorithm == null) return;
337      IContentView view = FindFirstView(Content.Algorithm);
338      if (view == null && MessageBox.Show(ParentForm,
339@"The defintion of this algorithm has been fixed inside the OKB
340and should not be changed in a way that changes its behaviour
341
342Please be careful with modifications!", "Algorithm assumed fixed!",
343          MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation) == DialogResult.OK)
344        view = MainFormManager.CreateDefaultView(Content.Algorithm.GetType());
345      if (view != null) {
346        view.Content = Content.Algorithm;
347        view.Show();
348      }
349    }
350
351    private void viewProblemButton_Click(object sender, EventArgs e) {
352      if (Content.Problem == null) return;
353      IContentView view = FindFirstView(Content.Problem);
354      if (view == null && MessageBox.Show(ParentForm,
355@"The defintion of this problem has been fixed inside the OKB
356and should not be changed in a way that changes its behaviour.
357
358Please be careful with modifications!", "Problem assumed fixed!",
359          MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation) == DialogResult.OK)
360        view = MainFormManager.CreateDefaultView(Content.Problem.GetType());
361      if (view != null) {
362        view.Content = Content.Problem;
363        view.Show();
364      }
365    }
366
367    private static IContentView FindFirstView(IContent content) {
368      return MainFormManager.MainForm.Views
369        .Where(v => v is IContentView)
370        .Cast<IContentView>()
371        .Where(v => v.Content == content)
372        .FirstOrDefault();
373    }
374
375  }
376}
Note: See TracBrowser for help on using the repository browser.