git @ Cat's Eye Technologies Cosmos-Boulders / master src / input-context.js
master

Tree @master (Download .tar.gz)

input-context.js @masterraw · history · blame

// SPDX-FileCopyrightText: In 2019, Chris Pressey, the original author of this work, placed it into the public domain.
// SPDX-License-Identifier: Unlicense
// For more information, please refer to <https://unlicense.org/>


import { bless } from '../contrib/concoctor-0.2/concoctor.js';
import { concoctJaft as concoct } from '../contrib/jaft-0.2/jaftConcoctor.js';
import { error, isUndefined, not, makeAction } from './utils.js';
import { newMap, get, setr } from './immutable.js';
import { makeGame, updateGame } from './game.js';


/* --[ InputContext objects ]-------------------------------------------------------- */


const makeInputContext = concoct({ newMap, setr, makeGame }, `(x, y, vx, vy) =>
    let ic = newMap();
    let ic = setr("game", makeGame(), ic);
    let ic = setr("leftPressed", false, ic);
    let ic = setr("rightPressed", false, ic);
    let ic = setr("thrustPressed", false, ic);
    let ic = setr("firePressed", false, ic);
    ic`);


const makeControlsAction = bless(function(action, leftPressed, rightPressed, thrustPressed, firePressed, startPressed) {
    return {
        type: "CONTROLS_CHANGED",
        leftPressed: action.leftPressed,
        rightPressed: action.rightPressed,
        thrustPressed: action.thrustPressed,
        firePressed: action.firePressed,
        startPressed: action.startPressed,
        prev: {
            leftPressed: leftPressed,
            rightPressed: rightPressed,
            thrustPressed: thrustPressed,
            firePressed: firePressed,
            startPressed: startPressed
        }
    };
});

// Reducer that takes an InputContext and an Action and returns a new InputContext.
// Action must be one of: FRAME_READY | COIN_INSERTED
const updateInputContext = concoct({
    error, get, setr, not, isUndefined, makeInputContext, makeControlsAction, makeAction, updateGame
}, `(inputContext, action) =>
    isUndefined(inputContext) ? makeInputContext() : (
        const game = get(inputContext, "game");
        action.type === "FRAME_READY" ? (
            const leftPressed =   get(inputContext, "leftPressed");
            const rightPressed =  get(inputContext, "rightPressed");
            const thrustPressed = get(inputContext, "thrustPressed");
            const firePressed =   get(inputContext, "firePressed");
            const startPressed =  get(inputContext, "startPressed");
            const game2 = (
                not(action.leftPressed === leftPressed) ||
                not(action.rightPressed === rightPressed) ||
                not(action.thrustPressed === thrustPressed) ||
                not(action.firePressed === firePressed) ||
                not(action.startPressed === startPressed)) ?
                    updateGame(game, makeControlsAction(action, leftPressed, rightPressed, thrustPressed, firePressed, startPressed)) : game;
            const game3 = updateGame(game2, makeAction("FRAME_READY"));
            let ic = setr("game", game3, inputContext);
            let ic = setr("leftPressed", action.leftPressed, ic);
            let ic = setr("rightPressed", action.rightPressed, ic);
            let ic = setr("thrustPressed", action.thrustPressed, ic);
            let ic = setr("firePressed", action.firePressed, ic);
            let ic = setr("startPressed", action.startPressed, ic);
            ic
        ) : (
            action.type === "COIN_INSERTED" ? setr("game", updateGame(game, action), inputContext) : error("Unhandled action", action.type)
        )
    )`);

export { updateInputContext };