#region License Information /* HeuristicLab * Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL) * * This file is part of HeuristicLab. * * HeuristicLab is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HeuristicLab is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with HeuristicLab. If not, see . */ #endregion using System; using System.Collections.Generic; using System.Text; using System.Xml; using System.Threading; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; using HeuristicLab.Common; namespace HeuristicLab.Core { /// /// Base class to represent an engine, which is an interpreter, holding the code, the data and /// the actual state, which is the runtime stack and a pointer onto the next operation. It represents /// one execution and can handle parallel executions. /// public abstract class EngineBase : ItemBase, IEngine { /// /// Field of the current instance that represent the operator graph. /// [Storable] protected IOperatorGraph myOperatorGraph; /// /// Gets the current operator graph. /// public IOperatorGraph OperatorGraph { get { return myOperatorGraph; } } /// /// Field of the current instance that represent the global scope. /// [Storable] protected IScope myGlobalScope; /// /// Gets the current global scope. /// public IScope GlobalScope { get { return myGlobalScope; } } [Storable] private TimeSpan myExecutionTime; /// /// Gets or sets the execution time. /// /// Calls in the setter. public TimeSpan ExecutionTime { get { return myExecutionTime; } protected set { myExecutionTime = value; OnExecutionTimeChanged(); } } /// /// Field of the current instance that represent the execution stack. /// [Storable] protected Stack myExecutionStack; /// /// Gets the current execution stack. /// public Stack ExecutionStack { get { return myExecutionStack; } } /// /// Flag of the current instance whether it is currently running. /// protected bool myRunning; /// /// Gets information whether the instance is currently running. /// public bool Running { get { return myRunning; } } /// /// Flag of the current instance whether it is canceled. /// protected bool myCanceled; /// /// Gets information whether the instance is currently canceled. /// public bool Canceled { get { return myCanceled; } } /// /// Gets information whether the instance has already terminated. /// public virtual bool Terminated { get { return ExecutionStack.Count == 0; } } /// /// Initializes a new instance of with a new global scope. /// /// Calls . protected EngineBase() { myOperatorGraph = new OperatorGraph(); myGlobalScope = new Scope("Global"); myExecutionStack = new Stack(); Reset(); } /// /// Clones the current instance (deep clone). /// /// Deep clone through method of helper class /// . /// Dictionary of all already clone objects. (Needed to avoid cycles.) /// The cloned object as . public override object Clone(IDictionary clonedObjects) { EngineBase clone = (EngineBase)base.Clone(clonedObjects); clone.myOperatorGraph = (IOperatorGraph)Auxiliary.Clone(OperatorGraph, clonedObjects); clone.myGlobalScope = (IScope)Auxiliary.Clone(GlobalScope, clonedObjects); clone.myExecutionTime = ExecutionTime; IOperation[] operations = new IOperation[ExecutionStack.Count]; ExecutionStack.CopyTo(operations, 0); for (int i = operations.Length - 1; i >= 0; i--) clone.myExecutionStack.Push((IOperation)Auxiliary.Clone(operations[i], clonedObjects)); clone.myRunning = Running; clone.myCanceled = Canceled; return clone; } /// /// Calls /// of class . public virtual void Execute() { myRunning = true; myCanceled = false; ThreadPool.QueueUserWorkItem(new WaitCallback(Run), null); } /// /// Calls /// of class . public virtual void ExecuteSteps(int steps) { myRunning = true; myCanceled = false; ThreadPool.QueueUserWorkItem(new WaitCallback(Run), steps); } /// /// Calls /// of class . public void ExecuteStep() { ExecuteSteps(1); } /// /// Sets the protected flag myCanceled to true. public virtual void Abort() { myCanceled = true; } /// /// Sets myCanceled and myRunning to false. The global scope is cleared, /// the execution time is reseted, the execution stack is cleared and a new /// with the initial operator is added.
/// Calls .
public virtual void Reset() { myCanceled = false; myRunning = false; GlobalScope.Clear(); ExecutionTime = new TimeSpan(); myExecutionStack.Clear(); if (OperatorGraph.InitialOperator != null) myExecutionStack.Push(new AtomicOperation(OperatorGraph.InitialOperator, GlobalScope)); OnInitialized(); } private void Run(object state) { if (state == null) Run(); else RunSteps((int)state); myRunning = false; OnFinished(); } private void Run() { DateTime start = DateTime.Now; DateTime end; while ((!Canceled) && (!Terminated)) { ProcessNextOperation(); end = DateTime.Now; ExecutionTime += end - start; start = end; } ExecutionTime += DateTime.Now - start; } private void RunSteps(int steps) { DateTime start = DateTime.Now; DateTime end; int step = 0; while ((!Canceled) && (!Terminated) && (step < steps)) { ProcessNextOperation(); step++; end = DateTime.Now; ExecutionTime += end - start; start = end; } ExecutionTime += DateTime.Now - start; } /// /// Performs the next operation. /// protected abstract void ProcessNextOperation(); /// /// Occurs when the current instance is initialized. /// public event EventHandler Initialized; /// /// Fires a new Initialized event. /// protected virtual void OnInitialized() { if (Initialized != null) Initialized(this, new EventArgs()); } /// /// Occurs when an operation is executed. /// public event EventHandler> OperationExecuted; /// /// Fires a new OperationExecuted event. /// /// The operation that has been executed. protected virtual void OnOperationExecuted(IOperation operation) { if (OperationExecuted != null) OperationExecuted(this, new EventArgs(operation)); } /// /// Occurs when an exception occured during the execution. /// public event EventHandler> ExceptionOccurred; /// /// Aborts the execution and fires a new ExceptionOccurred event. /// /// The exception that was thrown. protected virtual void OnExceptionOccurred(Exception exception) { Abort(); if (ExceptionOccurred != null) ExceptionOccurred(this, new EventArgs(exception)); } /// /// Occurs when the execution time changed. /// public event EventHandler ExecutionTimeChanged; /// /// Fires a new ExecutionTimeChanged event. /// protected virtual void OnExecutionTimeChanged() { if (ExecutionTimeChanged != null) ExecutionTimeChanged(this, new EventArgs()); } /// /// Occurs when the execution is finished. /// public event EventHandler Finished; /// /// Fires a new Finished event. /// protected virtual void OnFinished() { if (Finished != null) Finished(this, new EventArgs()); } } }