# `Cauldron2D.Drafter.Client.Stage`
[🔗](https://github.com/jaman/cauldron/blob/v0.3.0/cauldron_2d_drafter/lib/cauldron_2d/drafter/client/stage.ex#L1)

A graphics card drawing a client's scenes: a `CauldronGPU.Host` renderer, offscreen for
pictures shown in the pane or in a window of its own, and the cache a scene's `:gpu`
function keeps between ticks.

    {:ok, stage} = Stage.start(:pane, title: "Quake")
    # once {Stage, ^stage, :ready} has arrived:
    {:ok, raster} = Stage.picture(stage, scene.gpu, {960, 600}, 1.0)

The process that starts a stage is its owner and receives `{Stage, stage, message}`:

  * `:ready` — the renderer has opened; `picture/4` and `draw/2` may be used
  * `{:failed, reason}` — it did not open, or stopped and could not be started again;
    the stage has stopped
  * `{:input, event}` — a key pressed or released in the window, as a terminal's drafter
    event (`Cauldron2D.Drafter.Client.WindowKeys`)
  * `:closed` — the window was closed; the stage has stopped

A renderer process that exits is started again with the scene it had, so the cache
stays good. The stage stops when its owner exits.

# `gpu`

```elixir
@type gpu() :: (term(), term(), {pos_integer(), pos_integer()}, number() -&gt;
            {list(), term()})
```

# `mode`

```elixir
@type mode() :: :pane | :window
```

# `t`

```elixir
@type t() :: pid()
```

# `available?`

```elixir
@spec available?() :: boolean()
```

Whether this build has `CauldronGPU` and a renderer to open.

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `draw`

```elixir
@spec draw(t(), gpu()) :: :ok
```

Sends the scene `gpu` describes to the window. Ticks sent faster than they are drawn are dropped for the newest.

# `picture`

```elixir
@spec picture(t(), gpu(), {pos_integer(), pos_integer()}, number()) ::
  {:ok, FrenchCurve.Raster.t()} | {:error, term()}
```

The scene `gpu` describes drawn at `size` pixels, as a raster. `{:error, reason}` when
the renderer is not ready, the function raises, or no frame comes back in time.

# `start`

```elixir
@spec start(mode(), keyword()) :: {:ok, t()} | {:error, term()}
```

Starts a stage owned by the caller, opening its renderer in the background. Options:
`:title` (the window's title).

# `stop`

```elixir
@spec stop(t()) :: :ok
```

Stops the stage, closing its renderer.

---

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