Began replacing calls to helpers with calls to memoized functions
This commit is contained in:
@@ -257,8 +257,16 @@ var attributeBase = function(charId, statName){
|
||||
};
|
||||
|
||||
if (Meteor.isClient) {
|
||||
Template.registerHelper("charCalculate", function(func, charId, input) {
|
||||
return Characters.calculate[func](charId, input);
|
||||
Template.registerHelper("characterCalculate", function(func, charId, input) {
|
||||
try {
|
||||
return Characters.calculate[func](charId, input);
|
||||
} catch (e){
|
||||
if (!Characters.calculate[func]){
|
||||
throw new Error(func + "is not a function name");
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -311,15 +319,15 @@ Characters.calculate = {
|
||||
attributeValue: memoize(function(charId, attributeName){
|
||||
var attribute = Characters.calculate.getField(charId, attributeName);
|
||||
//base value
|
||||
var value = Characters.calculate.attributeBase(attributeName);
|
||||
var value = Characters.calculate.attributeBase(charId, attributeName);
|
||||
//plus adjustment
|
||||
value += attribute.adjustment;
|
||||
return value;
|
||||
}),
|
||||
attributeBase: preventLoop(memoize(function(charId, attributeName){
|
||||
attributeBase: memoize(preventLoop(function(charId, attributeName){
|
||||
return attributeBase(charId, attributeName);
|
||||
})),
|
||||
skillMod: preventLoop(memoize(function(charId, skillName){
|
||||
skillMod: memoize(preventLoop(function(charId, skillName){
|
||||
var skill = Characters.calculate.getField(charId, skillName);
|
||||
//get the final value of the ability score
|
||||
var ability = Characters.calculate.attributeValue(charId, skill.ability);
|
||||
@@ -369,7 +377,7 @@ Characters.calculate = {
|
||||
{charId: charId, name: skillName, enabled: true},
|
||||
{sort: {value: -1}}
|
||||
);
|
||||
return prof && prof.value;
|
||||
return prof && prof.value || 0;
|
||||
}),
|
||||
passiveSkill: memoize(function(charId, skillName){
|
||||
var skill = Characters.calculate.getField(charId, skillName);
|
||||
@@ -435,7 +443,11 @@ Characters.calculate = {
|
||||
|
||||
var depreciated = function() {
|
||||
var err = new Error();
|
||||
console.log("this function has been superceeded", {stacktrace: err.stack});
|
||||
var name = "";
|
||||
if(Template.instance()){
|
||||
name = Template.instance().view.name;
|
||||
}
|
||||
console.log("this function has been depreciated", {viewName: name, stacktrace: err.stack});
|
||||
};
|
||||
|
||||
//functions and calculated values.
|
||||
|
||||
@@ -18,10 +18,10 @@
|
||||
</div>
|
||||
<div class="resourceValue" layout vertical center>
|
||||
<div>
|
||||
{{../attributeValue name}}
|
||||
{{characterCalculate "attributeValue" ../_id name}}
|
||||
</div>
|
||||
<div class="title white-text">
|
||||
d{{diceNum}} {{../abilityMod "constitution"}}
|
||||
d{{diceNum}} {{characterCalculate "abilityMod" ../_id "constitution"}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<!-- needs name, char, and skillName -->
|
||||
<!-- needs name, charId, and skillName -->
|
||||
<template name="skillDialog">
|
||||
{{#baseDialog title=name class=color hideEdit=true}}
|
||||
{{> skillDialogView}}
|
||||
@@ -8,7 +8,7 @@
|
||||
<template name="skillDialogView">
|
||||
<div layout vertical center>
|
||||
<div class="display2">
|
||||
{{char.skillMod skillName}}
|
||||
{{characterCalculate "skillMod" charId skillName}}
|
||||
</div>
|
||||
<div class="subhead">
|
||||
<core-icon icon="{{profIcon}}" class="black54"></core-icon>
|
||||
@@ -25,9 +25,9 @@
|
||||
<table class="summaryTable">
|
||||
<tr>
|
||||
<td>{{abilityName}}</td>
|
||||
<td>{{char.abilityMod ability}}</td>
|
||||
<td>{{characterCalculate "abilityMod" charId ability}}</td>
|
||||
</tr>
|
||||
{{#if char.proficiency skillName}}
|
||||
{{#if characterCalculate "proficiency" charId skillName}}
|
||||
<tr>
|
||||
<td>{{proficiencyValue}}</td>
|
||||
<td>{{signedString profBonus}}</td>
|
||||
@@ -59,7 +59,7 @@
|
||||
{{/each}}
|
||||
<tr class="body2">
|
||||
<td>Total</td>
|
||||
<td>{{char.skillMod skillName}}</td>
|
||||
<td>{{characterCalculate "skillMod" charId skillName}}</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
@@ -106,9 +106,7 @@ Template.skillDialogView.helpers({
|
||||
return a || b || c;
|
||||
},
|
||||
profIcon: function(){
|
||||
var char = Characters.findOne(this.charId);
|
||||
if (!char) return;
|
||||
var prof = char.proficiency(this.skillName);
|
||||
var prof = Characters.calculate.proficiency(this.charId, this.skillName);
|
||||
if (prof > 0 && prof < 1) return "image:brightness-2";
|
||||
if (prof === 1) return "image:brightness-1";
|
||||
if (prof > 1) return "av:album";
|
||||
@@ -123,13 +121,13 @@ Template.skillDialogView.helpers({
|
||||
profBonus: function(){
|
||||
var char = Characters.findOne(this.charId);
|
||||
if (!char) return;
|
||||
return char.proficiency(this.skillName) *
|
||||
char.attributeValue("proficiencyBonus");
|
||||
var prof = Characters.calculate.proficiency(this.charId, this.skillName);
|
||||
var proficiencyBonus =
|
||||
Characters.calculate.attributeValue(this.charId, "proficiencyBonus");
|
||||
return prof * proficiencyBonus;
|
||||
},
|
||||
proficiencyValue: function(){
|
||||
var char = Characters.findOne(this.charId);
|
||||
if (!char) return;
|
||||
var prof = char.proficiency(this.skillName);
|
||||
var prof = Characters.calculate.proficiency(this.charId, this.skillName);
|
||||
if (prof == 0.5) return "Half Proficiency";
|
||||
if (prof == 1) return "Proficient";
|
||||
if (prof == 2) return "Double Proficiency";
|
||||
@@ -199,22 +197,15 @@ Template.skillDialogView.helpers({
|
||||
return skill.ability;
|
||||
},
|
||||
abilityName: function(){
|
||||
var opts = {fields: {}};
|
||||
opts.fields[this.skillName] = 1;
|
||||
var char = Characters.findOne(this.charId, opts);
|
||||
if (!char) return;
|
||||
var skill = char[this.skillName];
|
||||
var skill = Characters.calculate.getField(this.charId, this.skillName);
|
||||
if (!skill) return;
|
||||
var ability = skill.ability;
|
||||
return abilities[ability] && abilities[ability].name;
|
||||
},
|
||||
char: function(){
|
||||
return Characters.findOne(this.charId, {fields:{_id: 1}});
|
||||
},
|
||||
sourceName: function(){
|
||||
if (this.parent.collection === "Characters"){
|
||||
if (this.parent.group === "racial"){
|
||||
return Characters.findOne(this.charId, {fields:{race: 1}}).race || "Race";
|
||||
return Characters.calculate.getField(this.charId, "race") || "Race";
|
||||
}
|
||||
if (this.parent.group === "background"){
|
||||
return "Background";
|
||||
|
||||
@@ -8,7 +8,9 @@
|
||||
{{#if failSkill}}
|
||||
<div class="fail skill-mod">fail</div>
|
||||
{{else}}
|
||||
<div class="{{advantage}} skill-mod">{{../skillMod skill}}</div>
|
||||
<div class="{{advantage}} skill-mod">
|
||||
{{characterCalculate "skillMod" ../_id skill}}
|
||||
</div>
|
||||
{{/if}}
|
||||
<div flex>
|
||||
{{name}}
|
||||
@@ -16,7 +18,7 @@
|
||||
*
|
||||
{{/if}}
|
||||
{{#if showPassive}}
|
||||
({{../passiveSkill skill}})
|
||||
({{characterCalculate "passiveSkill" ../_id skill}})
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -7,7 +7,7 @@ Template.skillRow.helpers({
|
||||
return "radio-button-off";
|
||||
},
|
||||
failSkill: function(){
|
||||
var charId = Template.parentData(1)._id;
|
||||
var charId = Template.parentData()._id;
|
||||
return Effects.find({
|
||||
charId: charId,
|
||||
stat: this.skill,
|
||||
@@ -16,12 +16,13 @@ Template.skillRow.helpers({
|
||||
}).count();
|
||||
},
|
||||
advantage: function(){
|
||||
var advantage = Template.parentData(1).advantage(this.skill);
|
||||
var charId = Template.parentData()._id;
|
||||
var advantage = Characters.calculate.advantage(charId, this.skill);
|
||||
if (advantage > 0) return "advantage";
|
||||
if (advantage < 0) return "disadvantage";
|
||||
},
|
||||
conditionalCount: function(){
|
||||
var charId = Template.parentData(1)._id;
|
||||
var charId = Template.parentData()._id;
|
||||
return Effects.find({
|
||||
charId: charId,
|
||||
stat: this.skill,
|
||||
|
||||
@@ -75,9 +75,9 @@
|
||||
<div class="left display1 white-text {{color}}"
|
||||
hero-id="toolbar" {{detailHero stat ../_id}}>
|
||||
{{#if isSkill}}
|
||||
{{../skillMod stat}}
|
||||
{{characterCalculate "skillMod" ../_id stat}}
|
||||
{{else}}
|
||||
{{prefix}}{{../attributeValue stat}}
|
||||
{{prefix}}{{characterCalculate "attributeValue" ../_id stat}}
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="right subhead" flex horizontal layout center>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
preventLoop = function(inputFunction){
|
||||
var self = this;
|
||||
if (!_.isFunction(inputFunction)){
|
||||
throw new Meteor.Error(
|
||||
"Not a function",
|
||||
@@ -9,23 +10,26 @@ preventLoop = function(inputFunction){
|
||||
//if we try to visit the same argument twice before resolving its value
|
||||
//we are in a dependency loop and need to GTFO
|
||||
var visitedArgs = [];
|
||||
return function(argument){
|
||||
var value;
|
||||
return function(){
|
||||
var result;
|
||||
var hash = _.reduce(arguments, function(memo, arg) {
|
||||
return memo + arg;
|
||||
}, "");
|
||||
//we're still evaluating this attribute, must be in a loop
|
||||
if (_.contains(visitedArgs, argument)) {
|
||||
if (_.contains(visitedArgs, hash)) {
|
||||
console.warn("dependency loop detected");
|
||||
return NaN;
|
||||
} else {
|
||||
//push this skill to the list of visited skills
|
||||
//push this hash to the list of visited hashes
|
||||
//we can't visit it again unless it returns first
|
||||
visitedArgs.push(argument);
|
||||
visitedArgs.push(hash);
|
||||
}
|
||||
try {
|
||||
value = inputFunction.call(this, argument);
|
||||
result = inputFunction.apply(this, arguments);
|
||||
} finally{
|
||||
//this argument returns or fails, pull it from the array
|
||||
visitedArgs = _.without(visitedArgs, argument);
|
||||
//this hash returns or fails, pull it from the array
|
||||
visitedArgs = _.without(visitedArgs, hash);
|
||||
}
|
||||
return value;
|
||||
return result;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -24,7 +24,7 @@ function CacheObject(func, address, args, cache, context){
|
||||
if (!computation.firstRun && !self.dep.hasDependents()){
|
||||
computation.stop();
|
||||
delete cache[address];
|
||||
console.log("Nothing depends on '" + address + "', deleting");
|
||||
return;
|
||||
}
|
||||
//call the expensive function
|
||||
var newValue = func.apply(context, args);
|
||||
|
||||
Reference in New Issue
Block a user