Пример #1
0
        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);
        }
Пример #2
0
 /// <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);
 }
Пример #3
0
 protected virtual bool ProceedToEvent()
 {
     target = generator.Current;
     Value  = target.Value;
     if (target.IsProcessed)
     {
         return(false);
     }
     target.AddCallback(Resume);
     return(true);
 }
Пример #4
0
    /// <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);
    }
Пример #5
0
        /// <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);
            }
        }
Пример #6
0
        /// <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);
        }
Пример #7
0
    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;
    }
Пример #8
0
 protected virtual bool ProceedToEvent()
 {
     target = generator.Current;
       Value = target.Value;
       if (target.IsProcessed) return false;
       target.AddCallback(Resume);
       return true;
 }