#region License Information /* HeuristicLab * Copyright (C) 2002-2010 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 HeuristicLab.Common; using HeuristicLab.Core; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; namespace HeuristicLab.DebugEngine { [StorableClass] [Item("Debug Engine", "Engine for debugging algorithms.")] public class DebugEngine : Engine { private IOperator currentOperator; [StorableConstructor] protected DebugEngine(bool deserializing) : base(deserializing) { } protected DebugEngine(DebugEngine original, Cloner cloner) : base(original, cloner) { } public DebugEngine() : base() { } public new Stack ExecutionStack { get { return base.ExecutionStack; } } public IAtomicOperation CurrentOperation { get; private set; } public override IDeepCloneable Clone(Cloner cloner) { return new DebugEngine(this, cloner); } /// /// Deals with the next operation, if it is an it is executed, /// if it is a its single operations are pushed on the execution stack. /// /// If an error occurs during the execution the operation is aborted and the operation /// is pushed on the stack again.
/// If the execution was successful is called.
protected override void ProcessNextOperation() { currentOperator = null; IOperation next = ExecutionStack.Pop(); OperationCollection coll = next as OperationCollection; while (coll != null) { Log.LogMessage("Expanding OperationCollection"); for (int i = coll.Count - 1; i >= 0; i--) { ExecutionStack.Push(coll[i]); } next = ExecutionStack.Count > 0 ? ExecutionStack.Pop() : null; coll = next as OperationCollection; } IAtomicOperation operation = next as IAtomicOperation; if (operation != null) { Log.LogMessage("Preparing IAtomicOperation"); try { currentOperator = operation.Operator; CurrentOperation = operation; if (operation.Operator.Breakpoint) { Log.LogMessage(string.Format("Breakpoint: Before {0}", operation.Operator.Name != string.Empty ? operation.Operator.Name : operation.Operator.ItemName)); Pause(); } Log.LogMessage("Executing IAtomicOperation"); ExecutionStack.Push(operation.Operator.Execute((IExecutionContext)operation)); } catch (Exception ex) { OnExceptionOccurred(new OperatorExecutionException(operation.Operator, ex)); Pause(); } } else { Log.LogMessage("Nothing to do"); CurrentOperation = null; } } public override void Pause() { base.Pause(); if (currentOperator != null) currentOperator.Abort(); } public override void Stop() { base.Stop(); if (currentOperator != null) currentOperator.Abort(); } public virtual void Step() { OnStarted(); var lastUpdateTime = DateTime.Now; if (ExecutionStack.Count > 0) { while (ExecutionStack.Count > 0 && ExecutionStack.Peek() == null) ExecutionStack.Pop(); if (ExecutionStack.Count > 0) ProcessNextOperation(); } ExecutionTime += DateTime.Now - lastUpdateTime; OnPaused(); } } }