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

The game controllers a client has seen, and which of its players each one plays.

A controller is known by its device id (`Gamepad.Wire`'s `device`) and its name, the
name it reported when it connected; two connected controllers reporting the same name
are told apart as `"<name>"`, `"<name> #2"` and on, in the order they connected. A
controller heard from before it said it connected is named `"controller <device>"`.

The client's players are numbered from 1: the player itself, then each of its seats
(`Cauldron2D.Drafter.Client.Seats`). `slots/3` gives each connected controller a slot,
its player's number less one, from `assignments`, a map from controller name to a
player number or `:none`:

  * a controller assigned a player that exists and no earlier controller took plays it
  * a controller with no assignment plays the lowest-numbered player left free, in
    the order the controllers connected
  * a controller assigned `:none`, or left with no free player, plays no one (`nil`)

    controllers = Controllers.new() |> Controllers.connect(0, "Xbox Wireless Controller")
    Controllers.slots(controllers, %{"Xbox Wireless Controller" => 2}, 2)
    #=> %{0 => 1}

# `assignments`

```elixir
@type assignments() :: %{required(String.t()) =&gt; pos_integer() | :none}
```

# `device`

```elixir
@type device() :: non_neg_integer()
```

# `t`

```elixir
@type t() :: %Cauldron2D.Drafter.Client.Controllers{
  connected: [{device(), String.t()}]
}
```

# `connect`

```elixir
@spec connect(t(), device(), String.t()) :: t()
```

The controllers with `device` connected under `name`, numbered when the name is taken.

# `disconnect`

```elixir
@spec disconnect(t(), device()) :: t()
```

The controllers without `device`.

# `known?`

```elixir
@spec known?(t(), device()) :: boolean()
```

Whether `device` is known.

# `listed`

```elixir
@spec listed(t(), %{required(device()) =&gt; non_neg_integer() | nil}) :: [
  %{name: String.t(), player: pos_integer() | nil}
]
```

The connected controllers, in the order they connected, each `%{name, player}` with `player` its number or `nil`.

# `new`

```elixir
@spec new() :: t()
```

No controllers seen.

# `seen`

```elixir
@spec seen(t(), device()) :: t()
```

The controllers with `device` known, named `"controller <device>"` when it was not already.

# `slots`

```elixir
@spec slots(t(), assignments(), pos_integer()) :: %{
  required(device()) =&gt; non_neg_integer() | nil
}
```

Each connected controller's slot, or `nil`, for `players` players under `assignments`.

---

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