@babylonjs/core
Version:
Getting started? Play directly with the Babylon.js API using our [playground](https://playground.babylonjs.com/). It also contains a lot of samples to learn how to use it.
101 lines • 3.88 kB
JavaScript
/**
* Class used to evaluate queries containing `and` and `or` operators
*/
export class AndOrNotEvaluator {
/**
* Evaluate a query
* @param query defines the query to evaluate
* @param evaluateCallback defines the callback used to filter result
* @returns true if the query matches
*/
static Eval(query, evaluateCallback) {
if (!query.match(/\([^()]*\)/g)) {
query = AndOrNotEvaluator._HandleParenthesisContent(query, evaluateCallback);
}
else {
query = query.replace(/\([^()]*\)/g, (r) => {
// remove parenthesis
r = r.slice(1, r.length - 1);
return AndOrNotEvaluator._HandleParenthesisContent(r, evaluateCallback);
});
}
if (query === "true") {
return true;
}
if (query === "false") {
return false;
}
return AndOrNotEvaluator.Eval(query, evaluateCallback);
}
static _HandleParenthesisContent(parenthesisContent, evaluateCallback) {
evaluateCallback =
evaluateCallback ||
((r) => {
return r === "true" ? true : false;
});
let result;
const or = parenthesisContent.split("||");
for (const i in or) {
if (Object.prototype.hasOwnProperty.call(or, i)) {
let ori = AndOrNotEvaluator._SimplifyNegation(or[i].trim());
const and = ori.split("&&");
if (and.length > 1) {
for (let j = 0; j < and.length; ++j) {
const andj = AndOrNotEvaluator._SimplifyNegation(and[j].trim());
if (andj !== "true" && andj !== "false") {
if (andj[0] === "!") {
result = !evaluateCallback(andj.substring(1));
}
else {
result = evaluateCallback(andj);
}
}
else {
result = andj === "true" ? true : false;
}
if (!result) {
// no need to continue since 'false && ... && ...' will always return false
ori = "false";
break;
}
}
}
if (result || ori === "true") {
// no need to continue since 'true || ... || ...' will always return true
result = true;
break;
}
// result equals false (or undefined)
if (ori !== "true" && ori !== "false") {
if (ori[0] === "!") {
result = !evaluateCallback(ori.substring(1));
}
else {
result = evaluateCallback(ori);
}
}
else {
result = ori === "true" ? true : false;
}
}
}
// the whole parenthesis scope is replaced by 'true' or 'false'
return result ? "true" : "false";
}
static _SimplifyNegation(booleanString) {
booleanString = booleanString.replace(/^[\s!]+/, (r) => {
// remove whitespaces
r = r.replace(/[\s]/g, () => "");
return r.length % 2 ? "!" : "";
});
booleanString = booleanString.trim();
if (booleanString === "!true") {
booleanString = "false";
}
else if (booleanString === "!false") {
booleanString = "true";
}
return booleanString;
}
}
//# sourceMappingURL=andOrNotEvaluator.js.map