Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Core/3.3/EngineBase.cs @ 1667

Last change on this file since 1667 was 1667, checked in by epitzer, 15 years ago

Convert persistence of Core plugin to new persistence framework. The target framework has been upgraded from 2.0 to 3.5 and events during persistence are not generated anymore. (#603)

File size: 10.0 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2008 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.Text;
25using System.Xml;
26using System.Threading;
27using HeuristicLab.Persistence.Default.Decomposers.Storable;
28
29namespace HeuristicLab.Core {
30  /// <summary>
31  /// Base class to represent an engine, which is an interpreter, holding the code, the data and
32  /// the actual state, which is the runtime stack and a pointer onto the next operation. It represents
33  /// one execution and can handle parallel executions.
34  /// </summary>
35  public abstract class EngineBase : ItemBase, IEngine {
36
37    /// <summary>
38    /// Field of the current instance that represent the operator graph.
39    /// </summary>
40    [Storable]
41    protected IOperatorGraph myOperatorGraph;
42    /// <summary>
43    /// Gets the current operator graph.
44    /// </summary>
45    public IOperatorGraph OperatorGraph {
46      get { return myOperatorGraph; }
47    }
48    /// <summary>
49    /// Field of the current instance that represent the global scope.
50    /// </summary>
51    [Storable]
52    protected IScope myGlobalScope;
53    /// <summary>
54    /// Gets the current global scope.
55    /// </summary>
56    public IScope GlobalScope {
57      get { return myGlobalScope; }
58    }
59
60    [Storable]
61    private TimeSpan myExecutionTime;
62    /// <summary>
63    /// Gets or sets the execution time.
64    /// </summary>
65    /// <remarks>Calls <see cref="OnExecutionTimeChanged"/> in the setter.</remarks>
66    public TimeSpan ExecutionTime {
67      get { return myExecutionTime; }
68      protected set {
69        myExecutionTime = value;
70        OnExecutionTimeChanged();
71      }
72    }
73
74    /// <summary>
75    /// Field of the current instance that represent the execution stack.
76    /// </summary>
77    [Storable]
78    protected Stack<IOperation> myExecutionStack;
79    /// <summary>
80    /// Gets the current execution stack.
81    /// </summary>
82    public Stack<IOperation> ExecutionStack {
83      get { return myExecutionStack; }
84    }
85
86    /// <summary>
87    /// Flag of the current instance whether it is currently running.
88    /// </summary>
89    protected bool myRunning;
90    /// <summary>
91    /// Gets information whether the instance is currently running.
92    /// </summary>
93    public bool Running {
94      get { return myRunning; }
95    }
96
97    /// <summary>
98    /// Flag of the current instance whether it is canceled.
99    /// </summary>
100    protected bool myCanceled;
101    /// <summary>
102    /// Gets information whether the instance is currently canceled.
103    /// </summary>
104    public bool Canceled {
105      get { return myCanceled; }
106    }
107    /// <summary>
108    /// Gets information whether the instance has already terminated.
109    /// </summary>
110    public virtual bool Terminated {
111      get { return ExecutionStack.Count == 0; }
112    }
113
114    /// <summary>
115    /// Initializes a new instance of <see cref="EngineBase"/> with a new global scope.
116    /// </summary>
117    /// <remarks>Calls <see cref="Reset"/>.</remarks>
118    protected EngineBase() {
119      myOperatorGraph = new OperatorGraph();
120      myGlobalScope = new Scope("Global");
121      myExecutionStack = new Stack<IOperation>();
122      Reset();
123    }
124
125    /// <summary>
126    /// Clones the current instance (deep clone).
127    /// </summary>
128    /// <remarks>Deep clone through <see cref="Auxiliary.Clone"/> method of helper class
129    /// <see cref="Auxiliary"/>.</remarks>
130    /// <param name="clonedObjects">Dictionary of all already clone objects. (Needed to avoid cycles.)</param>
131    /// <returns>The cloned object as <see cref="EngineBase"/>.</returns>
132    public override object Clone(IDictionary<Guid, object> clonedObjects) {
133      EngineBase clone = (EngineBase)base.Clone(clonedObjects);
134      clone.myOperatorGraph = (IOperatorGraph)Auxiliary.Clone(OperatorGraph, clonedObjects);
135      clone.myGlobalScope = (IScope)Auxiliary.Clone(GlobalScope, clonedObjects);
136      clone.myExecutionTime = ExecutionTime;
137      IOperation[] operations = new IOperation[ExecutionStack.Count];
138      ExecutionStack.CopyTo(operations, 0);
139      for (int i = operations.Length - 1; i >= 0; i--)
140        clone.myExecutionStack.Push((IOperation)Auxiliary.Clone(operations[i], clonedObjects));
141      clone.myRunning = Running;
142      clone.myCanceled = Canceled;
143      return clone;
144    }
145
146    /// <inheritdoc/>
147    /// <remarks>Calls <see cref="ThreadPool.QueueUserWorkItem(System.Threading.WaitCallback, object)"/>
148    /// of class <see cref="ThreadPool"/>.</remarks>
149    public virtual void Execute() {
150      myRunning = true;
151      myCanceled = false;
152      ThreadPool.QueueUserWorkItem(new WaitCallback(Run), null);
153    }
154    /// <inheritdoc/>
155    /// <remarks>Calls <see cref="ThreadPool.QueueUserWorkItem(System.Threading.WaitCallback, object)"/>
156    /// of class <see cref="ThreadPool"/>.</remarks>
157    public virtual void ExecuteSteps(int steps) {
158      myRunning = true;
159      myCanceled = false;
160      ThreadPool.QueueUserWorkItem(new WaitCallback(Run), steps);
161    }
162    /// <inheritdoc/>
163    /// <remarks>Calls <see cref="ThreadPool.QueueUserWorkItem(System.Threading.WaitCallback, object)"/>
164    /// of class <see cref="ThreadPool"/>.</remarks>
165    public void ExecuteStep() {
166      ExecuteSteps(1);
167    }
168    /// <inheritdoc/>
169    /// <remarks>Sets the protected flag <c>myCanceled</c> to <c>true</c>.</remarks>
170    public virtual void Abort() {
171      myCanceled = true;
172    }
173    /// <inheritdoc/>
174    /// <remarks>Sets <c>myCanceled</c> and <c>myRunning</c> to <c>false</c>. The global scope is cleared,
175    /// the execution time is reseted, the execution stack is cleared and a new <see cref="AtomicOperation"/>
176    /// with the initial operator is added. <br/>
177    /// Calls <see cref="OnInitialized"/>.</remarks>
178    public virtual void Reset() {
179      myCanceled = false;
180      myRunning = false;
181      GlobalScope.Clear();
182      ExecutionTime = new TimeSpan();
183      myExecutionStack.Clear();
184      if (OperatorGraph.InitialOperator != null)
185        myExecutionStack.Push(new AtomicOperation(OperatorGraph.InitialOperator, GlobalScope));
186      OnInitialized();
187    }
188
189    private void Run(object state) {
190      if (state == null) Run();
191      else RunSteps((int)state);
192      myRunning = false;
193      OnFinished();
194    }
195    private void Run() {
196      DateTime start = DateTime.Now;
197      DateTime end;
198      while ((!Canceled) && (!Terminated)) {
199        ProcessNextOperation();
200        end = DateTime.Now;
201        ExecutionTime += end - start;
202        start = end;
203      }
204      ExecutionTime += DateTime.Now - start;
205    }
206    private void RunSteps(int steps) {
207      DateTime start = DateTime.Now;
208      DateTime end;
209      int step = 0;
210      while ((!Canceled) && (!Terminated) && (step < steps)) {
211        ProcessNextOperation();
212        step++;
213        end = DateTime.Now;
214        ExecutionTime += end - start;
215        start = end;
216      }
217      ExecutionTime += DateTime.Now - start;
218    }
219
220    /// <summary>
221    /// Performs the next operation.
222    /// </summary>
223    protected abstract void ProcessNextOperation();
224
225    /// <summary>
226    /// Occurs when the current instance is initialized.
227    /// </summary>
228    public event EventHandler Initialized;
229    /// <summary>
230    /// Fires a new <c>Initialized</c> event.
231    /// </summary>
232    protected virtual void OnInitialized() {
233      if (Initialized != null)
234        Initialized(this, new EventArgs());
235    }
236    /// <summary>
237    /// Occurs when an operation is executed.
238    /// </summary>
239    public event EventHandler<OperationEventArgs> OperationExecuted;
240    /// <summary>
241    /// Fires a new <c>OperationExecuted</c> event.
242    /// </summary>
243    /// <param name="operation">The operation that has been executed.</param>
244    protected virtual void OnOperationExecuted(IOperation operation) {
245      if (OperationExecuted != null)
246        OperationExecuted(this, new OperationEventArgs(operation));
247    }
248    /// <summary>
249    /// Occurs when an exception occured during the execution.
250    /// </summary>
251    public event EventHandler<ExceptionEventArgs> ExceptionOccurred;
252    /// <summary>
253    /// Aborts the execution and fires a new <c>ExceptionOccurred</c> event.
254    /// </summary>
255    /// <param name="exception">The exception that was thrown.</param>
256    protected virtual void OnExceptionOccurred(Exception exception) {
257      Abort();
258      if (ExceptionOccurred != null)
259        ExceptionOccurred(this, new ExceptionEventArgs(exception));
260    }
261    /// <summary>
262    /// Occurs when the execution time changed.
263    /// </summary>
264    public event EventHandler ExecutionTimeChanged;
265    /// <summary>
266    /// Fires a new <c>ExecutionTimeChanged</c> event.
267    /// </summary>
268    protected virtual void OnExecutionTimeChanged() {
269      if (ExecutionTimeChanged != null)
270        ExecutionTimeChanged(this, new EventArgs());
271    }
272    /// <summary>
273    /// Occurs when the execution is finished.
274    /// </summary>
275    public event EventHandler Finished;
276    /// <summary>
277    /// Fires a new <c>Finished</c> event.
278    /// </summary>
279    protected virtual void OnFinished() {
280      if (Finished != null)
281        Finished(this, new EventArgs());
282    }
283  }
284}
Note: See TracBrowser for help on using the repository browser.