Input · class
InputSource
Explained in Moving things.
class InputSourceimport { InputSource } from '@driftengine/core';Constructor
new
constructor(target: HTMLElement, preventDefaultCodes?: Iterable<string>, options?: InputOptions)options is a third parameter rather than a widened second, so every existing call site
keeps compiling. A consumer that passes only a target and its prevent-default codes gets the
behaviour it always had, plus a working controller it did not ask for.
| Parameter | Type | Description |
|---|---|---|
target | HTMLElement | |
preventDefaultCodes? | Iterable<string> | |
options? | InputOptions |
Properties
| Name | Type | Description |
|---|---|---|
isCoarsereadonly | boolean | |
touchesreadonly | Map<number, TouchPoint> | |
targetreadonly | HTMLElement |
Accessors
| Name | Type | Description |
|---|---|---|
padsget | readonly GamepadView[] | The pads currently connected and seen, most recently sampled.MoreA pad is invisible until the player uses it, and that is the browser's rule rather than this engine's: reporting a connected gamepad before a button has been pressed is a fingerprinting surface, so none does. It happens to be the rule this design wanted anyway. The array is stable and its length is set rather than rebuilt, so reading it allocates nothing. |
lastDeviceget | InputDevice | Which device the player last actually used. See activeDevice.ts for what counts as use. |
hasPointerLockget | boolean |
Methods
isDown
isDown(code: string): boolean| Parameter | Type | Description |
|---|---|---|
code | string |
pad
pad(at: number): GamepadView | nullOne pad by position in pads, or null.
| Parameter | Type | Description |
|---|---|---|
at | number |
More
Position in the list, not the browser's slot — GamepadView.index answers that, and is
what a consumer pins a player to. The distinction shows itself when a pad is unplugged: the
list closes up, and a caller holding a slot wants index.
onDeviceChange
onDeviceChange(listener: (device: InputDevice) => void): () => voidTold when that changes, and only when it changes. Returns the unsubscribe.
| Parameter | Type | Description |
|---|---|---|
listener | (device: InputDevice) => void |
setSourceEnabled
setSourceEnabled(source: InputSourceName, enabled: boolean): voidTurn a device on or off at runtime, for a settings screen.
| Parameter | Type | Description |
|---|---|---|
source | InputSourceName | |
enabled | boolean |
More
A disabled source is inert rather than absent, and disabling the gamepad stops the poll outright — so an application that does not want controllers pays for no snapshot a frame.
poll
poll(): voidSample the pads now.
More
Called once an animation frame by this source's own loop unless autoPoll is false, and
public so a consumer can pin the sample to its own fixed tick instead — which is what a
recorded replay needs, since a sample taken on a frame callback is not reproducible.
getGamepads() allocates, an array and the objects behind it, and that cost is the
browser's rather than something this engine can pool. So it is called exactly once here and
never from a read: every accessor on a view is a lookup on numbers already copied out. A frame
that runs three simulation ticks polls once, which is also the correct semantics — the
hardware cannot have changed between two ticks of one frame.
keyPressed
keyPressed(code: string): booleanWhether a key went down since the last poll. Readable by anything, cleared at the next poll.
| Parameter | Type | Description |
|---|---|---|
code | string |
More
The keyboard's half of the pair GamepadView.pressed documents: use this to draw, and
consumeKeyPress to act, so a slow frame running the fixed-step loop twice cannot act twice.
consumeKeyPress
consumeKeyPress(code: string): booleanThe same edge, claimed: true for exactly one caller, then gone for everybody.
| Parameter | Type | Description |
|---|---|---|
code | string |
mouseDown
mouseDown(button: MouseButton): booleanWhether a mouse button is held: pressed over the target and not yet released anywhere.
| Parameter | Type | Description |
|---|---|---|
button | MouseButton |
More
A browser opens its context menu on the right button's release; a game binding that button
cancels contextmenu on its canvas, which is a decision about the page and not this source's.
mousePressed
mousePressed(button: MouseButton): booleanWhether a mouse button went down since the last poll, as keyPressed is for a key.
| Parameter | Type | Description |
|---|---|---|
button | MouseButton |
consumeMousePress
consumeMousePress(button: MouseButton): booleanThe same edge, claimed, as consumeKeyPress is for a key: true for exactly one caller.
| Parameter | Type | Description |
|---|---|---|
button | MouseButton |
subscribe
subscribe(callbacks: InputCallbacks): () => voidAdd a device-event subscriber. Multiple reusable control layers may listen without overwriting one another; interpretation still happens outside the raw source. Subscription and removal are initialization-time operations.
| Parameter | Type | Description |
|---|---|---|
callbacks | InputCallbacks |
consumeMouseDelta
consumeMouseDelta(out: { dx: number; dy: number; }): voidDrain accumulated relative mouse motion into out (allocation-free).
| Parameter | Type | Description |
|---|---|---|
out | { dx: number; dy: number; } |
requestPointerLock
requestPointerLock(): voiddispose
dispose(): void