Skip to content

Commit

Permalink
v0.5.2 add { once: true } option
Browse files Browse the repository at this point in the history
  • Loading branch information
reececomo committed Jan 20, 2025
1 parent 75b5887 commit 67d6f76
Show file tree
Hide file tree
Showing 11 changed files with 65 additions and 42 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ gamepad.playVibration({
The gamepad buttons reference **Standard Controller Layout**:
| Button Index | BindableCode | Description | Xbox | Playstation | Nintendo<sup>[[?]](#gamepad---nintendo-layout-remapping)</sup> |
| Button Index | GamepadCode | Description | Xbox | Playstation | Nintendo<sup>[[?]](#gamepad---nintendo-layout-remapping)</sup> |
|:---:|:---|:---|:---:|:---:|:---:|
| `0` | `"A"` | **Face Button 0** | A | Cross | A |
| `1` | `"B"` | **Face Button 1** | B | Circle | X* |
Expand All @@ -259,7 +259,7 @@ The gamepad buttons reference **Standard Controller Layout**:
Bindable helpers are available for the joysticks too:
| Axis # | BindableCode | Standard | Layout
| Axis # | GamepadCode | Standard | Layout
|:---:|:---:|:---:|:---:|
| `0` | `"LeftStickLeft"`<br/>`"LeftStickRight"` | **Left Stick (Left/Right)** | ⬅️➡️ |
| `1` | `"LeftStickUp"`<br/>`"LeftStickDown"` | **Left Stick (Up/Down)** | ⬆️⬇️ |
Expand Down
2 changes: 1 addition & 1 deletion dist/index.cjs

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/index.cjs.map

Large diffs are not rendered by default.

31 changes: 17 additions & 14 deletions dist/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ declare class InputDeviceManager {
/** Remove an event listener (or all if none provided) */
off<K extends keyof InputDeviceEvent>(event: K, listener: (event: InputDeviceEvent[K]) => void): this;
/** Adds a named bind event listener. */
onBind<N extends string>(name: N | readonly N[], listener: (event: NamedBindEvent<N>) => void): this;
onBind<N extends string>(name: N | readonly N[], listener: (event: NamedBindEvent<N>) => void, options?: EventOptions): this;
/** Remove a named bind event listener (or all if none provided). */
offBind(name: string | string[], listener?: (event: NamedBindEvent) => void): this;
/** Report a named bind event (from a CustomDevice). */
Expand Down Expand Up @@ -220,7 +220,7 @@ declare const ButtonCode: readonly [
export declare class GamepadDevice {
source: Gamepad;
/** Set named binds for newly connected gamepads */
static configureDefaultBinds(binds: Partial<Record<string, BindableCode[]>>): void;
static configureDefaultBinds(binds: Partial<Record<string, GamepadCode[]>>): void;
static defaultOptions: {
/**
* When set to `"physical"` _(default)_, ABXY refer to the equivalent
Expand Down Expand Up @@ -252,7 +252,7 @@ export declare class GamepadDevice {
* // ...
* }
*/
binds: Partial<Record<string, BindableCode[]>>;
binds: Partial<Record<string, GamepadCode[]>>;
joystick: {
/**
* The range of movement in a joystick recognized as input, to
Expand Down Expand Up @@ -340,17 +340,17 @@ export declare class GamepadDevice {
/** @returns true if any button from the named bind is pressed. */
pressedBind(name: string): boolean;
/** @returns true if any of the given buttons are pressed. */
pressedAny(btns: BindableCode[]): boolean;
pressedAny(btns: GamepadCode[]): boolean;
/** @returns true if all of the given buttons are pressed. */
pressedAll(btns: BindableCode[]): boolean;
pressedAll(btns: GamepadCode[]): boolean;
/** Set named binds for this gamepad */
configureBinds(binds: Partial<Record<string, BindableCode[]>>): void;
configureBinds(binds: Partial<Record<string, GamepadCode[]>>): void;
/** Add an event listener */
on<K extends keyof GamepadDeviceEvent>(event: K, listener: (event: GamepadDeviceEvent[K]) => void): this;
on<K extends keyof GamepadDeviceEvent>(event: K, listener: (event: GamepadDeviceEvent[K]) => void, options?: EventOptions): this;
/** Remove an event listener (or all if none provided). */
off<K extends keyof GamepadDeviceEvent>(event: K, listener?: (event: GamepadDeviceEvent[K]) => void): this;
/** Add a named bind event listener (or all if none provided). */
onBind(name: string, listener: (event: GamepadNamedBindEvent) => void): this;
onBind(name: string, listener: (event: GamepadNamedBindEvent) => void, options?: EventOptions): this;
/** Remove a named bind event listener (or all if none provided). */
offBind(name: string, listener?: (event: GamepadNamedBindEvent) => void): this;
/**
Expand Down Expand Up @@ -455,11 +455,11 @@ export declare class KeyboardDevice {
/** Set custom binds */
configureBinds(binds: Partial<Record<string, KeyCode[]>>): void;
/** Add an event listener. */
on<K extends keyof KeyboardDeviceEvent>(event: K, listener: (event: KeyboardDeviceEvent[K]) => void): this;
on<K extends keyof KeyboardDeviceEvent>(event: K, listener: (event: KeyboardDeviceEvent[K]) => void, options?: EventOptions): this;
/** Remove an event listener (or all if none provided). */
off<K extends keyof KeyboardDeviceEvent>(event: K, listener?: (event: KeyboardDeviceEvent[K]) => void): this;
/** Add a named bind event listener (or all if none provided). */
onBind(name: string, listener: (event: KeyboardDeviceNamedBindKeydownEvent) => void): this;
onBind(name: string, listener: (event: KeyboardDeviceNamedBindKeydownEvent) => void, options?: EventOptions): this;
/** Remove a named bind event listener (or all if none provided). */
offBind(name: string, listener?: (event: KeyboardDeviceNamedBindKeydownEvent) => void): this;
/**
Expand Down Expand Up @@ -688,6 +688,9 @@ export interface CustomDevice {
*/
clear?(): void;
}
export interface EventOptions {
once?: boolean;
}
export interface GamepadAxisEvent {
device: GamepadDevice;
axis: Axis;
Expand Down Expand Up @@ -761,14 +764,14 @@ export interface NavigationResponder {
}
export type Axis = (typeof Axis)[keyof typeof Axis];
export type AxisCode = typeof AxisCode[number];
/**
* Bindable codes for button and joystick events.
*/
export type BindableCode = ButtonCode | AxisCode;
export type Button = (typeof Button)[keyof typeof Button];
export type ButtonCode = typeof ButtonCode[number];
export type Device = GamepadDevice | KeyboardDevice | CustomDevice;
export type GamepadButtonDownEvent = (gamepad: GamepadDevice, button: Button) => void;
/**
* Bindable codes for button and joystick events.
*/
export type GamepadCode = ButtonCode | AxisCode;
export type GamepadDeviceEvent = {
bind: GamepadNamedBindEvent;
} & {
Expand Down
2 changes: 1 addition & 1 deletion dist/index.mjs

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/index.mjs.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "pixijs-input-devices",
"version": "0.5.1",
"version": "0.5.2",
"author": "Reece Como <[email protected]>",
"authors": [
"Reece Como <[email protected]>"
Expand Down
7 changes: 4 additions & 3 deletions src/lib/InputDevice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { CustomDevice } from "./devices/CustomDevice";
import { GamepadDevice } from "./devices/gamepads/GamepadDevice";
import { KeyboardDevice } from "./devices/keyboard/KeyboardDevice";
import { isMobile, isTouchCapable } from "./utils/detectors";
import { EventEmitter } from "./utils/events";
import { EventEmitter, EventOptions } from "./utils/events";


export interface InputDeviceEvent {
Expand Down Expand Up @@ -130,11 +130,12 @@ class InputDeviceManager
/** Adds a named bind event listener. */
public onBind<N extends string>(
name: N | readonly N[],
listener: ( event: NamedBindEvent<N> ) => void
listener: ( event: NamedBindEvent<N> ) => void,
options?: EventOptions,
): this
{
name = Array.isArray( name ) ? name : [name];
name.forEach( n => this._bindEmitter.on( n, listener ) );
name.forEach( n => this._bindEmitter.on( n, listener, options ) );
return this;
}

Expand Down
24 changes: 13 additions & 11 deletions src/lib/devices/gamepads/GamepadDevice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import { Axis, AxisCode, Button, ButtonCode } from "./buttons";
import { detectLayout, GamepadLayout } from "./layouts";
import { throttle } from "../../utils/throttle";
import { EventEmitter } from "../../utils/events";
import { EventEmitter, EventOptions } from "../../utils/events";


export { Button, GamepadLayout };
Expand Down Expand Up @@ -51,7 +51,7 @@ export type GamepadDeviceEvent = {
/**
* Bindable codes for button and joystick events.
*/
export type BindableCode = ButtonCode | AxisCode;
export type GamepadCode = ButtonCode | AxisCode;

/**
* A gamepad (game controller).
Expand All @@ -66,7 +66,7 @@ export class GamepadDevice
{
/** Set named binds for newly connected gamepads */
public static configureDefaultBinds(
binds: Partial<Record<string, BindableCode[]>>
binds: Partial<Record<string, GamepadCode[]>>
): void
{
this.defaultOptions.binds = {
Expand Down Expand Up @@ -114,7 +114,7 @@ export class GamepadDevice
"navigate.right": [ "DPadRight", "LeftStickRight" ],
"navigate.trigger": [ "A" ],
"navigate.up": [ "DPadUp", "LeftStickUp" ],
} as Partial<Record<string, BindableCode[]>>,
} as Partial<Record<string, GamepadCode[]>>,

joystick: {
/**
Expand Down Expand Up @@ -223,7 +223,7 @@ export class GamepadDevice
}

/** @returns true if any of the given buttons are pressed. */
public pressedAny( btns: BindableCode[] ): boolean
public pressedAny( btns: GamepadCode[] ): boolean
{
for ( let i = 0; i < btns.length; i++ )
{
Expand All @@ -234,7 +234,7 @@ export class GamepadDevice
}

/** @returns true if all of the given buttons are pressed. */
public pressedAll( btns: BindableCode[] ): boolean
public pressedAll( btns: GamepadCode[] ): boolean
{
for ( let i = 0; i < btns.length; i++ )
{
Expand All @@ -245,7 +245,7 @@ export class GamepadDevice
}

/** Set named binds for this gamepad */
public configureBinds( binds: Partial<Record<string, BindableCode[]>> ): void
public configureBinds( binds: Partial<Record<string, GamepadCode[]>> ): void
{
this.options.binds = {
...this.options.binds,
Expand All @@ -258,10 +258,11 @@ export class GamepadDevice
/** Add an event listener */
public on<K extends keyof GamepadDeviceEvent>(
event: K,
listener: (event: GamepadDeviceEvent[K]) => void
listener: (event: GamepadDeviceEvent[K]) => void,
options?: EventOptions,
): this
{
this._emitter.on(event, listener);
this._emitter.on( event, listener, options );
return this;
}

Expand All @@ -278,10 +279,11 @@ export class GamepadDevice
/** Add a named bind event listener (or all if none provided). */
public onBind(
name: string,
listener: ( event: GamepadNamedBindEvent ) => void
listener: ( event: GamepadNamedBindEvent ) => void,
options?: EventOptions,
): this
{
this._bindEmitter.on( name, listener );
this._bindEmitter.on( name, listener, options );
return this;
}

Expand Down
12 changes: 7 additions & 5 deletions src/lib/devices/keyboard/KeyboardDevice.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { KeyCode } from "./keys";
import { EventEmitter } from "../../utils/events";
import { EventEmitter, EventOptions } from "../../utils/events";
import {
requestKeyboardLayout,
getLayoutKeyLabel,
Expand Down Expand Up @@ -230,10 +230,11 @@ export class KeyboardDevice
/** Add an event listener. */
public on<K extends keyof KeyboardDeviceEvent>(
event: K,
listener: (event: KeyboardDeviceEvent[K]) => void
listener: (event: KeyboardDeviceEvent[K]) => void,
options?: EventOptions,
): this
{
this._emitter.on(event, listener);
this._emitter.on( event, listener, options );
return this;
}

Expand All @@ -250,10 +251,11 @@ export class KeyboardDevice
/** Add a named bind event listener (or all if none provided). */
public onBind(
name: string,
listener: ( event: KeyboardDeviceNamedBindKeydownEvent ) => void
listener: ( event: KeyboardDeviceNamedBindKeydownEvent ) => void,
options?: EventOptions,
): this
{
this._bindEmitter.on( name, listener );
this._bindEmitter.on( name, listener, options );
return this;
}

Expand Down
19 changes: 17 additions & 2 deletions src/lib/utils/events.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
export interface EventOptions {
once?: boolean;
}

export class EventEmitter<EType>
{
private readonly _listeners: { [E in keyof EType]?: ((e: EType[E]) => void)[] } = {};
Expand All @@ -12,10 +16,21 @@ export class EventEmitter<EType>
this._listeners[e]?.forEach( (fn) => fn(payload) );
}

public on<E extends keyof EType>(event: E, fn: (event: EType[E]) => void): void
public on<E extends keyof EType>(event: E, fn: (event: EType[E]) => void, options?: EventOptions): void
{
if (!this._listeners[event]) this._listeners[event] = [];
this._listeners[event]?.push(fn);

if ( options?.once )
{
const onceFn = (e: EType[E]): void =>
{
fn(e);
this.off( event, onceFn );
};

this._listeners[event]?.push(onceFn);
}
else this._listeners[event]?.push(fn);
}

public off<E extends keyof EType>(event: E, fn?: (event: EType[E]) => void): void
Expand Down

0 comments on commit 67d6f76

Please sign in to comment.