#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 System.Drawing; 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. /// [Item("Engine", "A base class for engines.")] public abstract class Engine : Item, IEngine { public override Image ItemImage { get { return HeuristicLab.Common.Resources.VS2008ImageLibrary.Event; } } /// /// Field of the current instance that represent the operator graph. /// private OperatorGraph operatorGraph; /// /// Gets the current operator graph. /// [Storable] public OperatorGraph OperatorGraph { get { return operatorGraph; } set { if (value == null) throw new ArgumentNullException(); if (value != operatorGraph) { if (operatorGraph != null) operatorGraph.InitialOperatorChanged -= new EventHandler(operatorGraph_InitialOperatorChanged); operatorGraph = value; if (operatorGraph != null) operatorGraph.InitialOperatorChanged += new EventHandler(operatorGraph_InitialOperatorChanged); OnOperatorGraphChanged(); Initialize(); } } } /// /// Field of the current instance that represent the global scope. /// [Storable] private Scope globalScope; /// /// Gets the current global scope. /// public IScope GlobalScope { get { return globalScope; } } [Storable] private TimeSpan executionTime; /// /// Gets or sets the execution time. /// /// Calls in the setter. public TimeSpan ExecutionTime { get { return executionTime; } protected set { executionTime = value; OnExecutionTimeChanged(); } } /// /// Field of the current instance that represent the execution stack. /// [Storable] private Stack executionStack; /// /// Gets the current execution stack. /// protected Stack ExecutionStack { get { return executionStack; } } /// /// Flag of the current instance whether it is currently running. /// private bool running; /// /// Gets information whether the instance is currently running. /// public bool Running { get { return running; } } /// /// Flag of the current instance whether it is canceled. /// private bool canceled; /// /// Gets information whether the instance is currently canceled. /// protected bool Canceled { get { return canceled; } } /// /// Gets information whether the instance has already terminated. /// public bool Finished { get { return executionStack.Count == 0; } } /// /// Initializes a new instance of with a new global scope. /// /// Calls . protected Engine() { globalScope = new Scope("Global"); executionStack = new Stack(); OperatorGraph = new OperatorGraph(); } /// /// 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 IDeepCloneable Clone(Cloner cloner) { Engine clone = (Engine)base.Clone(cloner); clone.OperatorGraph = (OperatorGraph)cloner.Clone(operatorGraph); clone.globalScope = (Scope)cloner.Clone(globalScope); clone.executionTime = executionTime; ExecutionContext[] contexts = executionStack.ToArray(); for (int i = contexts.Length - 1; i >= 0; i--) clone.executionStack.Push((ExecutionContext)cloner.Clone(contexts[i])); clone.running = running; clone.canceled = canceled; return clone; } /// /// 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 void Initialize() { canceled = false; running = false; globalScope.Clear(); ExecutionTime = new TimeSpan(); executionStack.Clear(); if (OperatorGraph.InitialOperator != null) executionStack.Push(new ExecutionContext(null, OperatorGraph.InitialOperator, GlobalScope)); OnInitialized(); } /// /// Calls /// of class . public void Start() { running = true; canceled = false; ThreadPool.QueueUserWorkItem(new WaitCallback(Run), null); } /// /// Calls /// of class . public void Step() { running = true; canceled = false; ThreadPool.QueueUserWorkItem(new WaitCallback(RunStep), null); } /// /// Sets the protected flag myCanceled to true. public virtual void Stop() { canceled = true; } private void Run(object state) { OnStarted(); DateTime start = DateTime.Now; DateTime end; while ((!Canceled) && (!Finished)) { ProcessNextOperator(); end = DateTime.Now; ExecutionTime += end - start; start = end; } ExecutionTime += DateTime.Now - start; running = false; OnStopped(); } private void RunStep(object state) { OnStarted(); DateTime start = DateTime.Now; if ((!Canceled) && (!Finished)) ProcessNextOperator(); ExecutionTime += DateTime.Now - start; running = false; OnStopped(); } /// /// Performs the next operation. /// protected abstract void ProcessNextOperator(); private void operatorGraph_InitialOperatorChanged(object sender, EventArgs e) { Initialize(); } public event EventHandler OperatorGraphChanged; protected virtual void OnOperatorGraphChanged() { if (OperatorGraphChanged != null) OperatorGraphChanged(this, EventArgs.Empty); } /// /// 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 initialized. /// public event EventHandler Initialized; /// /// Fires a new Initialized event. /// protected virtual void OnInitialized() { if (Initialized != null) Initialized(this, new EventArgs()); } /// /// Occurs when the execution is executed. /// public event EventHandler Started; /// /// Fires a new Started event. /// protected virtual void OnStarted() { if (Started != null) Started(this, new EventArgs()); } /// /// Occurs when the execution is finished. /// public event EventHandler Stopped; /// /// Fires a new Stopped event. /// protected virtual void OnStopped() { if (Stopped != null) Stopped(this, new EventArgs()); } /// /// 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) { if (ExceptionOccurred != null) ExceptionOccurred(this, new EventArgs(exception)); } } }