UNPKG

use-control

Version:

A powerful set of hooks for elegantly handling keyboard, mouse and gamepad input (soon)

69 lines 3.32 kB
import { useEffect } from 'react'; import { Subject } from 'rxjs'; import { filter, map } from 'rxjs/operators'; var buttonCache = {}; var poll; export var gamepadButtonPress$ = new Subject(); export var gamepadButtonHeld$ = new Subject(); export var gamepadButtonReleased$ = new Subject(); export var gamepadAxes$ = new Subject(); // TODO(ben): consider using an interval() stream for the tick export function initGamepad(pollIntervalMs) { if (pollIntervalMs === void 0) { pollIntervalMs = 1000 / 60; } // makes init idempotent if (poll) clearInterval(poll); poll = setInterval(function () { var _a; var gamepads = navigator.getGamepads ? navigator.getGamepads() : navigator.webkitGetGamepads ? navigator.webkitGetGamepads() : []; if (!gamepads) return; for (var ctrlIdx = 0; ctrlIdx < gamepads.length; ctrlIdx++) { if (gamepads[ctrlIdx]) { for (var btnIdx = 0; btnIdx < gamepads[0].buttons.length; btnIdx++) { var btn = gamepads[ctrlIdx].buttons[btnIdx]; var cachedBtn = ((_a = buttonCache === null || buttonCache === void 0 ? void 0 : buttonCache[ctrlIdx]) === null || _a === void 0 ? void 0 : _a[btnIdx]) || {}; if (btn.pressed) { // TODO(ben): technically speaking this isn't used, we actually handle "held" through the higher level hook useButtonHeld gamepadButtonHeld$.next({ controllerIndex: 0, buttonIndex: btnIdx }); } if (!btn.pressed && cachedBtn.pressed) { gamepadButtonReleased$.next({ controllerIndex: ctrlIdx, buttonIndex: btnIdx }); } if (btn.pressed && !cachedBtn.pressed) { gamepadButtonPress$.next({ controllerIndex: ctrlIdx, buttonIndex: btnIdx }); } } buttonCache[ctrlIdx] = gamepads[ctrlIdx].buttons.slice(); for (var axisIdx = 0; axisIdx < gamepads[ctrlIdx].axes.length; axisIdx++) { var axis = gamepads[ctrlIdx].axes[axisIdx]; gamepadAxes$.next({ controllerIndex: ctrlIdx, axisIndex: axisIdx, value: axis }); } } } }, pollIntervalMs); } export function teardownGamepad() { clearInterval(poll); } export function useGamepadButtonPressed(controllerIndex, buttonIndex, sink) { useEffect(function () { var sub = gamepadButtonPress$ .pipe(filter(function (p) { return p.buttonIndex === buttonIndex && p.controllerIndex === controllerIndex; })) .subscribe(sink); return function () { return sub.unsubscribe(); }; }, [controllerIndex, buttonIndex, sink]); } export function useGamepadAxis(controllerIndex, axisIndex, sink) { useEffect(function () { var sub = gamepadAxes$ .pipe(filter(function (p) { return p.axisIndex === axisIndex && p.controllerIndex === controllerIndex; }), map(function (p) { return p.value; })) .subscribe(sink); return function () { return sub.unsubscribe(); }; }, [controllerIndex, axisIndex, sink]); } //# sourceMappingURL=gamepad.js.map