def run(self, until=None): """Executes :meth:`step()` until the given criterion *until* is met. - If it is ``None`` (which is the default), this method will return when there are no further events to be processed. - If it is an :class:`~simpy.events.Event`, the method will continue stepping until this event has been triggered and will return its value. Raises a :exc:`RuntimeError` if there are no further events to be processed and the *until* event was not triggered. - If it is a number, the method will continue stepping until the environment's time reaches *until*. """ if until is not None: if not isinstance(until, Event): # Assume that *until* is a number if it is not None and # not an event. Create a Timeout(until) in this case. at = float(until) if at <= self.now: raise ValueError('until(=%s) should be > the current ' 'simulation time.' % at) # Schedule the event with before all regular timeouts. until = Event(self) until.ok = True until._value = None self.schedule(until, URGENT, at - self.now) elif until.callbacks is None: # Until event has already been processed. return until.value until.callbacks.append(StopSimulation.callback) try: while True: self.step() except StopSimulation as exc: return exc.args[0] # == until.value except EmptySchedule: if until is not None: # @ FIXED ASSERTION ERROR try: not until.triggered except: pass raise RuntimeError('No scheduled events left but "until" ' 'event was not triggered: %s' % until)
def run(self, until=None): """Executes :meth:`step()` until the given criterion *until* is met. - If it is ``None`` (which is the default), this method will return when there are no further events to be processed. - If it is an :class:`~simpy.events.Event`, the method will continue stepping until this event has been triggered and will return its value. Raises a :exc:`RuntimeError` if there are no further events to be processed and the *until* event was not triggered. - If it is a number, the method will continue stepping until the environment's time reaches *until*. """ if until is not None: if not isinstance(until, Event): # Assume that *until* is a number if it is not None and # not an event. Create a Timeout(until) in this case. at = float(until) if at <= self.now: raise ValueError('until(=%s) should be > the current ' 'simulation time.' % at) # Schedule the event before all regular timeouts. until = Event(self) until._ok = True until._value = None self.schedule(until, URGENT, at - self.now) elif until.callbacks is None: # Until event has already been processed. return until.value until.callbacks.append(StopSimulation.callback) try: while True: self.step() except StopSimulation as exc: return exc.args[0] # == until.value except EmptySchedule: if until is not None: assert not until.triggered raise RuntimeError('No scheduled events left but "until" ' 'event was not triggered: %s' % until)
def run(self, until=None): """Executes :meth:`step()` until the given criterion *until* is met. - If it is ``None`` (which is the default) this method will return if there are no further events to be processed. - If it is an :class:`~simpy.events.Event` the method will continue stepping until this event has been triggered and will return its value. - If it can be converted to a number the method will continue stepping until the environment's time reaches *until*. """ if until is None: until = Event(self) elif not isinstance(until, Event): at = float(until) if at <= self.now: raise ValueError('until(=%s) should be > the current ' 'simulation time.' % at) # Schedule the event with before all regular timeouts. until = Event(self) until.ok = True until._value = None self.schedule(until, URGENT, at - self.now) until.callbacks.append(_stop_simulate) try: while True: self.step() except EmptySchedule: pass if not until.triggered: return None if not until.ok: raise until.value return until.value