import {compose, TickingPromise} from '@avocado/core'; import {EventEmitter} from '@avocado/mixins'; import {Traversal} from './traversal'; import {Traversals} from './traversals'; const decorate = compose( EventEmitter, ); export class Actions extends decorate(Traversals) { constructor() { super(); this._index = 0; this.traversals = []; this.pending = null; } emitFinished() { this.emit('actionsFinished'); } get index() { return this._index; } set index(index) { this._index = index; } tick(context, elapsed) { if (this.traversals.length === 0) { this.emitFinished(); return; } if ( this.pending && this.pending instanceof TickingPromise && 'function' === typeof this.pending.ticker ) { this.pending.ticker(elapsed); return; } // Actions execute immediately until a promise is made, or they're all // executed. while (true) { const result = this.traversals[this.index].traverse(context); if (result instanceof Promise) { result.then(() => this.prologue()); result.catch((error) => { throw error; }); this.pending = result; break; } this.prologue(); if (0 === this.index) { break; } } } prologue() { this.pending = null; if (0 === (this.index = (this.index + 1) % this.traversals.length)) { this.emitFinished(); } } }