Files
DiceCloud/app/imports/api/engine/computation/buildComputation/linkCalculationDependencies.js
Stefan Zermatten 1a14393031 Parsed calculations are now cached between calculations
Parsing is one of the more expensive computations done to characters, so 
the parser results are now stored on the DB and only updated if they are 
dirty. A hash is used to determine if the calculation has changed since 
the last computation
2021-10-03 20:59:04 +02:00

43 lines
1.6 KiB
JavaScript

import findAncestorByType from '/imports/api/engine/computation/utility/findAncestorByType.js';
import { traverse } from '/imports/parser/resolve.js';
export default function linkCalculationDependencies(dependencyGraph, prop, {propsById}){
prop._computationDetails.calculations.forEach(calcObj => {
// Store resolved ancestors
let memo = {
// ancestors: {} //this gets added if there are resolved ancestors
};
// Traverse the parsed calculation looking for variable names
traverse(calcObj.parseNode, node => {
// Skip nodes that aren't symbols or accessors
if (node.parseType !== 'symbol' && node.parseType !== 'accessor') return;
// Link ancestor references as direct property dependencies
if (node.name[0] === '#'){
let ancestorProp = getAncestorProp(
node.name.slice(1), memo, prop, propsById
);
if (!ancestorProp) return;
dependencyGraph.addLink(prop._id, ancestorProp._id, calcObj);
} else {
// Link variable name references as variable dependencies
dependencyGraph.addLink(prop._id, node.name, calcObj);
}
});
// Store the resolved ancestors in this calculation's local scope
if (memo.ancestors) {
calcObj._localScope = { ...calcObj._localScope, ...memo.ancestors};
}
});
}
function getAncestorProp(type, memo, prop, propsById){
if (memo.ancestors && memo.ancestors['#' + type]){
return memo.ancestors['#' + type];
} else {
var ancestorProp = findAncestorByType( prop, type, propsById );
if (!memo.ancestors) memo.ancestors = {};
memo.ancestors['#' + type] = ancestorProp;
return ancestorProp;
}
}