refactor: TickingPromise is more of a joy

This commit is contained in:
cha0s 2019-09-08 05:34:17 -05:00
parent e87489f691
commit 6b124ab183
6 changed files with 84 additions and 66 deletions

View File

@ -1,13 +1,13 @@
import {TickingPromise} from '@avocado/core'; import {TickingPromise} from '@avocado/core';
export const wait = (duration) => { export const wait = (duration) => {
let resolve; return new TickingPromise(
const promise = new TickingPromise(_resolve => resolve = _resolve); () => {},
promise.ticker = (elapsed) => { (elapsed, resolve) => {
duration -= elapsed; duration -= elapsed;
if (duration <= 0) { if (duration <= 0) {
resolve(); resolve();
} }
} },
return promise; );
}; };

View File

@ -41,11 +41,8 @@ export class Actions extends decorate(Traversals) {
return; return;
} }
if (this.pending) { if (this.pending) {
if ( if (this.pending instanceof TickingPromise) {
this.pending instanceof TickingPromise this.pending.tick(elapsed);
&& 'function' === typeof this.pending.ticker
) {
this.pending.ticker(elapsed);
} }
return; return;
} }
@ -91,15 +88,16 @@ export class Actions extends decorate(Traversals) {
} }
} }
if (tickingPromises.length > 0) { if (tickingPromises.length > 0) {
const tickingPromise = new TickingPromise((resolve) => { return new TickingPromise(
resolve(Promise.all(results)); (resolve) => {
}); resolve(Promise.all(results));
tickingPromise.ticker = (elapsed) => { },
for (let i = 0; i < tickingPromises.length; i++) { (elapsed) => {
tickingPromises[i].ticker(elapsed); for (let i = 0; i < tickingPromises.length; i++) {
} tickingPromises[i].tick(elapsed);
}; }
return tickingPromise; },
);
} }
if (promises.length > 0) { if (promises.length > 0) {
return Promise.all(results); return Promise.all(results);
@ -119,17 +117,16 @@ export class Actions extends decorate(Traversals) {
this.tick(context, 0); this.tick(context, 0);
// If it's pending, we have to return a ticking promise. // If it's pending, we have to return a ticking promise.
if (this.pending) { if (this.pending) {
let resolve_; return new TickingPromise(
const tickingPromise = new TickingPromise((resolve) => { (resolve) => {
resolve_ = resolve; this.once('actionsFinished', () => {
}); resolve();
tickingPromise.ticker = (elapsed) => { });
this.tick(context, elapsed); },
} (elapsed) => {
this.once('actionsFinished', () => { this.tick(context, elapsed);
resolve_(); },
}); );
return tickingPromise;
} }
} }

View File

@ -15,22 +15,26 @@ export class Traversals extends Collection('traversal') {
}, false)) { }, false)) {
return results; return results;
} }
// Otherwise, wrap in a promise. // Proxy any tickers.
const tpromise = new TickingPromise((resolve, reject) => {
return Promise.all(results);
});
// Proxy all ticks.
const tickableResults = results.filter((result) => { const tickableResults = results.filter((result) => {
if (!(result instanceof TickingPromise)) return false; if (!(result instanceof TickingPromise)) {
if ('function' !== typeof result.ticker) return false; return false;
}
return true; return true;
}); });
if (tickableResults.length > 0) { // If none, just promise.
tpromise.ticker = (elapsed) => { if (0 === tickableResults.length) {
tickableResults.forEach((result) => result.ticker(elapsed)); return Promise.all(results);
};
} }
return tpromise; // Otherwise, tick all tickers and resolve.
return new TickingPromise(
(resolve) => {
resolve(Promise.all(results));
},
(elapsed) => {
tickableResults.forEach((result) => result.tick(elapsed));
},
);
} }
} }

View File

@ -62,10 +62,26 @@ export function virtualizeStatic(fields) {
} }
export class TickingPromise extends Promise { export class TickingPromise extends Promise {
constructor(resolve, reject) {
super(resolve, reject); constructor(executor, ticker) {
this.ticker = null; let _reject, _resolve;
super((resolve, reject) => {
_reject = reject;
_resolve = resolve;
if (executor) {
executor(resolve, reject);
}
});
this.executor = executor;
this.reject = _reject;
this.resolve = _resolve;
this.ticker = ticker;
} }
tick(elapsed) {
this.ticker(elapsed, this.resolve, this.reject);
}
} }
export {EventEmitterMixin as EventEmitter} from './event-emitter'; export {EventEmitterMixin as EventEmitter} from './event-emitter';

View File

@ -56,13 +56,14 @@ export class Existent extends decorate(Trait) {
duration, duration,
easing easing
); );
const promise = new TickingPromise((resolve) => { return new TickingPromise(
resolve(result.promise); (resolve) => {
}); resolve(result.promise);
promise.ticker = (elapsed) => { },
result.tick(elapsed); (elapsed) => {
} result.tick(elapsed);
return promise; },
);
}, },
}; };

View File

@ -30,16 +30,16 @@ export class Mobile extends decorate(Trait) {
return { return {
moveFor: (vector, duration) => { moveFor: (vector, duration) => {
let resolve; return new TickingPromise(
const promise = new TickingPromise(_resolve => resolve = _resolve); () => {},
promise.ticker = (elapsed) => { (elapsed, resolve) => {
duration -= elapsed; duration -= elapsed;
if (duration <= 0) { if (duration <= 0) {
return resolve(); return resolve();
} }
this.entity.requestMovement(Vector.normalize(vector)); this.entity.requestMovement(Vector.normalize(vector));
} },
return promise; );
}, },
applyMovement: (vector) => { applyMovement: (vector) => {