input_handler_input_handler.js
/**
* @module InputHandler
* @fileoverview Contains abstract InputHandler class.
*/
import EventHandlerLayer from "../../event/event_handler_layer.js";
/**
* Abstract input handler. Used for handling input events.
* @class
* @abstract
*/
class InputHandler {
/**
* Create a new abstract input handler.
* @param {EventHandler|EventHandlerLayer} parentHandler Parent event handler or layer
* @param {string} prefix Prefix for event handler
* @param {function} condition Function for checking whether events should run
* @constructor
*/
constructor(parentHandler, prefix, condition = () => { return true; }) {
this._condition = condition;
this._parent = parentHandler;
this._layer = new EventHandlerLayer(this._parent, prefix);
this._press = new EventHandlerLayer(this._layer, "press/");
this._release = new EventHandlerLayer(this._layer, "release/");
this._down = new EventHandlerLayer(this._layer, "down/");
this._currentlyDown = new Set();
}
/**
* Handle deletion of the handler and its input listeners.
*/
destructor() {}
// Getters
/**
* Check if the game is in focus (user is not focused on input).
* @returns {boolean} Whether the game is focused
*/
gameFocused() {
const inputs = document.querySelectorAll("input, textarea");
for (const input of inputs) {
if (input.matches(":focus"))
return false;
}
return true;
}
/**
* Check if a key is currently being held down.
* @param {any} key Key to check for
* @returns {boolean} Whether key is being held down
*/
isDown(key) {
return this._currentlyDown.has(key);
}
// Key is pressed (fires once)
/**
* Add an event to listen for a specific key press. Will fire once.
* @param {any|any[]} key Key(s) to listen for
* @param {function} func Function to run upon firing
*/
onPress(key, func = () => {}) {
if (key instanceof Array)
for (const k of key)
this._press.on(k, func);
else
this._press.on(key, func);
}
/**
* Fire a specific key if there are events listening for it.
* @param {any} key Key to fire
* @param {any} args Optional arguments to pass into function
* @protected
*/
_doPress(key, args = null) {
if (!this._condition())
return;
this._press.do(key, null, args);
}
// Key is released (fires once)
/**
* Add an event to listen for a specific key release. Will fire once.
* @param {any|any[]} key Key(s) to listen for
* @param {function} func Function to run upon firing
*/
onRelease(key, func = () => {}) {
if (key instanceof Array)
for (const k of key)
this._release.on(k, func);
else
this._release.on(key, func);
}
/**
* Fire a specific key if there are events listening for it.
* @param {any} key Key to fire
* @param {any} args Optional arguments to pass into function
* @protected
*/
_doRelease(key, args = null) {
if (!this._condition())
return;
this._release.do(key, null, args);
}
// Key is pressed down (continuously fires)
/**
* Add an event to fire while a key is pressed down. Fires continuously.
* @param {any|any[]} key Key(s) to listen for
* @param {function} func Function to run upon firing
*/
whileDown(key, func = () => {}) {
if (key instanceof Array)
for (const k of key)
this._down.on(k, func);
else
this._down.on(key, func);
}
/**
* Fire a specific key if there are events listening for it.
* @param {any} key Key to fire
* @param {any} args Optional arguments to pass into function
* @protected
*/
_doDown(key, args = null) {
if (!this._condition())
return;
this._down.do(key, null, args);
}
}
export default InputHandler;