All files / ts/controller/input inputReceiver.ts

100% Statements 56/56
100% Branches 4/4
100% Functions 9/9
100% Lines 53/53

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 881x 1x 1x     1x     1x               10x 10x 10x 10x   10x 10x 10x   10x 10x   10x 10x 10x 10x 10x 10x 10x 10x 10x 10x       1x 1x   1x 1x   1x 1x 1x 1x 1x 1x 1x 1x 1x 1x       2x 2x 2x 1x   1x       1x 1x       1x 1x       1x 1x 1x 1x 1x   1x    
import { Bounds2, IBounds2 } from "../../models/bounds2.js";
import { EventTouch } from "./events/eventTouch.js";
import { EventMouse } from "./events/eventMouse.js";
import { IDestroyable } from "../../environment/objectStates.js";
import { IEngineCanvas } from "../../engineCanvas.js";
import { EventKey } from "./events/eventKey.js";
 
export interface IInputReceiver extends EventTarget, IDestroyable { }
export class InputReceiver extends EventTarget implements IInputReceiver {
 
    private readonly _engineCanvas: IEngineCanvas;
    private readonly _keyEvent: (event: KeyboardEvent) => void;
    private readonly _mouseEvent: (event: MouseEvent) => void;
    private readonly _touchEvent: (event: TouchEvent) => void;
 
    public constructor(engineCanvas: IEngineCanvas) {
        super();
        this._engineCanvas = engineCanvas;
        const document = this._engineCanvas.ownerDocument;
        const defaultView = <Window>document.defaultView;
 
        this._keyEvent = (e): void => this.onKey(e);
        this._mouseEvent = (e): void => this.onMouse(e);
        this._touchEvent = (e): void => this.onTouch(e);
 
        defaultView.addEventListener("keydown", this._keyEvent);
        defaultView.addEventListener("keyup", this._keyEvent);
 
        this._engineCanvas.addEventListener("keydown", this._keyEvent);
        this._engineCanvas.addEventListener("keyup", this._keyEvent);
        this._engineCanvas.addEventListener("mousedown", this._mouseEvent);
        this._engineCanvas.addEventListener("mouseup", this._mouseEvent);
        this._engineCanvas.addEventListener("mousemove", this._mouseEvent);
        this._engineCanvas.addEventListener("mouseleave", this._mouseEvent);
        this._engineCanvas.addEventListener("touchstart", this._touchEvent, false);
        this._engineCanvas.addEventListener("touchend", this._touchEvent, false);
        this._engineCanvas.addEventListener("touchcancel", this._touchEvent, false);
        this._engineCanvas.addEventListener("touchmove", this._touchEvent, false);
    }
 
    public destroy(): void {
        const document = this._engineCanvas.ownerDocument;
        const defaultView = <Window>document.defaultView;
 
        defaultView.removeEventListener("keydown", this._keyEvent);
        defaultView.removeEventListener("keyup", this._keyEvent);
 
        this._engineCanvas.removeEventListener("keydown", this._keyEvent);
        this._engineCanvas.removeEventListener("keyup", this._keyEvent);
        this._engineCanvas.removeEventListener("mousedown", this._mouseEvent);
        this._engineCanvas.removeEventListener("mouseup", this._mouseEvent);
        this._engineCanvas.removeEventListener("mousemove", this._mouseEvent);
        this._engineCanvas.removeEventListener("mouseleave", this._mouseEvent);
        this._engineCanvas.removeEventListener("touchstart", this._touchEvent, false);
        this._engineCanvas.removeEventListener("touchend", this._touchEvent, false);
        this._engineCanvas.removeEventListener("touchcancel", this._touchEvent, false);
        this._engineCanvas.removeEventListener("touchmove", this._touchEvent, false);
    }
 
    private onKey(event: KeyboardEvent): void {
        const document = this._engineCanvas.ownerDocument;
        const focused = document.activeElement === this._engineCanvas;
        if (focused && event.currentTarget instanceof Window)
            return;
 
        this.dispatchEvent(new EventKey(focused, event.type, <KeyboardEventInit>event));
    }
 
    private onMouse(event: MouseEvent): void {
        const position = new Bounds2(event.clientX, event.clientY);
        this.dispatchEvent(new EventMouse(position, event.type, <MouseEventInit>event));
    }
 
    private onTouch(event: TouchEvent): void {
        const positions = this.getTouchPositions(event.changedTouches);
        this.dispatchEvent(new EventTouch(positions, event.type, <TouchEventInit><unknown>event));
    }
 
    private getTouchPositions(touchList: TouchList): Array<IBounds2> {
        const positions = new Array<IBounds2>();
        const touches = Array.from(touchList);
        for (let touch of touches) {
            const position = new Bounds2(touch.clientX, touch.clientY);
            positions.push(position);
        }
        return positions;
    }
}