UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

141 lines (110 loc) 3.25 kB
import { assert } from "../../assert.js"; import TaskState from "../task/TaskState.js"; import { AsynchronousAction } from "./AsynchronousAction.js"; export class AsynchronousActionSequence extends AsynchronousAction { /** * * @param {AsynchronousAction[]} sequence */ constructor(sequence) { super(); assert.isArray(sequence); /** * * @type {AsynchronousAction[]} * @private */ this.__sequence = sequence; this.__index = 0; /** * * @type {AsynchronousAction|null} * @private */ this.__active = null; } /** * * @private */ __finalizeActive() { // remove listeners this.__active.on.finished.remove(this.__handleActiveFinished, this); this.__active.on.failed.remove(this.__handleActiveFailed, this); this.__active.on.cancelled.remove(this.__handleActiveCancelled, this); // advance sequence cursor this.__index++; // clear active this.__active = null; } /** * * @private */ __handleActiveFinished() { this.__finalizeActive(); this.prod(); } /** * * @private */ __handleActiveFailed(reason) { this.__finalizeActive(); this.__fail(reason); } /** * * @private */ __handleActiveCancelled() { this.__finalizeActive(); this.status = TaskState.CANCELLED; this.on.cancelled.send0(); } /** * */ prod() { if (this.status !== TaskState.RUNNING) { return; } if (this.__index === this.__sequence.length) { // reached end of sequence this.__succeed(); return; } if (this.__active === null) { this.__active = this.__sequence[this.__index]; if (this.__active.status === TaskState.CANCELLED) { this.__handleActiveCancelled(); } else { this.__active.on.finished.addOne(this.__handleActiveFinished, this); this.__active.on.failed.addOne(this.__handleActiveFailed, this); this.__active.on.cancelled.addOne(this.__handleActiveCancelled, this); try { this.__active.start(); } catch (e) { // an element failed during start-up sequence this.__handleActiveFailed(e); } } } } cancel() { return new Promise((resolve, reject) => { if (this.status === TaskState.RUNNING) { this.status = TaskState.CANCELLED; this.__active.on.cancelled.remove(this.__handleActiveCancelled, this); this.__active.cancel().then(resolve, reject); this.on.cancelled.send0(); } else { reject(); } }); } start() { super.start(); this.prod(); } }