Computation engine rewrite continues
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
import evaluateCalculation from '/imports/api/creature/computation/newEngine/computeComputation/evaluateCalculation.js';
|
||||
import computeVariable from '/imports/api/creature/computation/newEngine/computeComputation/computeVariable.js';
|
||||
|
||||
export default function computeCreatureComputation(computation){
|
||||
const stack = [];
|
||||
// dict of computed nodes by id
|
||||
const scope = {};
|
||||
const graph = computation.dependencyGraph;
|
||||
// Add all nodes to the stack
|
||||
graph.forEachNode(node => stack.push({
|
||||
node,
|
||||
visited: false,
|
||||
visitedChildren: false,
|
||||
}));
|
||||
// Depth first traversal of nodes
|
||||
while (stack.length){
|
||||
let top = stack[stack.length - 1];
|
||||
if (top.visited){
|
||||
// The object has already
|
||||
stack.pop();
|
||||
} else if (top.visitedChildren){
|
||||
// Compute the top object of the stack
|
||||
compute(graph, top.node, scope);
|
||||
// If the node holds a variable, store it in the scope
|
||||
if (!top.node.data?.type){
|
||||
scope[top.node.id] = top.node.data;
|
||||
}
|
||||
// Mark the object as visited and remove from stack
|
||||
top.visited = true;
|
||||
stack.pop();
|
||||
} else {
|
||||
// Push children to graph
|
||||
pushDependenciesToStack(top.node.id, graph, stack);
|
||||
top.visitedChildren = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function compute(graph, node, scope){
|
||||
// Get the property
|
||||
let prop = node.data;
|
||||
|
||||
// evaluate all the calculations
|
||||
if (prop?._computationDetails?.calculations){
|
||||
prop._computationDetails.calculations.forEach(calcObj => {
|
||||
evaluateCalculation(calcObj, scope)
|
||||
});
|
||||
}
|
||||
|
||||
// Compute the property by type
|
||||
let typeCompute = propTypeComputations[prop?.type || '_variable'];
|
||||
typeCompute?.(graph, node);
|
||||
}
|
||||
|
||||
var propTypeComputations = {
|
||||
'_variable': computeVariable,
|
||||
};
|
||||
|
||||
function pushDependenciesToStack(nodeId, graph, stack){
|
||||
graph.forEachLinkedNode(
|
||||
nodeId,
|
||||
(linkedNode, link) => {
|
||||
// Ignore inventory links, they can't cause dependency loops
|
||||
// and are already fully computed when they are created
|
||||
if (link.data === 'inventory') return;
|
||||
stack.push({
|
||||
node: linkedNode,
|
||||
visited: false,
|
||||
visitedChildren: false,
|
||||
});
|
||||
},
|
||||
true // enumerate only outbound links
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user