# `Drafter.Runtime.AppLoop`
[🔗](https://github.com/jaman/drafter/blob/main/lib/drafter/runtime/app_loop.ex#L1)

The Drafter application event loop.

Owns the receive loop and all message dispatch. Rendering is delegated to
`Drafter.Runtime.Renderer`.

# `enter_loop`

```elixir
@spec enter_loop(module(), term(), map(), map(), map() | nil, keyword()) :: :ok
```

Turns the calling process into the application loop, returning when the app stops.

Registers the caller with `Drafter.AppRegistry` and applies `:refresh_rate`
from `opts`, then receives and dispatches events until the application returns
`{:stop, reason}` or the session shuts down.

Remote sessions call this directly. A local terminal goes through `run/2`,
which sets the terminal up first.

`timers` maps a timer id to the `:timer` reference already running for it,
`widget_hierarchy` is the hierarchy from a prior render or `nil` for none.

## Options

  * `:refresh_rate` - frame pacing, as accepted by
    `Drafter.Runtime.FrameClock.interval_for/1`. Default: the app's
    `refresh_rate/0`, or `"30fps"` when it defines none.

Unlike `start/3`, this function does not mount the app, so `:props` is not read here.

# `run`

```elixir
@spec run(
  module(),
  keyword()
) :: :ok
```

Set the local terminal up, then mount the app and run the loop until it stops.

Registers with the theme, skin and screen managers, drains any stale input, clears
the screen and sizes the compositor to the terminal, then hands off to `start/3`
with a screen rect covering the whole terminal.

## Options

Takes the same options as `start/3`.

# `start`

```elixir
@spec start(module(), map(), keyword()) :: :ok
```

Mount an app, run its ready hook, and enter the event loop for `screen_rect`.

This is everything `run/2` does once the terminal has been set up; a headless run
enters here directly. Returns when the loop returns.

`screen_rect` is a `%{x: x, y: y, width: w, height: h}` map. The app is rendered
once before its ready hook and once after, so intervals registered during the hook
are running before the first event is taken.

## Options

  * `:props` - map or keyword list of mount props passed to the app's `mount/1`.
    Default: `%{}`. See `Drafter.Runtime.mount_props/1`.
  * `:refresh_rate` - frame pacing, as accepted by
    `Drafter.Runtime.FrameClock.interval_for/1`. Default: the app's
    `refresh_rate/0`, or `"30fps"` when it defines none.

---

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