feat: Actions::parallel

This commit is contained in:
cha0s 2019-06-06 00:09:51 -05:00
parent 8803402f43
commit 7b7b688d81
4 changed files with 43 additions and 0 deletions

View File

@ -30,6 +30,7 @@ export function buildValue(value) {
'object' === typeof value 'object' === typeof value
&& ( && (
'traversal' === value.type 'traversal' === value.type
|| 'actions' === value.type
|| 'condition' === value.type || 'condition' === value.type
) )
) { ) {

View File

@ -21,6 +21,10 @@ export class Globals {
console.log(any); console.log(any);
} }
parallel(actions, context) {
return actions.parallel(context);
}
randomNumber(min, max, floor = true) { randomNumber(min, max, floor = true) {
let mag = Math.random() * ((max - min) + 1); let mag = Math.random() * ((max - min) + 1);
return min + (floor ? Math.floor(mag) : mag); return min + (floor ? Math.floor(mag) : mag);

View File

@ -89,6 +89,8 @@ class Context extends Map {
return node[step.key]; return node[step.key];
case 'invoke': case 'invoke':
const args = step.args.map((arg) => arg.get(this)); const args = step.args.map((arg) => arg.get(this));
// Pass the context itself as the last arg.
args.push(this);
// Any arg promises will be resolved; the arg values will be passed // Any arg promises will be resolved; the arg values will be passed
// transparently to the invocation. // transparently to the invocation.
let hasPromise = false; let hasPromise = false;

View File

@ -31,6 +31,10 @@ export class Actions extends decorate(Traversals) {
this._index = index; this._index = index;
} }
get() {
return this;
}
tick(context, elapsed) { tick(context, elapsed) {
if (this.traversals.length === 0) { if (this.traversals.length === 0) {
this.emitFinished(); this.emitFinished();
@ -68,6 +72,38 @@ export class Actions extends decorate(Traversals) {
} }
} }
parallel(context) {
const promises = [];
const results = [];
const tickingPromises = [];
for (let i = 0; i < this.traversals.length; i++) {
const traversal = this.traversals[i];
const result = traversal.traverse(context);
results.push(result);
if (result instanceof TickingPromise) {
tickingPromises.push(result);
}
else if (result instanceof Promise) {
promises.push(result);
}
}
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;
}
if (promises.length > 0) {
return Promise.all(results);
}
return results;
}
prologue() { prologue() {
this.pending = null; this.pending = null;
if (0 === (this.index = (this.index + 1) % this.traversals.length)) { if (0 === (this.index = (this.index + 1) % this.traversals.length)) {