@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
88 lines (72 loc) • 2.54 kB
JavaScript
import { assert } from "../../../assert.js";
import { array_push_if_unique } from "../../../collection/array/array_push_if_unique.js";
import { compileReactiveExpression } from "../../../lang/reactive/compileReactiveExpression.js";
import DataType from "../../../parser/simple/DataType.js";
import { inferReactiveExpressionTypes } from "../transform/inferReactiveExpressionTypes.js";
export class ReactiveTrigger {
/**
*
* @param {string} code
*/
constructor(code) {
assert.isString(code, "code");
/**
* @readonly
* @type {ReactiveExpression}
*/
this.expression = compileReactiveExpression(code);
//infer types
inferReactiveExpressionTypes(this.expression);
if (this.expression.dataType === DataType.Any) {
//enforce top level type
this.expression.dataType = DataType.Boolean;
}
/**
* Cached flat list of references
* @type {ReactiveReference[]}
*/
this.references = [];
this.expression.traverse(
/**
*
* @param {ReactiveExpression|ReactiveReference} node
*/
(node) => {
if (node.isReference) {
array_push_if_unique(this.references, node);
}
});
}
/**
*
* @param {function(ReactiveReference)} visitor
* @param {*} [thisArg]
*/
traverseReferences(visitor, thisArg) {
this.references.forEach(visitor, thisArg);
}
/**
* Given a dictionary-style object, connect references in the expression to values of properties with matching names.
* @example given object {a: Vector1} and expression a > 7, value of A will be taken from that input object
* @param {Object} data
*/
connect(data) {
assert.isObject(data, 'data');
const references = this.references;
const ref_count = references.length;
for (let i = 0; i < ref_count; i++) {
const ref = references[i];
const refName = ref.name;
const datum = data[refName];
ref.connect(datum);
}
}
disconnect() {
const references = this.references;
const ref_count = references.length;
for (let i = 0; i < ref_count; i++) {
const ref = references[i];
ref.disconnect();
}
}
}