Continued iterating on calculations, added failing test for bugs found
This commit is contained in:
@@ -4,10 +4,13 @@ import { unset } from 'lodash';
|
||||
export default function removeSchemaFields(schemas, prop){
|
||||
schemas.forEach(schema => {
|
||||
schema._schemaKeys.forEach(key => {
|
||||
// Skip object and array keys
|
||||
// Skip object and array keys, except the errors array
|
||||
if (
|
||||
schema.getQuickTypeForKey(key) === 'object' ||
|
||||
schema.getQuickTypeForKey(key) === 'objectArray'
|
||||
(
|
||||
schema.getQuickTypeForKey(key) === 'objectArray' &&
|
||||
key.slice(-6)!== 'errors'
|
||||
)
|
||||
) return;
|
||||
// Unset other computed only keys
|
||||
applyFnToKey(prop, key, unset)
|
||||
|
||||
@@ -29,6 +29,9 @@ function evaluateCalculation(calculation, scope){
|
||||
} else {
|
||||
calculation.errors = context.errors
|
||||
}
|
||||
// remove the working fields
|
||||
delete calculation._parseLevel;
|
||||
delete calculation._parsedCalculation;
|
||||
}
|
||||
|
||||
function embedInlineCalculations(inlineCalcObj){
|
||||
|
||||
@@ -6,13 +6,16 @@ import clean from '../../utility/cleanProp.testFn.js';
|
||||
export default function(){
|
||||
const computation = buildComputationFromProps(testProperties);
|
||||
computeCreatureComputation(computation);
|
||||
|
||||
|
||||
const prop = computation.propsById['actionId'];
|
||||
assert.equal(prop.summary.value, 'test summary 3 without referencing anything 7');
|
||||
assert.equal(prop.description.value, 'test description 12 with reference 0.25 prop');
|
||||
assert.equal(prop.uses.value, 7);
|
||||
assert.equal(prop.usesLeft, 2);
|
||||
|
||||
const rolled = computation.propsById['rolledDescriptionId'];
|
||||
assert.equal(rolled.summary.value, 'test roll gets compiled {1d4 + 4} properly');
|
||||
|
||||
const itemConsumed = prop.resources.itemsConsumed[0];
|
||||
assert.equal(itemConsumed.quantity.value, 3);
|
||||
assert.equal(itemConsumed.available, 27);
|
||||
@@ -60,6 +63,14 @@ var testProperties = [
|
||||
},
|
||||
usesUsed: 5,
|
||||
}),
|
||||
clean({
|
||||
_id: 'rolledDescriptionId',
|
||||
type: 'action',
|
||||
ancestors: [{id: 'charId'}],
|
||||
summary: {
|
||||
text: 'test roll gets compiled {1d4 + (2 + 2)} properly',
|
||||
},
|
||||
}),
|
||||
clean({
|
||||
_id: 'numItemsConumedId',
|
||||
type: 'attribute',
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { Meteor } from 'meteor/meteor'
|
||||
import { isEqual, forOwn } from 'lodash';
|
||||
import { isEqual } from 'lodash';
|
||||
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
|
||||
import propertySchemasIndex from '/imports/api/properties/computedOnlyPropertySchemasIndex.js';
|
||||
|
||||
export default function writeAlteredProperties(computation){
|
||||
let bulkWriteOperations = [];
|
||||
// Loop through all properties on the memo
|
||||
forOwn(computation.propsById, changed => {
|
||||
computation.props.forEach(changed => {
|
||||
let schema = propertySchemasIndex[changed.type];
|
||||
if (!schema){
|
||||
console.warn('No schema for ' + changed.type);
|
||||
@@ -36,6 +36,9 @@ function addChangedKeysToOp(op, keys, original, changed) {
|
||||
// and compile an operation that sets all those keys
|
||||
for (let key of keys){
|
||||
if (!isEqual(original[key], changed[key])){
|
||||
console.log('not equal: ', key);
|
||||
console.log(original[key])
|
||||
console.log(changed[key])
|
||||
if (!op) op = newOperation(original._id, changed.type);
|
||||
let value = changed[key];
|
||||
if (value === undefined){
|
||||
@@ -83,6 +86,7 @@ function addUnsetOp(op, key){
|
||||
// compensation without needing to roll back changes, which causes multiple
|
||||
// expensive redraws of the character sheet
|
||||
function writePropertiesSequentially(bulkWriteOps){
|
||||
console.log({opsLength: bulkWriteOps.length});
|
||||
bulkWriteOps.forEach(op => {
|
||||
let updateOneOrMany = op.updateOne || op.updateMany;
|
||||
CreatureProperties.update(updateOneOrMany.filter, updateOneOrMany.update, {
|
||||
@@ -91,6 +95,7 @@ function writePropertiesSequentially(bulkWriteOps){
|
||||
bypassCollection2: true,
|
||||
});
|
||||
});
|
||||
console.log('finished writing ops');
|
||||
}
|
||||
|
||||
// This is more efficient on the database, but significantly less efficient
|
||||
|
||||
@@ -9,6 +9,7 @@ const DamageSchema = createPropertySchema({
|
||||
type: 'fieldToCompute',
|
||||
optional: true,
|
||||
defaultValue: '1d8 + strength.modifier',
|
||||
parseLevel: 'compile',
|
||||
},
|
||||
// Who this damage applies to
|
||||
target: {
|
||||
@@ -31,6 +32,7 @@ const ComputedOnlyDamageSchema = createPropertySchema({
|
||||
amount: {
|
||||
type: 'computedOnlyField',
|
||||
optional: true,
|
||||
parseLevel: 'compile',
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ function computedOnlyInlineCalculationField(field){
|
||||
},
|
||||
[`${field}.inlineCalculations.$`]: {
|
||||
type: Object,
|
||||
parseLevel: 'compile',
|
||||
},
|
||||
// The part between bracers {}
|
||||
[`${field}.inlineCalculations.$.calculation`]: {
|
||||
|
||||
@@ -15,7 +15,7 @@ let schema = new SimpleSchema({
|
||||
|
||||
Meteor.publish('singleCharacter', function(creatureId){
|
||||
schema.validate({ creatureId });
|
||||
this.autorun(function (){
|
||||
this.autorun(function (computation){
|
||||
let userId = this.userId;
|
||||
let creatureCursor
|
||||
creatureCursor = Creatures.find({
|
||||
@@ -24,7 +24,7 @@ Meteor.publish('singleCharacter', function(creatureId){
|
||||
let creature = creatureCursor.fetch()[0];
|
||||
try { assertViewPermission(creature, userId) }
|
||||
catch(e){ return [] }
|
||||
if (creature.computeVersion !== VERSION){
|
||||
if (creature.computeVersion !== VERSION && computation.firstRun){
|
||||
try {
|
||||
computeCreature(creatureId)
|
||||
}
|
||||
|
||||
@@ -1,18 +1,17 @@
|
||||
<template lang="html">
|
||||
<div class="attribute-form">
|
||||
<div class="layout column align-center">
|
||||
<text-field
|
||||
<computed-field
|
||||
ref="focusFirst"
|
||||
label="Base Value"
|
||||
class="base-value-field"
|
||||
hint="This is the value of the attribute before effects are applied. Can be a number or a calculation"
|
||||
style="width: 332px;"
|
||||
:value="model.baseValueCalculation"
|
||||
:error-messages="errors.baseValueCalculation"
|
||||
@change="change('baseValueCalculation', ...arguments)"
|
||||
:model="model.baseValue"
|
||||
:error-messages="errors.baseValue"
|
||||
@change="({path, value, ack}) => $emit('change', {path: ['baseValue', ...path], value, ack})"
|
||||
/>
|
||||
</div>
|
||||
<calculation-error-list :errors="model.baseValueErrors" />
|
||||
<div class="layout wrap">
|
||||
<text-field
|
||||
label="Name"
|
||||
@@ -54,14 +53,12 @@
|
||||
:error-messages="errors.spellSlotLevelCalculation"
|
||||
@change="change('spellSlotLevelCalculation', ...arguments)"
|
||||
/>
|
||||
<calculation-error-list :errors="model.spellSlotLevelErrors" />
|
||||
<text-area
|
||||
label="Description"
|
||||
:value="model.description"
|
||||
:error-messages="errors.description"
|
||||
@change="change('description', ...arguments)"
|
||||
/>
|
||||
<calculation-error-list :calculations="model.descriptionCalculations" />
|
||||
<form-section
|
||||
name="Advanced"
|
||||
standalone
|
||||
@@ -122,12 +119,12 @@
|
||||
<script lang="js">
|
||||
import FormSection from '/imports/ui/properties/forms/shared/FormSection.vue';
|
||||
import propertyFormMixin from '/imports/ui/properties/forms/shared/propertyFormMixin.js';
|
||||
import CalculationErrorList from '/imports/ui/properties/forms/shared/CalculationErrorList.vue';
|
||||
import ComputedField from '/imports/ui/properties/forms/shared/ComputedField.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
FormSection,
|
||||
CalculationErrorList,
|
||||
ComputedField,
|
||||
},
|
||||
mixins: [propertyFormMixin],
|
||||
inject: {
|
||||
|
||||
29
app/imports/ui/properties/forms/shared/ComputedField.vue
Normal file
29
app/imports/ui/properties/forms/shared/ComputedField.vue
Normal file
@@ -0,0 +1,29 @@
|
||||
<template lang="html">
|
||||
<div class="computed-field">
|
||||
<text-field
|
||||
:value="model.calculation"
|
||||
v-bind="$attrs"
|
||||
@change="(value, ack) => $emit('change', {path: ['calculation'], value, ack})"
|
||||
/>
|
||||
<calculation-error-list :errors="model.errors" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CalculationErrorList from '/imports/ui/properties/forms/shared/CalculationErrorList.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
CalculationErrorList,
|
||||
},
|
||||
props: {
|
||||
model: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="css" scoped>
|
||||
</style>
|
||||
Reference in New Issue
Block a user