diff --git a/packages/behavior/item/actions.js b/packages/behavior/item/actions.js index 80a0226..19eaff6 100644 --- a/packages/behavior/item/actions.js +++ b/packages/behavior/item/actions.js @@ -16,7 +16,7 @@ export class Actions extends decorate(Traversals) { constructor() { super(); this._index = 0; - this._pending = null; + this._actionPromise = null; } emitFinished() { @@ -36,33 +36,34 @@ export class Actions extends decorate(Traversals) { } tick(context, elapsed) { + // Empty resolves immediately. if (this.traversals.length === 0) { this.emitFinished(); return; } - if (this._pending) { - if (this._pending instanceof TickingPromise) { - this._pending.tick(elapsed); - } + // If the action promise ticks, tick it. + if (this._actionPromise && this._actionPromise instanceof TickingPromise) { + this._actionPromise.tick(elapsed); return; } - // Actions execute immediately until a promise is made, or they're all // executed. while (true) { + // Run the action. const result = this.traversals[this.index].traverse(context); + // Deferred result. if (result instanceof Promise) { - result.then(() => { + this._actionPromise = result; + // Handle any errors. + result.catch(console.error).finally(() => { + // Finally, run the prologue. this.prologue(); }); - result.catch((error) => { - console.error(error); - this.prologue(); - }); - this._pending = result; break; } + // Immediate result. this.prologue(); + // Need to break out immediately if required. if (0 === this.index) { break; } @@ -70,15 +71,21 @@ export class Actions extends decorate(Traversals) { } parallel(context) { + // Map all traversals to results. const results = this.traversals.map((traversal) => { return traversal.traverse(context); }); + // Wrap all results in a TickingPromise. return TickingPromise.all(results); } prologue() { - this._pending = null; - if (0 === (this.index = (this.index + 1) % this.traversals.length)) { + // Clear out the action promise. + this._actionPromise = null; + // Increment and wrap the index. + this.index = (this.index + 1) % this.traversals.length; + // If rolled over, the actions are finished. + if (0 === this.index) { this.emitFinished(); } } @@ -90,9 +97,7 @@ export class Actions extends decorate(Traversals) { tickingPromise(context) { return new TickingPromise( (resolve) => { - this.once('actionsFinished', () => { - resolve(); - }); + this.once('actionsFinished', resolve); }, (elapsed) => { this.tick(context, elapsed);