69 lines
1.4 KiB
JavaScript
69 lines
1.4 KiB
JavaScript
|
import {TickingPromise} from '@avocado/core';
|
||
|
import {EventEmitter} from '@avocado/mixins';
|
||
|
|
||
|
import {Traversal} from './traversal';
|
||
|
import {Traversals} from './traversals';
|
||
|
|
||
|
@EventEmitter
|
||
|
export class Actions extends Traversals {
|
||
|
|
||
|
static type() {
|
||
|
return 'actions';
|
||
|
}
|
||
|
|
||
|
constructor() {
|
||
|
super();
|
||
|
this.index_PRIVATE = 0;
|
||
|
this.traversals = [];
|
||
|
this.pending = null;
|
||
|
}
|
||
|
|
||
|
get index() {
|
||
|
return this.index_PRIVATE;
|
||
|
}
|
||
|
|
||
|
set index(index) {
|
||
|
this.index_PRIVATE = index;
|
||
|
}
|
||
|
|
||
|
tick(context, elapsed) {
|
||
|
if (this.traversals.length === 0) {
|
||
|
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.invocations.length)) {
|
||
|
this.emit('actionsFinished');
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|