# `Atui.Runtime`
[🔗](https://github.com/iboard/atui/blob/v0.3.0/lib/atui/runtime.ex#L1)

The main IO loop: owns the terminal, the view stack and every view's timer.

Everything that is impure lives here. Keys arrive as messages from
`Atui.Input`, ticks from timers, and both are dispatched to views; whatever a
view replies decides the new state. After every event the stack is rendered
into a single frame and compared with the last one — if nothing changed,
nothing is written, so an idle UI is silent on the wire.

Views are stacked, topmost first: the bottom one is the root and each push (a
popup) draws over what is below it.

## Who gets what

Keys go to the **root view first** — the place for global keys like quit —
and on to the **focused view**, which is the topmost one, for every key the
root answers `{:pass, state}` to.

Ticks are per view: each one asks for its own interval in
`c:Atui.View.tick_interval/1` and gets a timer and a counter of its own, so a
clock ticking every second costs nothing to a view that never ticks.

Events go to the focused view, unless addressed to a particular view with
`send_event_to/3`, which is how a covered view keeps working. Any message the
runtime does not recognise is delivered as an event, so a `Task` reply or a
PubSub broadcast reaches the UI without ceremony.

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `quit`

Quits the UI as if the root view had returned `:halt`.

# `schedule_event_to`

Schedules an event for `module`, delivered after `delay` milliseconds.

Call it from inside a view callback, where it addresses the runtime the view
is running in — how a view gives something of its own a timer without owning
a process. Returns a timer reference for `Process.cancel_timer/1`.

# `screen`

The most recently rendered screen — the way tests inspect the UI.

# `send_event`

Sends an event to the focused view's `c:Atui.View.handle_event/2`.

Sending the runtime a plain message does the same thing, so anything that can
reach the process — a monitor, a `Task`, a subscription — can drive the UI.

# `send_event_to`

Sends an event to the topmost view of `module`, wherever it sits in the stack.

Lets a covered view keep working while a popup has focus. The event is dropped
if no such view is mounted.

# `send_key`

Feeds a key to the loop as if it had been typed.

# `start_link`

Starts the loop.

Options:

  * `:view` — the root view module (required)
  * `:view_opts` — passed to the root view's `mount/1`
  * `:headless` — do not touch the terminal; render into memory only. Used by
    tests, which then read frames back with `screen/1`.
  * `:size` — force a viewport size as `{cols, rows}` instead of asking the
    terminal
  * `:halt` — `:system` stops the VM when the UI quits (default), `:stop`
    only stops this process

# `view_stack`

The current view stack as a list of modules, topmost first.

# `view_state`

The state of the topmost view of `module`, or `nil` if it is not mounted.

A window into a running UI — for tests, and for asking a live application what
it thinks it is showing.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
