input_handler_keyboard_handler.js

import InputHandler from "./input_handler.js";

/**
 * @module KeyboardHandler
 * @fileoverview Contains KeyboardHandler class.
 */

/**
 * Keyboard input handler.
 * @class
 * @extends InputHandler
 */
class KeyboardHandler extends InputHandler {
    /**
     * Create a new keyboard input handler.
     * @param {EventHandler|EventHandlerLayer} parentHandler Parent event handler or layer
     * @param {function} condition Function for checking whether events should run
     * @constructor
     */
    constructor(parentHandler, condition = () => { return true; }) {
        super(parentHandler, "keyboard/", condition);

        this._downHandler = this._handleDown.bind(this);
        this._upHandler = this._handleUp.bind(this);

        this._blurHandler = this._handleBlur.bind(this);

        this._init();
    }

    destructor() {
        super.destructor();

        document.removeEventListener("keydown", this._downHandler);
        document.removeEventListener("keyup", this._upHandler);

        document.removeEventListener("blur", this._blurHandler);
    }


    // Initialization

    /**
     * Setup up keyboard input listening.
     * @private
     */
    _init() {
        document.addEventListener("keydown", this._downHandler);
        document.addEventListener("keyup", this._upHandler);

        window.addEventListener("blur", this._blurHandler);
    }


    // Handling key presses

    /**
     * Handle the event of pressing down a key.
     * @param {KeyboardEvent} event Event from document
     * @private
     */
    _handleDown(event) {
        if (!this.gameFocused())
            return;

        const key = event.key.toLowerCase();

        if (!this._currentlyDown.has(key))
            this._doPress(key);
        this._currentlyDown.add(key);
        this._doDown(key);
    }

    /**
     * Handle the event of releasing a key.
     * @param {KeyboardEvent} event Event from document
     * @private
     */
    _handleUp(event) {
        const key = event.key.toLowerCase();

        if (!this.gameFocused()) {
            this._currentlyDown.delete(key);
            return;
        }

        this._currentlyDown.delete(key);
        this._doRelease(key);
    }

    /**
     * Handle the event of the page losing focus.
     * @private
     */
    _handleBlur() {
        this._currentlyDown.clear();
    }
}

export default KeyboardHandler;