Skip to content

xnano.time

xnano.time

xnano.time

A canvas's time: how long it has run, whether it is stopped, and the formulas that follow it.

Classes:

  • Time –

    The time a canvas runs on.

Time

Time(canvas: Canvas[object, object])

The time a canvas runs on.

Get it from Canvas.time or from context.time inside a hook. Everything that moves follows it: animations, effects, formulas, hook timers (every and after), fixed-step updates and the musical beat. Any thread may read it. Used in arithmetic it is the formula for seconds, so canvas.time / 2 is a value that follows the clock. stop freezes all of them while input keeps arriving, and step moves a frozen clock one frame at a time.

elapsed, delta and fps are numbers you read now; seconds and milliseconds are formulas that a placement keeps following. A Frame carries the same numbers as elapsed_seconds and delta_seconds. fps here is the rate measured over recent frames, while Canvas.fps is the most frames the canvas draws per second.

Attributes:

Examples:

import xnano

with xnano.new(width=20, height=1) as canvas:
    ball = canvas.write('o')
    ball.x = (canvas.width - 1) * ((canvas.time.seconds / 2) % 1.0)
    canvas.step(delta_seconds=1.0)
    assert canvas.time.elapsed == 1.0
    canvas.time.stop()
    assert canvas.time.is_stopped
    canvas.time.step(delta_seconds=0.5)
    assert canvas.time.elapsed == 1.5

Create the canvas's time. Use canvas.time instead of calling this.

Parameters:

Methods:

  • stop –

    Freeze time.

  • resume –

    Let time run on from where stop froze it.

  • step –

    Move time by delta_seconds, one frame by default, and draw exactly one frame.

Source code in xnano/time.py
def __init__(self, canvas: Canvas[object, object]) -> None:
    """
    Create the canvas's time. Use ``canvas.time`` instead of calling this.

    Args:
        canvas: The canvas the time belongs to.
    """
    self._canvas = canvas

elapsed property

elapsed: float

Seconds since the canvas started, not counting time spent stopped.

elapsed_milliseconds property

elapsed_milliseconds: float

Milliseconds since the canvas started, not counting time spent stopped.

delta property

delta: float

Seconds between the two most recent frames.

frame property

frame: int

The number of steps the clock has counted, including steps that drew nothing.

fps property

fps: float

The frame rate measured over recent frames.

is_stopped property

is_stopped: bool

Whether time is frozen by stop.

is_realtime property

is_realtime: bool

Whether time follows the wall clock instead of moving only when you move it.

seconds property

seconds: NumericValue

A formula for the elapsed seconds, recomputed every frame.

milliseconds property

milliseconds: NumericValue

A formula for the elapsed milliseconds, recomputed every frame.

stop

stop() -> None

Freeze time.

Animations, effects, formulas, timers, fixed-step updates and the musical beat stand still. The canvas still draws and input still arrives, so a key can resume it, and step moves it one frame at a time. Stopping a stopped canvas does nothing.

Raises:

  • TerminalClosedError –

    The canvas is closed.

Source code in xnano/time.py
def stop(self) -> None:
    """
    Freeze time.

    Animations, effects, formulas, timers, fixed-step updates and the musical beat stand
    still. The canvas still draws and input still arrives, so a key can
    [`resume`][xnano.time.Time.resume] it, and [`step`][xnano.time.Time.step] moves it one
    frame at a time. Stopping a stopped canvas does nothing.

    Raises:
        TerminalClosedError: The canvas is closed.
    """
    canvas = self._canvas
    canvas._require_open()
    canvas._time_source.stop()
    audio = canvas._audio
    if audio is not None:
        canvas._host.post(audio._hold)
    # A frozen canvas still draws what changes, so it draws once more now.
    canvas._request_frame()

resume

resume() -> None

Let time run on from where stop froze it.

Resuming a canvas that is not stopped does nothing.

Raises:

  • TerminalClosedError –

    The canvas is closed.

Source code in xnano/time.py
def resume(self) -> None:
    """
    Let time run on from where [`stop`][xnano.time.Time.stop] froze it.

    Resuming a canvas that is not stopped does nothing.

    Raises:
        TerminalClosedError: The canvas is closed.
    """
    canvas = self._canvas
    canvas._require_open()
    canvas._time_source.resume()
    audio = canvas._audio
    if audio is not None:
        canvas._host.post(audio._release)

step

step(*, delta_seconds: float | None = None) -> Frame

Move time by delta_seconds, one frame by default, and draw exactly one frame.

This is Canvas.step; see it for every case.

Parameters:

  • delta_seconds (float | None, default: None ) –

    How far to move, above zero; one frame of the canvas's fps when None.

Returns:

Source code in xnano/time.py
def step(self, *, delta_seconds: float | None = None) -> Frame:
    """
    Move time by ``delta_seconds``, one frame by default, and draw exactly one frame.

    This is [`Canvas.step`][xnano.canvas.Canvas.step]; see it for every case.

    Args:
        delta_seconds: How far to move, above zero; one frame of the canvas's ``fps``
            when ``None``.

    Returns:
        The [`Frame`][xnano.context.Frame] that was drawn.
    """
    return self._canvas._step(delta_seconds)