Skip to content

Commit

Permalink
Keyboard: keyCode default to true
Browse files Browse the repository at this point in the history
This is preferred because it's independent of keyboard layout.

Also allow filter callback functions to use either original key code
case or lower case.
  • Loading branch information
brianchirls committed Aug 4, 2022
1 parent f0e13ba commit 4e54152
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 25 deletions.
28 changes: 14 additions & 14 deletions src/devices/Keyboard.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,19 @@ describe('Keyboard', () => {
describe('getControl', () => {
it('should return a ButtonInputControl', () => {
const keyboard = new Keyboard();
const control = keyboard.getControl('a');
const control = keyboard.getControl('KeyA');
expect(control).toBeInstanceOf(ButtonInputControl);
});

it('should set device property on control', () => {
const keyboard = new Keyboard();
const control = keyboard.getControl('a');
const control = keyboard.getControl('KeyA');
expect(control.device).toBe(keyboard);
});

it('should pass options to control constructor', () => {
const keyboard = new Keyboard();
const control = keyboard.getControl('a', {
const control = keyboard.getControl('KeyA', {
pressPoint: 0.7,
name: 'controlName'
});
Expand All @@ -47,7 +47,7 @@ describe('Keyboard', () => {

it('should set have no children, even if in options', () => {
const keyboard = new Keyboard();
const control = keyboard.getControl('a', <any>{
const control = keyboard.getControl('KeyA', <any>{
children: [
new ButtonInputControl(() => 0)
]
Expand All @@ -58,13 +58,13 @@ describe('Keyboard', () => {
describe.each([
[
'name is key, no filter', // test title
'w', // name argument
'KeyW', // name argument
undefined, // options argument
{ // expected keys
w: true,
x: false
},
'key:w' // expected name
'key:KeyW' // expected name
],
[
'no name or filter - any key',
Expand All @@ -79,7 +79,7 @@ describe('Keyboard', () => {
[
'filter is string, different from name',
'w key',
{ filter: 'w' },
{ filter: 'KeyW' },
{
w: true,
x: false
Expand All @@ -89,7 +89,7 @@ describe('Keyboard', () => {
[
'filter is function',
'w key',
{ filter: (set: Set<string>) => set.has('w') },
{ filter: (set: Set<string>) => set.has('KeyW') },
{
w: true,
x: false
Expand All @@ -99,7 +99,7 @@ describe('Keyboard', () => {
[
'filter is array',
'w or b key',
{ filter: ['w', 'b'] },
{ filter: ['KeyW', 'KeyW'] },
{
w: true,
x: false
Expand Down Expand Up @@ -203,9 +203,9 @@ describe('Keyboard', () => {

it('should set value with key code', () => {
const keyboard = new Keyboard({
keyCode: true
keyCode: false
});
const control = keyboard.getControl('keyw');
const control = keyboard.getControl('w');

window.dispatchEvent(new KeyboardEvent('keydown', {
code: 'KeyW',
Expand All @@ -218,11 +218,11 @@ describe('Keyboard', () => {
keyboard.destroy();
});

it('should release with key code', () => {
it('should release with key value', () => {
const keyboard = new Keyboard({
keyCode: true
keyCode: false
});
const control = keyboard.getControl('keyw');
const control = keyboard.getControl('w');

window.dispatchEvent(new KeyboardEvent('keydown', {
code: 'KeyW',
Expand Down
21 changes: 10 additions & 11 deletions src/devices/Keyboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,24 @@ import boolAsNum from '../util/boolAsNum';
import { Device, DeviceEvents, DeviceOptions } from '../Device';
import { WildcardHandler } from 'mitt';

/*
todo:
Emit 'change' event only to controls relevant to changed key.
Currently, we emit to every control, which is ineffecient.
*/

export interface KeyboardDeviceOptions extends DeviceOptions {
/**
* Optionally use layout-independent Key Code instead of
* key value string. (default: `false`)
* key value string. (default: `true`)
*
* Key Codes:
* https://www.w3.org/TR/uievents-code/#code-value-tables
*
* If false, use key values:
* https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values
*/
keyCode?: boolean;
}

export interface KeyboardGetControlOptions extends Omit<ButtonInputControlOptions, 'device' | 'children'> {
/**
* filter may be one of the following:
* - string: [name of key](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values) on the keyboard to respond to
* - string: name of code (or key value)
* - array of strings: responds to any of the keys in the array
* - function: a callback that gets called with a Set of active key names and
* is expected to return a boolean, whether or not to respond to the keyboard event.
Expand Down Expand Up @@ -84,18 +81,20 @@ export default class Keyboard extends Device<KeyboardEvents> {

let destroyed = false;
let enabled = false;
const { keyCode = false } = keyboardOptions || {};
const keyCode = keyboardOptions?.keyCode !== false;

const keysDown = new Set<string>();

const onKeyDown = (evt: KeyboardEvent) => {
const key = (keyCode ? evt.code : evt.key).toLowerCase();
const key = keyCode ? evt.code : evt.key;
keysDown.add(key);
keysDown.add(key.toLowerCase());
this.emit('change');
};
const onKeyUp = (evt: KeyboardEvent) => {
const key = (keyCode ? evt.code : evt.key).toLowerCase();
const key = keyCode ? evt.code : evt.key;
keysDown.delete(key);
keysDown.delete(key.toLowerCase());
this.emit('change');
};

Expand Down

0 comments on commit 4e54152

Please sign in to comment.