Fixed dependency loops causing a stack overflow. Added level variable

This commit is contained in:
Thaum Rystra
2020-05-14 13:32:46 +02:00
parent 97fcb76454
commit 29588a87d0
4 changed files with 39 additions and 6 deletions

View File

@@ -7,6 +7,7 @@ export default class ComputationMemo {
this.propsById = {};
this.skillsByAbility = {};
this.unassignedEffects = [];
this.classes = {};
props.filter((prop) => {
// skip effects, proficiencies, and class levels for the next pass
if (
@@ -33,17 +34,44 @@ export default class ComputationMemo {
prop.computationDetails = propDetails(prop);
return prop;
}
storeHighestClassLevel(name, prop){
storeHighestClassLevel(name, prop, isBaseClass){
// Only store the highest level classLevel
let stat = this.statsByVariableName[name]
if (!stat){
this.statsByVariableName[name] = prop;
if (isBaseClass){
this.classes[name] = prop;
}
} else if (!has(stat, 'level')){
// Stat is overriden by an attribute
return;
} else if (stat.level < prop.level) {
this.statsByVariableName[name] = prop;
if (isBaseClass){
this.classes[name] = prop;
}
}
this.updateLevel();
}
updateLevel(){
let currentLevel = this.statsByVariableName['level'];
if (!currentLevel){
currentLevel = {
value: 0,
computationDetails: {
builtIn: true,
computed: true,
}
};
this.statsByVariableName['level'] = currentLevel;
}
// bail out if overriden by an attribute
if (!currentLevel.computationDetails.builtIn) return;
let level = 0;
for (let name in this.classes){
level += this.classes[name].level || 0;
}
this.statsByVariableName['level'].value = level;
}
addClassLevel(prop){
prop = this.registerProperty(prop);
@@ -51,7 +79,7 @@ export default class ComputationMemo {
this.storeHighestClassLevel(prop.variableName, prop);
}
if (prop.baseClass){
this.storeHighestClassLevel(prop.baseClass, prop);
this.storeHighestClassLevel(prop.baseClass, prop, true);
}
}
addStat(prop){

View File

@@ -2,11 +2,15 @@ import evaluateCalculation from '/imports/api/creature/computation/evaluateCalcu
export default function computeEffect(effect, memo){
if (effect.computationDetails.computed) return;
if (_.isFinite(effect.calculation)){
if (!effect.calculation){
if(effect.operation === 'add' || effect.operation === 'base'){
effect.result = 0;
}
} else if (Number.isFinite(+effect.calculation)){
effect.result = +effect.calculation;
} else if(effect.operation === "conditional" || effect.operation === "rollBonus"){
} else if(effect.operation === 'conditional' || effect.operation === 'rollBonus'){
effect.result = effect.calculation;
} else if(_.contains(["advantage", "disadvantage", "fail"], effect.operation)){
} else if(_.contains(['advantage', 'disadvantage', 'fail'], effect.operation)){
effect.result = 1;
} else {
effect.result = evaluateCalculation(effect.calculation, memo);

View File

@@ -16,6 +16,8 @@ export default function computeStat(stat, memo){
console.warn('dependencyLoop', stat);
return;
}
// Before doing any work, mark this stat as busy
stat.computationDetails.busyComputing = true;
// Compute and aggregate all the effects
let aggregator = new EffectAggregator(stat, memo)
each(stat.computationDetails.effects, (effect) => {

View File

@@ -9,7 +9,6 @@ export default function evaluateCalculation(string, memo){
try {
calc = math.parse(string);
} catch (e) {
console.error(e);
return string;
}
// Ensure all symbol nodes are defined and coputed