public virtual object Run(Event stopEvent = null) { if (stopEvent != null) { if (stopEvent.IsProcessed) { return(stopEvent.Value); } stopEvent.AddCallback(StopSimulation); } try { var stop = Queue.Count == 0 && ScheduleQ.Count == 0; while (!stop) { Step(); ProcessedEvents++; lock (locker) { stop = Queue.Count == 0 && ScheduleQ.Count == 0; } } } catch (StopSimulationException e) { return(e.Value); } if (stopEvent == null) { return(null); } if (!stopEvent.IsTriggered) { throw new InvalidOperationException("No scheduled events left but \"until\" event was not triggered."); } return(stopEvent.Value); }
/// <summary> /// Run until a certain event is processed. /// </summary> /// <remarks> /// This simulation environment is not thread-safe, thus triggering this event outside the environment /// leads to potential race conditions. Please use the <see cref="ThreadSafeSimulation"/> environment in case you /// require this functionality. Note that the performance of <see cref="ThreadSafeSimulation"/> is lower due to locking. /// /// For real-time based termination, you can also call <see cref="StopAsync"/> which sets a flag indicating the simulation /// to stop before processing the next event. /// </remarks> /// <param name="stopEvent">The event that stops the simulation.</param> /// <returns></returns> public virtual object Run(Event stopEvent = null) { _stopRequested = false; if (stopEvent != null) { if (stopEvent.IsProcessed) { return(stopEvent.Value); } stopEvent.AddCallback(StopSimulation); } OnRunStarted(); try { var stop = ScheduleQ.Count == 0 || _stopRequested; while (!stop) { Step(); ProcessedEvents++; stop = ScheduleQ.Count == 0 || _stopRequested; } } catch (StopSimulationException e) { OnRunFinished(); return(e.Value); } OnRunFinished(); if (stopEvent == null) { return(null); } if (!_stopRequested && !stopEvent.IsTriggered) { throw new InvalidOperationException("No scheduled events left but \"until\" event was not triggered."); } return(stopEvent.Value); }
protected virtual bool ProceedToEvent() { target = generator.Current; Value = target.Value; if (target.IsProcessed) { return(false); } target.AddCallback(Resume); return(true); }
/// <summary> /// This interrupts a process and causes the IsOk flag to be set to false. /// If a process is interrupted the iterator method needs to call HandleFault() /// before continuing to yield further events. /// </summary> /// <exception cref="InvalidOperationException">This is thrown in three conditions: /// - If the process has already been triggered. /// - If the process attempts to interrupt itself. /// - If the process continues to yield events despite being faulted.</exception> /// <param name="cause">The cause of the interrupt.</param> public virtual void Interrupt(object cause = null) { if (IsTriggered) throw new InvalidOperationException("The process has terminated and cannot be interrupted."); if (Environment.ActiveProcess == this) throw new InvalidOperationException("A process is not allowed to interrupt itself."); var interruptEvent = new Event(Environment); interruptEvent.AddCallback(Resume); interruptEvent.Fail(cause); if (Target != null) Target.RemoveCallback(Resume); }
/// <summary> /// This interrupts a process and causes the IsOk flag to be set to false. /// If a process is interrupted the iterator method needs to call HandleFault() /// before continuing to yield further events. /// </summary> /// <exception cref="InvalidOperationException">This is thrown in three conditions: /// - If the process has already been triggered. /// - If the process attempts to interrupt itself. /// - If the process continues to yield events despite being faulted.</exception> /// <param name="cause">The cause of the interrupt.</param> public virtual void Interrupt(object cause = null) { if (IsTriggered) { throw new InvalidOperationException("The process has terminated and cannot be interrupted."); } if (Environment.ActiveProcess == this) { throw new InvalidOperationException("A process is not allowed to interrupt itself."); } var interruptEvent = new Event(Environment); interruptEvent.AddCallback(Resume); interruptEvent.Fail(cause); if (Target != null) { Target.RemoveCallback(Resume); } }
/// <summary> /// Run until a certain event is processed. /// </summary> /// <remarks> /// This method is thread-safe against manipulations of the event queue /// </remarks> /// <param name="stopEvent">The event that stops the simulation.</param> /// <returns></returns> public override object Run(Event stopEvent = null) { _stopRequested = false; if (stopEvent != null) { if (stopEvent.IsProcessed) { return(stopEvent.Value); } stopEvent.AddCallback(StopSimulation); } try { var stop = false; lock (_locker) { stop = ScheduleQ.Count == 0 || _stopRequested; } while (!stop) { Step(); ProcessedEvents++; lock (_locker) { stop = ScheduleQ.Count == 0 || _stopRequested; } } } catch (StopSimulationException e) { return(e.Value); } if (stopEvent == null) { return(null); } if (!stopEvent.IsTriggered) { throw new InvalidOperationException("No scheduled events left but \"until\" event was not triggered."); } return(stopEvent.Value); }
public virtual object Run(Event stopEvent = null) { if (stopEvent != null) { if (stopEvent.IsProcessed) return stopEvent.Value; stopEvent.AddCallback(StopSimulation); } try { var stop = Queue.Count == 0 && ScheduleQ.Count == 0; while (!stop) { Step(); ProcessedEvents++; lock (locker) { stop = Queue.Count == 0 && ScheduleQ.Count == 0; } } } catch (StopSimulationException e) { return e.Value; } if (stopEvent == null) return null; if (!stopEvent.IsTriggered) throw new InvalidOperationException("No scheduled events left but \"until\" event was not triggered."); return stopEvent.Value; }
protected virtual bool ProceedToEvent() { target = generator.Current; Value = target.Value; if (target.IsProcessed) return false; target.AddCallback(Resume); return true; }