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';
export const wait = (duration) => {
let resolve;
const promise = new TickingPromise(_resolve => resolve = _resolve);
promise.ticker = (elapsed) => {
duration -= elapsed;
if (duration <= 0) {
resolve();
}
}
return promise;
return new TickingPromise(
() => {},
(elapsed, resolve) => {
duration -= elapsed;
if (duration <= 0) {
resolve();
}
},
);
};

View File

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

View File

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

View File

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

View File

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