Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Clients.OKB/3.3/RunCreation/OKBAlgorithm.cs @ 15377

Last change on this file since 15377 was 15287, checked in by jkarder, 7 years ago

#2258: merged Async branch into trunk

File size: 17.0 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2016 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.Threading;
23using System.Threading.Tasks;
24using HeuristicLab.Clients.Access;
25using HeuristicLab.Collections;
26using HeuristicLab.Common;
27using HeuristicLab.Core;
28using HeuristicLab.Optimization;
29using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
30using HeuristicLab.Persistence.Default.Xml;
31using System;
32using System.Collections.Generic;
33using System.Drawing;
34using System.IO;
35using System.Linq;
36
37namespace HeuristicLab.Clients.OKB.RunCreation {
38  [Item("OKB Algorithm", "An algorithm which is stored in the OKB.")]
39  [Creatable(CreatableAttribute.Categories.TestingAndAnalysisOKB, Priority = 100)]
40  [StorableClass]
41  public sealed class OKBAlgorithm : Item, IAlgorithm, IStorableContent {
42    public string Filename { get; set; }
43
44    private long algorithmId;
45    public long AlgorithmId {
46      get { return algorithmId; }
47    }
48    private IAlgorithm algorithm;
49    private IAlgorithm Algorithm {
50      get { return algorithm; }
51      set {
52        if (value == null) throw new ArgumentNullException("Algorithm", "Algorithm cannot be null.");
53        if (value != algorithm) {
54          CancelEventArgs<string> e = new CancelEventArgs<string>(value.Name);
55          OnNameChanging(e);
56          if (!e.Cancel) {
57            IProblem problem = algorithm.Problem;
58            DeregisterAlgorithmEvents();
59            algorithm = value;
60            RegisterAlgorithmEvents();
61
62            OnToStringChanged();
63            OnItemImageChanged();
64            OnNameChanged();
65            OnDescriptionChanged();
66            OnAlgorithmChanged();
67            OnStoreAlgorithmInEachRunChanged();
68
69            try {
70              algorithm.Problem = problem;
71            } catch (ArgumentException) {
72              algorithm.Problem = null;
73            }
74            algorithm.Prepare(true);
75          }
76        }
77      }
78    }
79
80    public IEnumerable<IOptimizer> NestedOptimizers {
81      get {
82        // inner algorithm cannot be accessed directly
83        return Enumerable.Empty<IOptimizer>();
84      }
85    }
86
87    public override Image ItemImage {
88      get { return Algorithm.ItemImage; }
89    }
90
91    public static new Image StaticItemImage {
92      get { return HeuristicLab.Common.Resources.VSImageLibrary.Event; }
93    }
94
95    public string Name {
96      get { return Algorithm.Name; }
97      set { throw new NotSupportedException("Name cannot be changed."); }
98    }
99    public string Description {
100      get { return Algorithm.Description; }
101      set { throw new NotSupportedException("Description cannot be changed."); }
102    }
103    public bool CanChangeName {
104      get { return false; }
105    }
106    public bool CanChangeDescription {
107      get { return false; }
108    }
109
110    public IKeyedItemCollection<string, IParameter> Parameters {
111      get { return Algorithm.Parameters; }
112    }
113
114    public ExecutionState ExecutionState {
115      get { return Algorithm.ExecutionState; }
116    }
117    public TimeSpan ExecutionTime {
118      get { return Algorithm.ExecutionTime; }
119    }
120
121    public Type ProblemType {
122      get { return Algorithm.ProblemType; }
123    }
124    public IProblem Problem {
125      get { return Algorithm.Problem; }
126      set { Algorithm.Problem = value; }
127    }
128
129    public ResultCollection Results {
130      get { return Algorithm.Results; }
131    }
132
133    private RunCollection runs;
134    public RunCollection Runs {
135      get { return runs; }
136    }
137    private bool storeRunsAutomatically;
138    public bool StoreRunsAutomatically {
139      get { return storeRunsAutomatically; }
140      set {
141        if (value != storeRunsAutomatically) {
142          storeRunsAutomatically = value;
143          OnStoreRunsAutomaticallyChanged();
144        }
145      }
146    }
147    public bool StoreAlgorithmInEachRun {
148      get { return Algorithm.StoreAlgorithmInEachRun; }
149      set { Algorithm.StoreAlgorithmInEachRun = value; }
150    }
151
152    #region Persistence Properties
153    [Storable]
154    private Guid UserId;
155
156    [Storable(Name = "AlgorithmId")]
157    private long StorableAlgorithmId {
158      get { return algorithmId; }
159      set { algorithmId = value; }
160    }
161    [Storable(Name = "Algorithm")]
162    private IAlgorithm StorableAlgorithm {
163      get { return algorithm; }
164      set {
165        algorithm = value;
166        RegisterAlgorithmEvents();
167      }
168    }
169    [Storable(Name = "Runs")]
170    private RunCollection StorableRuns {
171      get { return runs; }
172      set {
173        runs = value;
174        RegisterRunsEvents();
175      }
176    }
177    [Storable(Name = "StoreRunsAutomatically")]
178    private bool StorableStoreRunsAutomatically {
179      get { return storeRunsAutomatically; }
180      set { storeRunsAutomatically = value; }
181    }
182    #endregion
183
184    [StorableConstructor]
185    private OKBAlgorithm(bool deserializing) : base(deserializing) { }
186    private OKBAlgorithm(OKBAlgorithm original, Cloner cloner)
187      : base(original, cloner) {
188      algorithmId = original.algorithmId;
189      algorithm = cloner.Clone(original.algorithm);
190      RegisterAlgorithmEvents();
191      runs = cloner.Clone(original.runs);
192      storeRunsAutomatically = original.storeRunsAutomatically;
193      UserId = original.UserId;
194      RegisterRunsEvents();
195    }
196    public OKBAlgorithm()
197      : base() {
198      algorithmId = -1;
199      algorithm = new EmptyAlgorithm("No algorithm selected. Please choose an algorithm from the OKB.");
200      RegisterAlgorithmEvents();
201      runs = new RunCollection();
202      storeRunsAutomatically = true;
203      RegisterRunsEvents();
204    }
205
206    private void CheckUserPermissions() {
207      if (UserInformation.Instance.UserExists) {
208        if (UserInformation.Instance.User.Roles.Count(x => x.Name == OKBRoles.OKBUser || x.Name == OKBRoles.OKBAdministrator) > 0) {
209          UserId = UserInformation.Instance.User.Id;
210        } else {
211          throw new Exception("You don't have the appropriate roles for executing OKB Algorithms.");
212        }
213      } else {
214        throw new Exception("You need an user account for executing OKB Algorithms.");
215      }
216    }
217
218    public override IDeepCloneable Clone(Cloner cloner) {
219      return new OKBAlgorithm(this, cloner);
220    }
221
222    public void Load(long algorithmId) {
223      if (this.algorithmId != algorithmId) {
224        IAlgorithm algorithm;
225        byte[] algorithmData = RunCreationClient.Instance.GetAlgorithmData(algorithmId);
226        using (MemoryStream stream = new MemoryStream(algorithmData)) {
227          algorithm = XmlParser.Deserialize<IAlgorithm>(stream);
228        }
229        this.algorithmId = algorithmId;
230        Algorithm = algorithm;
231      }
232    }
233
234    public IAlgorithm CloneAlgorithm() {
235      return (IAlgorithm)Algorithm.Clone();
236    }
237
238    public void CollectParameterValues(IDictionary<string, IItem> values) {
239      Algorithm.CollectParameterValues(values);
240    }
241    public void CollectResultValues(IDictionary<string, IItem> values) {
242      Algorithm.CollectResultValues(values);
243    }
244
245    public void Prepare() {
246      Algorithm.Prepare();
247    }
248    public void Prepare(bool clearRuns) {
249      if (clearRuns) runs.Clear();
250      Algorithm.Prepare(clearRuns);
251    }
252    public void Start() {
253      Start(CancellationToken.None);
254    }
255    public void Start(CancellationToken cancellationToken) {
256      CheckUserPermissions();
257      if (!ClientInformation.Instance.ClientExists && storeRunsAutomatically) {
258        throw new MissingClientRegistrationException();
259      }
260      Algorithm.Start(cancellationToken);
261    }
262    public async Task StartAsync() { await StartAsync(CancellationToken.None); }
263    public async Task StartAsync(CancellationToken cancellationToken) {
264      await AsyncHelper.DoAsync(Start, cancellationToken);
265    }
266    public void Pause() {
267      Algorithm.Pause();
268    }
269    public void Stop() {
270      Algorithm.Stop();
271    }
272
273    #region Events
274    public event EventHandler AlgorithmChanged;
275    private void OnAlgorithmChanged() {
276      EventHandler handler = AlgorithmChanged;
277      if (handler != null) handler(this, EventArgs.Empty);
278    }
279    public event EventHandler<CancelEventArgs<string>> NameChanging;
280    private void OnNameChanging(CancelEventArgs<string> e) {
281      var handler = NameChanging;
282      if (handler != null) handler(this, e);
283    }
284    public event EventHandler NameChanged;
285    private void OnNameChanged() {
286      var handler = NameChanged;
287      if (handler != null) handler(this, EventArgs.Empty);
288    }
289    public event EventHandler DescriptionChanged;
290    private void OnDescriptionChanged() {
291      var handler = DescriptionChanged;
292      if (handler != null) handler(this, EventArgs.Empty);
293    }
294    public event EventHandler ExecutionStateChanged;
295    private void OnExecutionStateChanged() {
296      var handler = ExecutionStateChanged;
297      if (handler != null) handler(this, EventArgs.Empty);
298    }
299    public event EventHandler ExecutionTimeChanged;
300    private void OnExecutionTimeChanged() {
301      var handler = ExecutionTimeChanged;
302      if (handler != null) handler(this, EventArgs.Empty);
303    }
304    public event EventHandler ProblemChanged;
305    private void OnProblemChanged() {
306      var handler = ProblemChanged;
307      if (handler != null) handler(this, EventArgs.Empty);
308    }
309    public event EventHandler StoreRunsAutomaticallyChanged;
310    private void OnStoreRunsAutomaticallyChanged() {
311      var handler = StoreRunsAutomaticallyChanged;
312      if (handler != null) handler(this, EventArgs.Empty);
313    }
314    public event EventHandler StoreAlgorithmInEachRunChanged;
315    private void OnStoreAlgorithmInEachRunChanged() {
316      var handler = StoreAlgorithmInEachRunChanged;
317      if (handler != null) handler(this, EventArgs.Empty);
318    }
319    public event EventHandler Prepared;
320    private void OnPrepared() {
321      var handler = Prepared;
322      if (handler != null) handler(this, EventArgs.Empty);
323    }
324    public event EventHandler Started;
325    private void OnStarted() {
326      var handler = Started;
327      if (handler != null) handler(this, EventArgs.Empty);
328    }
329    public event EventHandler Paused;
330    private void OnPaused() {
331      var handler = Paused;
332      if (handler != null) handler(this, EventArgs.Empty);
333    }
334    public event EventHandler Stopped;
335    private void OnStopped() {
336      var handler = Stopped;
337      if (handler != null) handler(this, EventArgs.Empty);
338    }
339    public event EventHandler<EventArgs<Exception>> ExceptionOccurred;
340    private void OnExceptionOccurred(Exception exception) {
341      var handler = ExceptionOccurred;
342      if (handler != null) handler(this, new EventArgs<Exception>(exception));
343    }
344
345    private void RegisterAlgorithmEvents() {
346      if (Algorithm != null) {
347        Algorithm.ToStringChanged += new EventHandler(Algorithm_ToStringChanged);
348        Algorithm.ItemImageChanged += new EventHandler(Algorithm_ItemImageChanged);
349        Algorithm.NameChanging += new EventHandler<CancelEventArgs<string>>(Algorithm_NameChanging);
350        Algorithm.NameChanged += new EventHandler(Algorithm_NameChanged);
351        Algorithm.DescriptionChanged += new EventHandler(Algorithm_DescriptionChanged);
352        Algorithm.ExecutionStateChanged += new EventHandler(Algorithm_ExecutionStateChanged);
353        Algorithm.ExecutionTimeChanged += new EventHandler(Algorithm_ExecutionTimeChanged);
354        Algorithm.ProblemChanged += new EventHandler(Algorithm_ProblemChanged);
355        Algorithm.Runs.ItemsAdded += new CollectionItemsChangedEventHandler<IRun>(Algorithm_Runs_ItemsAdded);
356        Algorithm.StoreAlgorithmInEachRunChanged += new EventHandler(Algorithm_StoreAlgorithmInEachRunChanged);
357        Algorithm.Prepared += new EventHandler(Algorithm_Prepared);
358        Algorithm.Started += new EventHandler(Algorithm_Started);
359        Algorithm.Paused += new EventHandler(Algorithm_Paused);
360        Algorithm.Stopped += new EventHandler(Algorithm_Stopped);
361        Algorithm.ExceptionOccurred += new EventHandler<EventArgs<Exception>>(Algorithm_ExceptionOccurred);
362      }
363    }
364    private void DeregisterAlgorithmEvents() {
365      if (Algorithm != null) {
366        Algorithm.ToStringChanged -= new EventHandler(Algorithm_ToStringChanged);
367        Algorithm.ItemImageChanged -= new EventHandler(Algorithm_ItemImageChanged);
368        Algorithm.NameChanging -= new EventHandler<CancelEventArgs<string>>(Algorithm_NameChanging);
369        Algorithm.NameChanged -= new EventHandler(Algorithm_NameChanged);
370        Algorithm.DescriptionChanged -= new EventHandler(Algorithm_DescriptionChanged);
371        Algorithm.ExecutionStateChanged -= new EventHandler(Algorithm_ExecutionStateChanged);
372        Algorithm.ExecutionTimeChanged -= new EventHandler(Algorithm_ExecutionTimeChanged);
373        Algorithm.ProblemChanged -= new EventHandler(Algorithm_ProblemChanged);
374        Algorithm.Runs.ItemsAdded -= new CollectionItemsChangedEventHandler<IRun>(Algorithm_Runs_ItemsAdded);
375        Algorithm.StoreAlgorithmInEachRunChanged -= new EventHandler(Algorithm_StoreAlgorithmInEachRunChanged);
376        Algorithm.Prepared -= new EventHandler(Algorithm_Prepared);
377        Algorithm.Started -= new EventHandler(Algorithm_Started);
378        Algorithm.Paused -= new EventHandler(Algorithm_Paused);
379        Algorithm.Stopped -= new EventHandler(Algorithm_Stopped);
380        Algorithm.ExceptionOccurred -= new EventHandler<EventArgs<Exception>>(Algorithm_ExceptionOccurred);
381      }
382    }
383
384    private void Algorithm_ToStringChanged(object sender, EventArgs e) {
385      OnToStringChanged();
386    }
387    private void Algorithm_ItemImageChanged(object sender, EventArgs e) {
388      OnItemImageChanged();
389    }
390    private void Algorithm_NameChanging(object sender, CancelEventArgs<string> e) {
391      OnNameChanging(e);
392    }
393    private void Algorithm_NameChanged(object sender, EventArgs e) {
394      OnNameChanged();
395    }
396    private void Algorithm_DescriptionChanged(object sender, EventArgs e) {
397      OnDescriptionChanged();
398    }
399    private void Algorithm_ExecutionStateChanged(object sender, EventArgs e) {
400      OnExecutionStateChanged();
401    }
402    private void Algorithm_ExecutionTimeChanged(object sender, EventArgs e) {
403      OnExecutionTimeChanged();
404    }
405    private void Algorithm_ProblemChanged(object sender, EventArgs e) {
406      OnProblemChanged();
407    }
408    private void Algorithm_Runs_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IRun> e) {
409      OKBProblem problem = Problem as OKBProblem;
410      foreach (IRun run in e.Items) {
411        if (problem != null) {
412          OKBRun okbRun = new OKBRun(AlgorithmId, problem.ProblemId, run, UserId);
413          runs.Add(okbRun);
414          if (StoreRunsAutomatically) {
415            okbRun.Store();
416          }
417        } else {
418          runs.Add(run);
419        }
420      }
421    }
422    private void Algorithm_StoreAlgorithmInEachRunChanged(object sender, EventArgs e) {
423      OnStoreAlgorithmInEachRunChanged();
424    }
425    private void Algorithm_Prepared(object sender, EventArgs e) {
426      OnPrepared();
427    }
428    private void Algorithm_Started(object sender, EventArgs e) {
429      OnStarted();
430    }
431    private void Algorithm_Paused(object sender, EventArgs e) {
432      OnPaused();
433    }
434    private void Algorithm_Stopped(object sender, EventArgs e) {
435      OnStopped();
436    }
437    private void Algorithm_ExceptionOccurred(object sender, EventArgs<Exception> e) {
438      OnExceptionOccurred(e.Value);
439    }
440
441    private void RegisterRunsEvents() {
442      runs.ItemsRemoved += new CollectionItemsChangedEventHandler<IRun>(runs_ItemsRemoved);
443      runs.CollectionReset += new CollectionItemsChangedEventHandler<IRun>(Runs_CollectionReset);
444    }
445    private void runs_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IRun> e) {
446      foreach (IRun run in e.Items) {
447        OKBRun okbRun = run as OKBRun;
448        if (okbRun != null)
449          Algorithm.Runs.Remove(okbRun.WrappedRun);
450        else
451          Algorithm.Runs.Remove(run);
452      }
453    }
454    private void Runs_CollectionReset(object sender, CollectionItemsChangedEventArgs<IRun> e) {
455      foreach (IRun run in e.OldItems) {
456        OKBRun okbRun = run as OKBRun;
457        if (okbRun != null)
458          Algorithm.Runs.Remove(okbRun.WrappedRun);
459        else
460          Algorithm.Runs.Remove(run);
461      }
462    }
463    #endregion
464  }
465}
Note: See TracBrowser for help on using the repository browser.