Changeset 4871 for branches/HeuristicLab.DebugEngine/DebugEngine.cs
- Timestamp:
- 11/20/10 14:13:32 (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/HeuristicLab.DebugEngine/DebugEngine.cs
r4827 r4871 21 21 22 22 using System; 23 using System.Linq; 23 24 using System.Collections.Generic; 24 25 using HeuristicLab.Common; 25 26 using HeuristicLab.Core; 26 27 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; 28 using HeuristicLab.Collections; 29 using System.Threading; 27 30 28 31 namespace HeuristicLab.DebugEngine { … … 30 33 [StorableClass] 31 34 [Item("Debug Engine", "Engine for debugging algorithms.")] 32 public class DebugEngine : Engine { 33 private IOperator currentOperator; 34 35 public class DebugEngine : Executable, IEngine { 36 37 38 #region Construction and Cloning 39 35 40 [StorableConstructor] 36 protected DebugEngine(bool deserializing) : base(deserializing) { } 37 protected DebugEngine(DebugEngine original, Cloner cloner) : base(original, cloner) { } 41 protected DebugEngine(bool deserializing) : base(deserializing) { 42 pausePending = stopPending = false; 43 timer = new System.Timers.Timer(100); 44 timer.AutoReset = true; 45 timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed); 46 } 47 protected DebugEngine(DebugEngine original, Cloner cloner) : base(original, cloner) { 48 if (original.ExecutionState == ExecutionState.Started) throw new InvalidOperationException(string.Format("Clone not allowed in execution state \"{0}\".", ExecutionState)); 49 Log = cloner.Clone(original.Log); 50 ExecutionStack = cloner.Clone(original.ExecutionStack); 51 pausePending = original.pausePending; 52 stopPending = original.stopPending; 53 timer = new System.Timers.Timer(100); 54 timer.AutoReset = true; 55 timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed); 56 this.currentOperation = cloner.Clone(original.currentOperation); 57 this.currentOperator = cloner.Clone(original.currentOperator); 58 } 38 59 public DebugEngine() 39 60 : base() { 40 }41 42 public new Stack<IOperation> ExecutionStack {43 get { return base.ExecutionStack; }44 }45 46 public IAtomicOperation CurrentOperation { get; private set;}61 Log = new Log(); 62 ExecutionStack = new ExecutionStack(); 63 pausePending = stopPending = false; 64 timer = new System.Timers.Timer(100); 65 timer.AutoReset = true; 66 timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed); 67 } 47 68 48 69 public override IDeepCloneable Clone(Cloner cloner) { 49 70 return new DebugEngine(this, cloner); 71 } 72 73 #endregion 74 75 #region Fields and Properties 76 77 [Storable] 78 public ILog Log { get; protected set; } 79 80 [Storable] 81 public ExecutionStack ExecutionStack { get; protected set; } 82 83 private bool pausePending, stopPending; 84 private DateTime lastUpdateTime; 85 private System.Timers.Timer timer; 86 87 [Storable] 88 private IOperator currentOperator; 89 90 [Storable] 91 private bool ignoreNextBreakpoint; 92 93 [Storable] 94 private IOperation currentOperation; 95 public virtual IOperation CurrentOperation { 96 get { return currentOperation; } 97 private set { 98 if (value == currentOperation) 99 return; 100 currentOperation = value; 101 OnOperationChanged(value); 102 } 103 } 104 105 public virtual IAtomicOperation CurrentAtomicOperation { 106 get { return CurrentOperation as IAtomicOperation; } 107 } 108 109 public virtual IExecutionContext CurrentExecutionContext { 110 get { return CurrentOperation as IExecutionContext; } 111 } 112 113 #endregion 114 115 #region Events 116 117 public event EventHandler<OperationChangedEventArgs> CurrentOperationChanged; 118 119 protected virtual void OnOperationChanged(IOperation newOperation) { 120 EventHandler<OperationChangedEventArgs> handler = CurrentOperationChanged; 121 if (handler != null) { 122 handler(this, new OperationChangedEventArgs(newOperation)); 123 } 124 } 125 126 #endregion 127 128 #region Std Methods 129 public sealed override void Prepare() { 130 base.Prepare(); 131 ExecutionStack.Clear(); 132 ignoreNextBreakpoint = false; 133 CurrentOperation = null; 134 OnPrepared(); 135 } 136 public void Prepare(IOperation initialOperation) { 137 base.Prepare(); 138 ExecutionStack.Clear(); 139 if (initialOperation != null) 140 ExecutionStack.Add(initialOperation); 141 ignoreNextBreakpoint = false; 142 CurrentOperation = null; 143 OnPrepared(); 144 } 145 protected override void OnPrepared() { 146 Log.LogMessage("Engine prepared"); 147 base.OnPrepared(); 148 } 149 150 public virtual void Step() { 151 OnStarted(); 152 lastUpdateTime = DateTime.Now; 153 ignoreNextBreakpoint = true; 154 timer.Start(); 155 ProcessNextOperation(); 156 timer.Stop(); 157 ExecutionTime += DateTime.Now - lastUpdateTime; 158 ignoreNextBreakpoint = false; 159 OnPaused(); 160 } 161 162 public override void Start() { 163 base.Start(); 164 CurrentOperation = null; 165 ThreadPool.QueueUserWorkItem(new WaitCallback(Run), null); 166 } 167 168 protected override void OnStarted() { 169 Log.LogMessage("Engine started"); 170 base.OnStarted(); 171 } 172 173 public override void Pause() { 174 base.Pause(); 175 pausePending = true; 176 if (currentOperator != null) currentOperator.Abort(); 177 } 178 179 protected override void OnPaused() { 180 Log.LogMessage("Engine paused"); 181 base.OnPaused(); 182 } 183 184 public override void Stop() { 185 CurrentOperation = null; 186 base.Stop(); 187 stopPending = true; 188 if (currentOperator != null) currentOperator.Abort(); 189 ignoreNextBreakpoint = false; 190 if (ExecutionState == ExecutionState.Paused) OnStopped(); 191 } 192 193 protected override void OnStopped() { 194 Log.LogMessage("Engine stopped"); 195 base.OnStopped(); 196 } 197 198 protected override void OnExceptionOccurred(Exception exception) { 199 Log.LogException(exception); 200 base.OnExceptionOccurred(exception); 201 } 202 203 private void Run(object state) { 204 OnStarted(); 205 pausePending = stopPending = false; 206 207 lastUpdateTime = DateTime.Now; 208 timer.Start(); 209 while (!pausePending && !stopPending && CanContinue) { 210 ProcessNextOperation(); 211 } 212 timer.Stop(); 213 ExecutionTime += DateTime.Now - lastUpdateTime; 214 215 if (pausePending) OnPaused(); 216 else OnStopped(); 217 } 218 219 private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { 220 DateTime now = DateTime.Now; 221 ExecutionTime += now - lastUpdateTime; 222 lastUpdateTime = now; 223 } 224 #endregion 225 226 #region Methods 227 228 public virtual bool CanContinue { 229 get { return CurrentOperation != null || ExecutionStack.Count > 0; } 50 230 } 51 231 … … 57 237 /// is pushed on the stack again.<br/> 58 238 /// If the execution was successful <see cref="EngineBase.OnOperationExecuted"/> is called.</remarks> 59 protected override void ProcessNextOperation() { 60 currentOperator = null; 61 IOperation next = ExecutionStack.Pop(); 62 OperationCollection coll = next as OperationCollection; 63 while (coll != null) { 64 Log.LogMessage("Expanding OperationCollection"); 65 for (int i = coll.Count - 1; i >= 0; i--) { 66 ExecutionStack.Push(coll[i]); 239 protected virtual void ProcessNextOperation() { 240 try { 241 IAtomicOperation atomicOperation = CurrentOperation as IAtomicOperation; 242 OperationCollection operations = CurrentOperation as OperationCollection; 243 if (atomicOperation != null && operations != null) 244 throw new InvalidOperationException("Current operation is both atomic and an operation collection"); 245 246 if (atomicOperation != null) { 247 Log.LogMessage(string.Format("Performing atomic operation {0}", Name(atomicOperation))); 248 PerformAtomicOperation(atomicOperation); 249 } else if (operations != null) { 250 Log.LogMessage("Expanding operation collection"); 251 ExpandOperationCollection(operations); 252 } else if (ExecutionStack.Count > 0) { 253 Log.LogMessage("Poping execution stack"); 254 CurrentOperation = ExecutionStack.Last(); 255 ExecutionStack.RemoveAt(ExecutionStack.Count - 1); 256 } else { 257 Log.LogMessage("Nothing to do"); 67 258 } 68 next = ExecutionStack.Count > 0 ? ExecutionStack.Pop() : null; 69 coll = next as OperationCollection; 70 } 71 IAtomicOperation operation = next as IAtomicOperation; 259 } catch (Exception x) { 260 OnExceptionOccurred(x); 261 } 262 } 263 264 protected virtual void PerformAtomicOperation(IAtomicOperation operation) { 72 265 if (operation != null) { 73 Log.LogMessage("Preparing IAtomicOperation"); 266 if (operation.Operator.Breakpoint) { 267 if (ignoreNextBreakpoint) { 268 ignoreNextBreakpoint = false; 269 } else { 270 ignoreNextBreakpoint = true; 271 Log.LogMessage(string.Format("Breaking before: {0}", Name(operation))); 272 Pause(); 273 return; 274 } 275 } 74 276 try { 75 277 currentOperator = operation.Operator; 76 CurrentOperation = operation; 77 if (operation.Operator.Breakpoint) { 78 Log.LogMessage(string.Format("Breakpoint: Before {0}", operation.Operator.Name != string.Empty ? operation.Operator.Name : operation.Operator.ItemName)); 79 Pause(); 278 IOperation successor = operation.Operator.Execute((IExecutionContext)operation); 279 CurrentOperation = null; 280 currentOperator = null; 281 if (successor != null) { 282 ExecutionStack.Add(successor); 80 283 } 81 Log.LogMessage("Executing IAtomicOperation");82 ExecutionStack.Push(operation.Operator.Execute((IExecutionContext)operation));83 284 } catch (Exception ex) { 84 285 OnExceptionOccurred(new OperatorExecutionException(operation.Operator, ex)); 85 286 Pause(); 86 287 } 87 } else { 88 Log.LogMessage("Nothing to do"); 89 CurrentOperation = null; 90 } 91 } 92 93 public override void Pause() { 94 base.Pause(); 95 if (currentOperator != null) currentOperator.Abort(); 96 } 97 public override void Stop() { 98 base.Stop(); 99 if (currentOperator != null) currentOperator.Abort(); 100 } 101 102 public virtual void Step() { 103 OnStarted(); 104 var lastUpdateTime = DateTime.Now; 105 if (ExecutionStack.Count > 0) { 106 while (ExecutionStack.Count > 0 && ExecutionStack.Peek() == null) 107 ExecutionStack.Pop(); 108 if (ExecutionStack.Count > 0) 109 ProcessNextOperation(); 110 } 111 ExecutionTime += DateTime.Now - lastUpdateTime; 112 OnPaused(); 113 } 288 } 289 } 290 291 protected virtual void ExpandOperationCollection(OperationCollection operations) { 292 ExecutionStack.AddRange(operations.Reverse()); 293 CurrentOperation = null; 294 } 295 296 protected virtual string Name(IAtomicOperation operation) { 297 return string.IsNullOrEmpty(operation.Operator.Name) ? operation.Operator.ItemName : operation.Operator.Name; 298 } 299 300 #endregion 114 301 } 115 302 }
Note: See TracChangeset
for help on using the changeset viewer.