Working with simulated time

The primary tool to work with time in a simulation is usim.time. It gives access to the current time, and using it in expressions provides Conditions to check or await the passing of time. For convenience and readability, several helpers are provided: usim.eternity and usim.instant are the longest and shortest delay possible, respectively. usim.delay() and usim.interval() allow to repeatedly delay in order to act at fixed intervals.

Direct Interaction with Time

usim.time

Representation of ongoing simulation time

now = time.now        # get the current time
await (time + 20)     # wait for a time span to pass
await (time == 1999)  # wait for a time date to occur
await (time >= 1999)  # wait for a time date to occur or pass

async with until(time + 20):  # abort block after a delay
    ...

async with until(time == 1999):  # abort block at a fixed time
    await party()

Due to the nature of simulated time there is only “directly after” any specific point in time, but not “directly before”. This allows to express only “strictly before” (time < point), and “equal or after” (time >= point) as awaitable events.

However, it is possible to test e.g. “equal or before” using the current time (time.now <= point). To avoid accidental mixing of awaitable and non-awaitable comparisons, expressions of usim.time never provide a result which cannot be awaited.

time.now

The current simulation time.

time + delay
await (time + delay)

A Notification that triggers after delay time has passed. Delays are not translated to absolute points in time; the same delay can be awaited multiple times, and each pauses for delay.

time >= date
await (time >= date)

A Condition that is satisfied at or after the simulation time equals date.

time == date
await (time == date)

A Condition that is satisfied only when the simulation time equals date.

time < date
await (time < date)

A Condition that is satisfied only before the simulation time equals date.

Actively Postpone and Suspend

usim.eternity

A point in time infinitely far into the future

An activity that awaits usim.eternity suspends indefinitely and never wakes up by itself. This holds true even when time advances to math.inf or another representation of infinity.

await eternity  # wait forever
usim.instant

A future point in time indistinguishable from the current time

An activity that awaits Instant is merely postponed. The current time has no effect on this.

await instant  # wait shortly, resuming in the same time step

Controlled Repetitions

async for ... in usim.interval(period) AsyncIterable[float][source]

Iterate through time by intervals of period

Parameters

period – on each step, pause with a period since the last step

Raises

IntervalExceeded – if the loop body is suspended for more than period

Asynchronous iteration pauses and provides the current time at each step.

print('It was', time.now)  # 0
async for now in interval(10):
    await (time + 1)
    print(now, time.now)  # (10, 11), (20, 21), (30, 31), ...

The first pause occurs before entering the loop body.

Using interval causes iteration to resume at regular times, even if the current activity is suspended in the loop body - the pause is shortened as necessary. This effectively creates a “clock” that ticks every period and runs the loop body. If the loop body is suspended for longer than period so that a regular interval cannot be met, IntervalExceeded is raised.

See also

delay() if you want to always pause for the same time

async for ... in usim.delay(period) AsyncIterable[float][source]

Iterate through time by delays of period

Parameters

period – on each step, pause for a period

Asynchronous iteration pauses and provides the current time at each step.

print('It was', time.now)  # 0
async for now in delay(10):
    await (time + 1)
    print(now, time.now)  # (10, 11), (21, 22), (32, 33), ...

The first pause occurs before entering the loop body.

Delaying causes iteration to always pause for the same time, even if the current activity is suspended in the loop body.

See also

interval() if you want to resume at regular times