Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Optimization/3.3/BatchRun.cs @ 4791

Last change on this file since 4791 was 4722, checked in by swagner, 14 years ago

Merged cloning refactoring branch back into trunk (#922)

File size: 15.3 KB
RevLine 
[3226]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;
[4533]23using System.Collections.Generic;
[3226]24using System.Drawing;
[3716]25using HeuristicLab.Collections;
[3265]26using HeuristicLab.Common;
[3226]27using HeuristicLab.Core;
[3716]28using HeuristicLab.Data;
[3226]29using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
30
31namespace HeuristicLab.Optimization {
32  /// <summary>
33  /// A run in which an algorithm is executed a given number of times.
34  /// </summary>
35  [Item("Batch Run", "A run in which an algorithm is executed a given number of times.")]
36  [Creatable("Testing & Analysis")]
37  [StorableClass]
[4419]38  public sealed class BatchRun : NamedItem, IOptimizer, IStorableContent {
39    public string Filename { get; set; }
40
[3226]41    public override Image ItemImage {
[3351]42      get {
[3372]43        if (ExecutionState == ExecutionState.Prepared) return HeuristicLab.Common.Resources.VS2008ImageLibrary.ExecutablePrepared;
44        else if (ExecutionState == ExecutionState.Started) return HeuristicLab.Common.Resources.VS2008ImageLibrary.ExecutableStarted;
45        else if (ExecutionState == ExecutionState.Paused) return HeuristicLab.Common.Resources.VS2008ImageLibrary.ExecutablePaused;
46        else if (ExecutionState == ExecutionState.Stopped) return HeuristicLab.Common.Resources.VS2008ImageLibrary.ExecutableStopped;
[3351]47        else return HeuristicLab.Common.Resources.VS2008ImageLibrary.Event;
48      }
[3226]49    }
50
[3265]51    [Storable]
52    private ExecutionState executionState;
53    public ExecutionState ExecutionState {
54      get { return executionState; }
55      private set {
56        if (executionState != value) {
57          executionState = value;
58          OnExecutionStateChanged();
[3351]59          OnItemImageChanged();
[3265]60        }
61      }
62    }
63
64    [Storable]
65    private TimeSpan executionTime;
66    public TimeSpan ExecutionTime {
67      get {
68        if ((Algorithm != null) && (Algorithm.ExecutionState != ExecutionState.Stopped))
69          return executionTime + Algorithm.ExecutionTime;
70        else
71          return executionTime;
72      }
73      private set {
74        executionTime = value;
75        OnExecutionTimeChanged();
76      }
77    }
78
[3280]79    [Storable]
[3226]80    private IAlgorithm algorithm;
81    public IAlgorithm Algorithm {
82      get { return algorithm; }
83      set {
84        if (algorithm != value) {
[4115]85          if (algorithm != null) {
86            DeregisterAlgorithmEvents();
87            IEnumerable<IRun> runs = algorithm.Runs;
88            algorithm = null; //necessary to avoid removing the runs from the old algorithm
89            Runs.RemoveRange(runs);
90          }
[3226]91          algorithm = value;
[4115]92          if (algorithm != null) {
93            RegisterAlgorithmEvents();
94            Runs.AddRange(algorithm.Runs);
95          }
[3226]96          OnAlgorithmChanged();
[3716]97          Prepare();
[3226]98        }
99      }
100    }
101
102    [Storable]
103    private int repetitions;
104    public int Repetitions {
105      get { return repetitions; }
106      set {
107        if (repetitions != value) {
108          repetitions = value;
109          OnRepetitionsChanged();
[3716]110          if ((Algorithm != null) && (Algorithm.ExecutionState == ExecutionState.Stopped))
[3275]111            Prepare();
[3226]112        }
113      }
114    }
[3716]115    [Storable]
116    private int repetitionsCounter;
[3226]117
118    [Storable]
[3260]119    private RunCollection runs;
120    public RunCollection Runs {
121      get { return runs; }
[3716]122      private set {
123        if (value == null) throw new ArgumentNullException();
124        if (runs != value) {
125          if (runs != null) DeregisterRunsEvents();
126          runs = value;
127          if (runs != null) RegisterRunsEvents();
128        }
129      }
[3226]130    }
131
[3265]132    private bool stopPending;
[3226]133
134    public BatchRun()
135      : base() {
[3280]136      name = ItemName;
137      description = ItemDescription;
[3265]138      executionState = ExecutionState.Stopped;
139      executionTime = TimeSpan.Zero;
[3226]140      repetitions = 10;
[3716]141      repetitionsCounter = 0;
142      Runs = new RunCollection();
[3265]143      stopPending = false;
[3226]144    }
[3280]145    public BatchRun(string name)
146      : base(name) {
147      description = ItemDescription;
[3265]148      executionState = ExecutionState.Stopped;
149      executionTime = TimeSpan.Zero;
[3226]150      repetitions = 10;
[3716]151      repetitionsCounter = 0;
152      Runs = new RunCollection();
[3265]153      stopPending = false;
[3226]154    }
[3280]155    public BatchRun(string name, string description)
156      : base(name, description) {
[3265]157      executionState = ExecutionState.Stopped;
158      executionTime = TimeSpan.Zero;
[3226]159      repetitions = 10;
[3716]160      repetitionsCounter = 0;
161      Runs = new RunCollection();
[3265]162      stopPending = false;
[3226]163    }
[3280]164    [StorableConstructor]
165    private BatchRun(bool deserializing)
166      : base(deserializing) {
167      stopPending = false;
168    }
169    [StorableHook(HookType.AfterDeserialization)]
[4722]170    private void AfterDeserialization() {
171      Initialize();
[3280]172    }
173
[4722]174    private BatchRun(BatchRun original, Cloner cloner)
175      : base(original, cloner) {
176      executionState = original.executionState;
177      executionTime = original.executionTime;
178      algorithm = cloner.Clone(original.algorithm);
179      repetitions = original.repetitions;
180      repetitionsCounter = original.repetitionsCounter;
181      runs = cloner.Clone(original.runs);
182      stopPending = original.stopPending;
183      Initialize();
184    }
[3226]185    public override IDeepCloneable Clone(Cloner cloner) {
[3280]186      if (ExecutionState == ExecutionState.Started) throw new InvalidOperationException(string.Format("Clone not allowed in execution state \"{0}\".", ExecutionState));
[4722]187      return new BatchRun(this, cloner);
[3226]188    }
189
[4722]190    private void Initialize() {
191      if (algorithm != null) RegisterAlgorithmEvents();
192      if (runs != null) RegisterRunsEvents();
193    }
194
[3226]195    public void Prepare() {
[3275]196      Prepare(false);
[3226]197    }
[3275]198    public void Prepare(bool clearRuns) {
[3265]199      if ((ExecutionState != ExecutionState.Prepared) && (ExecutionState != ExecutionState.Paused) && (ExecutionState != ExecutionState.Stopped))
200        throw new InvalidOperationException(string.Format("Prepare not allowed in execution state \"{0}\".", ExecutionState));
[3261]201      if (Algorithm != null) {
[3716]202        repetitionsCounter = 0;
203        if (clearRuns) runs.Clear();
[3275]204        Algorithm.Prepare(clearRuns);
[3261]205      }
[3226]206    }
[3265]207    public void Start() {
208      if ((ExecutionState != ExecutionState.Prepared) && (ExecutionState != ExecutionState.Paused))
209        throw new InvalidOperationException(string.Format("Start not allowed in execution state \"{0}\".", ExecutionState));
210      if (Algorithm != null) Algorithm.Start();
211    }
212    public void Pause() {
213      if (ExecutionState != ExecutionState.Started)
214        throw new InvalidOperationException(string.Format("Pause not allowed in execution state \"{0}\".", ExecutionState));
[3716]215      if ((Algorithm != null) && (Algorithm.ExecutionState == ExecutionState.Started))
216        Algorithm.Pause();
[3265]217    }
[3226]218    public void Stop() {
[3265]219      if ((ExecutionState != ExecutionState.Started) && (ExecutionState != ExecutionState.Paused))
220        throw new InvalidOperationException(string.Format("Stop not allowed in execution state \"{0}\".", ExecutionState));
221      stopPending = true;
[3716]222      if ((Algorithm != null) &&
223          ((Algorithm.ExecutionState == ExecutionState.Started) || (Algorithm.ExecutionState == ExecutionState.Paused)))
224        Algorithm.Stop();
[3226]225    }
226
227    #region Events
[3265]228    public event EventHandler ExecutionStateChanged;
229    private void OnExecutionStateChanged() {
230      EventHandler handler = ExecutionStateChanged;
231      if (handler != null) handler(this, EventArgs.Empty);
232    }
233    public event EventHandler ExecutionTimeChanged;
234    private void OnExecutionTimeChanged() {
235      EventHandler handler = ExecutionTimeChanged;
236      if (handler != null) handler(this, EventArgs.Empty);
237    }
[3226]238    public event EventHandler AlgorithmChanged;
239    private void OnAlgorithmChanged() {
[3265]240      EventHandler handler = AlgorithmChanged;
241      if (handler != null) handler(this, EventArgs.Empty);
[3226]242    }
243    public event EventHandler RepetitionsChanged;
244    private void OnRepetitionsChanged() {
[3265]245      EventHandler handler = RepetitionsChanged;
246      if (handler != null) handler(this, EventArgs.Empty);
[3226]247    }
248    public event EventHandler Prepared;
249    private void OnPrepared() {
[3265]250      ExecutionState = ExecutionState.Prepared;
251      EventHandler handler = Prepared;
252      if (handler != null) handler(this, EventArgs.Empty);
[3226]253    }
254    public event EventHandler Started;
255    private void OnStarted() {
[3265]256      ExecutionState = ExecutionState.Started;
257      EventHandler handler = Started;
258      if (handler != null) handler(this, EventArgs.Empty);
[3226]259    }
[3265]260    public event EventHandler Paused;
261    private void OnPaused() {
262      ExecutionState = ExecutionState.Paused;
263      EventHandler handler = Paused;
264      if (handler != null) handler(this, EventArgs.Empty);
265    }
[3226]266    public event EventHandler Stopped;
267    private void OnStopped() {
[3265]268      ExecutionState = ExecutionState.Stopped;
269      EventHandler handler = Stopped;
270      if (handler != null) handler(this, EventArgs.Empty);
[3226]271    }
[3265]272    public event EventHandler<EventArgs<Exception>> ExceptionOccurred;
[3226]273    private void OnExceptionOccurred(Exception exception) {
[3265]274      EventHandler<EventArgs<Exception>> handler = ExceptionOccurred;
275      if (handler != null) handler(this, new EventArgs<Exception>(exception));
[3226]276    }
277
[3261]278    private void RegisterAlgorithmEvents() {
[3265]279      algorithm.ExceptionOccurred += new EventHandler<EventArgs<Exception>>(Algorithm_ExceptionOccurred);
280      algorithm.ExecutionTimeChanged += new EventHandler(Algorithm_ExecutionTimeChanged);
281      algorithm.Paused += new EventHandler(Algorithm_Paused);
282      algorithm.Prepared += new EventHandler(Algorithm_Prepared);
[3261]283      algorithm.Started += new EventHandler(Algorithm_Started);
284      algorithm.Stopped += new EventHandler(Algorithm_Stopped);
[3280]285      algorithm.Runs.CollectionReset += new CollectionItemsChangedEventHandler<IRun>(Algorithm_Runs_CollectionReset);
286      algorithm.Runs.ItemsAdded += new CollectionItemsChangedEventHandler<IRun>(Algorithm_Runs_ItemsAdded);
287      algorithm.Runs.ItemsRemoved += new CollectionItemsChangedEventHandler<IRun>(Algorithm_Runs_ItemsRemoved);
[3261]288    }
[3226]289    private void DeregisterAlgorithmEvents() {
[3265]290      algorithm.ExceptionOccurred -= new EventHandler<EventArgs<Exception>>(Algorithm_ExceptionOccurred);
291      algorithm.ExecutionTimeChanged -= new EventHandler(Algorithm_ExecutionTimeChanged);
292      algorithm.Paused -= new EventHandler(Algorithm_Paused);
293      algorithm.Prepared -= new EventHandler(Algorithm_Prepared);
[3261]294      algorithm.Started -= new EventHandler(Algorithm_Started);
295      algorithm.Stopped -= new EventHandler(Algorithm_Stopped);
[3280]296      algorithm.Runs.CollectionReset -= new CollectionItemsChangedEventHandler<IRun>(Algorithm_Runs_CollectionReset);
297      algorithm.Runs.ItemsAdded -= new CollectionItemsChangedEventHandler<IRun>(Algorithm_Runs_ItemsAdded);
298      algorithm.Runs.ItemsRemoved -= new CollectionItemsChangedEventHandler<IRun>(Algorithm_Runs_ItemsRemoved);
[3226]299    }
[3265]300    private void Algorithm_ExceptionOccurred(object sender, EventArgs<Exception> e) {
[3261]301      OnExceptionOccurred(e.Value);
[3226]302    }
[3265]303    private void Algorithm_ExecutionTimeChanged(object sender, EventArgs e) {
304      OnExecutionTimeChanged();
305    }
306    private void Algorithm_Paused(object sender, EventArgs e) {
307      OnPaused();
308    }
309    private void Algorithm_Prepared(object sender, EventArgs e) {
[3276]310      if ((ExecutionState == ExecutionState.Paused) || (ExecutionState == ExecutionState.Stopped))
311        OnPrepared();
[3265]312    }
[3261]313    private void Algorithm_Started(object sender, EventArgs e) {
[3265]314      stopPending = false;
[3276]315      if (ExecutionState != ExecutionState.Started)
316        OnStarted();
[3261]317    }
318    private void Algorithm_Stopped(object sender, EventArgs e) {
[3716]319      repetitionsCounter++;
[3265]320
[3716]321      if (!stopPending && (repetitionsCounter < repetitions)) {
[3261]322        Algorithm.Prepare();
[3265]323        Algorithm.Start();
[3276]324      } else {
325        OnStopped();
[3226]326      }
327    }
[3280]328    private void Algorithm_Runs_CollectionReset(object sender, CollectionItemsChangedEventArgs<IRun> e) {
[3275]329      Runs.RemoveRange(e.OldItems);
330      Runs.AddRange(e.Items);
331    }
[3280]332    private void Algorithm_Runs_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IRun> e) {
[3275]333      Runs.AddRange(e.Items);
334    }
[3280]335    private void Algorithm_Runs_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IRun> e) {
[3275]336      Runs.RemoveRange(e.Items);
337    }
[3716]338
339    private void RegisterRunsEvents() {
340      runs.CollectionReset += new CollectionItemsChangedEventHandler<IRun>(Runs_CollectionReset);
[4115]341      runs.ItemsAdded += new CollectionItemsChangedEventHandler<IRun>(Runs_ItemsAdded);
[3716]342      runs.ItemsRemoved += new CollectionItemsChangedEventHandler<IRun>(Runs_ItemsRemoved);
343    }
[4115]344
[3716]345    private void DeregisterRunsEvents() {
346      runs.CollectionReset -= new CollectionItemsChangedEventHandler<IRun>(Runs_CollectionReset);
[4115]347      runs.ItemsAdded -= new CollectionItemsChangedEventHandler<IRun>(Runs_ItemsAdded);
[3716]348      runs.ItemsRemoved -= new CollectionItemsChangedEventHandler<IRun>(Runs_ItemsRemoved);
349    }
350    private void Runs_CollectionReset(object sender, CollectionItemsChangedEventArgs<IRun> e) {
351      foreach (IRun run in e.OldItems) {
352        IItem item;
353        run.Results.TryGetValue("Execution Time", out item);
354        TimeSpanValue executionTime = item as TimeSpanValue;
355        if (executionTime != null) ExecutionTime -= executionTime.Value;
356      }
357      if (Algorithm != null) Algorithm.Runs.RemoveRange(e.OldItems);
358      foreach (IRun run in e.Items) {
359        IItem item;
360        run.Results.TryGetValue("Execution Time", out item);
361        TimeSpanValue executionTime = item as TimeSpanValue;
362        if (executionTime != null) ExecutionTime += executionTime.Value;
363      }
364    }
[4115]365    private void Runs_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IRun> e) {
366      foreach (IRun run in e.Items) {
367        IItem item;
368        run.Results.TryGetValue("Execution Time", out item);
369        TimeSpanValue executionTime = item as TimeSpanValue;
370        if (executionTime != null) ExecutionTime += executionTime.Value;
371      }
372    }
[3716]373    private void Runs_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IRun> e) {
374      foreach (IRun run in e.Items) {
375        IItem item;
376        run.Results.TryGetValue("Execution Time", out item);
377        TimeSpanValue executionTime = item as TimeSpanValue;
378        if (executionTime != null) ExecutionTime -= executionTime.Value;
379      }
380      if (Algorithm != null) Algorithm.Runs.RemoveRange(e.Items);
381    }
[3226]382    #endregion
383  }
384}
Note: See TracBrowser for help on using the repository browser.