Reads the game controllers attached to this machine and hands their events to a process or a function.
{:ok, _pid} = Gamepad.start_link(sink: self())
receive do
{:gamepad, %{type: :button, button: :a, pressed: true}} -> :jump
endEvents are the maps Gamepad.Wire describes: a controller connecting or going away,
a button pressed or released, an axis moving, with buttons and axes named in the
Xbox layout whatever the hardware. A pid sink receives each as {:gamepad, event};
a function sink is called with the event.
What reads the hardware depends on the operating system:
- Linux —
/dev/input/js*is read inside the VM, oneGamepad.Linux.Readerprocess per device file, linked to the reader and decoded byGamepad.Linux. New device files are looked for every two seconds. The files must be readable by the user; distributions usually grant that to theinputgroup or to everyone - macOS —
priv/gamepad_helper, a Swift program on GameController.framework thatmix compilebuilds whenswiftcis present; it names every controller macOS itself supports over Bluetooth or USB - Windows —
priv/gamepad_helper.exe, a C program on XInput thatmix compilebuilds throughMakefile.winwith the Visual Studio Build Tools
A helper is a port the reader owns; it exits once the port closes, which happens when the reader stops, crashes, or its VM goes.
With no reader on the machine — a Linux box with no device files, a macOS build
without the helper — start_link/1 returns :ignore. available?/0 says
beforehand whether one exists.
A browser is read the same way by priv/static/gamepad.js (browser_script/0
gives the path to serve it from): Gamepad.watch(sink, options) polls the page's
Gamepad API and calls sink with one Gamepad.Wire line per change, buttons and
axes in the standard mapping named as the wire names them, triggers as axes;
options.every polls every that many milliseconds instead of every animation
frame; the handle's stop() ends it, sending gone for every controller.
Gamepad.available() says whether the page has the API at all. A server given
those lines reads them with Gamepad.Wire.parse/1.
Summary
Functions
Whether this machine has a way to read controllers at all.
The path of gamepad.js, the reader a browser page runs.
Returns a specification to start this module under a supervisor.
The reader this machine would use: :linux, {:helper, path}, or nil.
Starts the reader.
Types
@type sink() :: pid() | (Gamepad.Wire.event() -> any())
Where events go: a process, sent {:gamepad, event}, or a function of the event.
Functions
@spec available?() :: boolean()
Whether this machine has a way to read controllers at all.
@spec browser_script() :: Path.t()
The path of gamepad.js, the reader a browser page runs.
Returns a specification to start this module under a supervisor.
See Supervisor.
The reader this machine would use: :linux, {:helper, path}, or nil.
:linux is answered on Linux whether or not a controller is plugged in, since one
may be plugged in later.
@spec start_link(keyword()) :: GenServer.on_start() | :ignore
Starts the reader.
Options
:sink— required; a pid, sent{:gamepad, event}for each event, or a one-argument function called with each event:source— a reader in place of the detected one, assource/0returns it; a{:helper, path}runs any program speaking theGamepad.Wireprotocol, and a{:linux, glob}reads the joystick device files matchingglob
Returns :ignore when there is no reader.