Began migrating the rest of the codebase to the new computation engine
This commit is contained in:
@@ -3,7 +3,7 @@ import { RateLimiterMixin } from 'ddp-rate-limiter-mixin';
|
||||
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
|
||||
import { assertEditPermission } from '/imports/api/sharing/sharingPermissions.js';
|
||||
import getRootCreatureAncestor from '/imports/api/creature/creatureProperties/getRootCreatureAncestor.js';
|
||||
import { computeCreature } from '/imports/api/engine/computeCreature.js';
|
||||
import computeCreature from '/imports/api/engine/computeCreature.js';
|
||||
|
||||
const updateCreatureProperty = new ValidatedMethod({
|
||||
name: 'creatureProperties.update',
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { computeCreature } from '/imports/api/engine/computeCreature.js';
|
||||
import computeCreature from '/imports/api/engine/computeCreature.js';
|
||||
|
||||
/**
|
||||
* Recomputes all ancestor creatures of this property
|
||||
|
||||
@@ -4,7 +4,7 @@ import { RateLimiterMixin } from 'ddp-rate-limiter-mixin';
|
||||
import Creatures from '/imports/api/creature/creatures/Creatures.js';
|
||||
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
|
||||
import { assertEditPermission } from '/imports/api/creature/creatures/creaturePermissions.js';
|
||||
import { computeCreature } from '/imports/api/engine/computeCreature.js';
|
||||
import computeCreature from '/imports/api/engine/computeCreature.js';
|
||||
|
||||
const restCreature = new ValidatedMethod({
|
||||
name: 'creature.methods.longRest',
|
||||
|
||||
@@ -3,7 +3,7 @@ import { ValidatedMethod } from 'meteor/mdg:validated-method';
|
||||
import { RateLimiterMixin } from 'ddp-rate-limiter-mixin';
|
||||
import { assertEditPermission } from '/imports/api/creature/creatures/creaturePermissions.js';
|
||||
import Creatures from '/imports/api/creature/creatures/Creatures.js';
|
||||
import { computeCreature } from '/imports/api/engine/computeCreature.js';
|
||||
import computeCreature from '/imports/api/engine/computeCreature.js';
|
||||
import STORAGE_LIMITS from '/imports/constants/STORAGE_LIMITS.js';
|
||||
|
||||
let Experiences = new Mongo.Collection('experiences');
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { computeCreature } from '/imports/api/engine/computeCreature.js';
|
||||
import computeCreature from '/imports/api/engine/computeCreature.js';
|
||||
|
||||
export default function recomputeCreatureMixin(methodOptions){
|
||||
let runFunc = methodOptions.run;
|
||||
|
||||
@@ -22,6 +22,7 @@ function discoverInlineCalculationFields(prop, schemas){
|
||||
prop._computationDetails.inlineCalculations.push(inlineCalcObj);
|
||||
// Extract the calculations and store them on the property
|
||||
let string = inlineCalcObj.text;
|
||||
if (!string) return;
|
||||
inlineCalcObj.inlineCalculations = [];
|
||||
let matches = string.matchAll(INLINE_CALCULATION_REGEX);
|
||||
for (let match of matches){
|
||||
|
||||
@@ -45,7 +45,7 @@ function getProperties(creatureId){
|
||||
'removed': {$ne: true},
|
||||
}, {
|
||||
sort: {order: 1}
|
||||
});
|
||||
}).fetch();
|
||||
}
|
||||
|
||||
export function buildComputationFromProps(properties){
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
import { Meteor } from 'meteor/meteor'
|
||||
import { isEqual, forOwn } 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 => {
|
||||
let schema = propertySchemasIndex[changed.type];
|
||||
if (!schema){
|
||||
console.warn('No schema for ' + changed.type);
|
||||
return;
|
||||
}
|
||||
let id = changed._id;
|
||||
let op = undefined;
|
||||
let original = computation.originalPropsById[id];
|
||||
let keys = [
|
||||
'inactive',
|
||||
'deactivatedBySelf',
|
||||
'deactivatedByAncestor',
|
||||
'deactivatedByToggle',
|
||||
'damage',
|
||||
...schema.objectKeys(),
|
||||
];
|
||||
op = addChangedKeysToOp(op, keys, original, changed);
|
||||
if (op){
|
||||
bulkWriteOperations.push(op);
|
||||
}
|
||||
});
|
||||
writePropertiesSequentially(bulkWriteOperations);
|
||||
}
|
||||
|
||||
function addChangedKeysToOp(op, keys, original, changed) {
|
||||
// Loop through all keys that can be changed by computation
|
||||
// and compile an operation that sets all those keys
|
||||
for (let key of keys){
|
||||
if (!isEqual(original[key], changed[key])){
|
||||
if (!op) op = newOperation(original._id, changed.type);
|
||||
let value = changed[key];
|
||||
if (value === undefined){
|
||||
// Unset values that become undefined
|
||||
addUnsetOp(op, key);
|
||||
} else {
|
||||
// Set values that changed to something else
|
||||
addSetOp(op, key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
return op;
|
||||
}
|
||||
|
||||
function newOperation(_id, type){
|
||||
let newOp = {
|
||||
updateOne: {
|
||||
filter: {_id},
|
||||
update: {},
|
||||
}
|
||||
};
|
||||
if (Meteor.isClient){
|
||||
newOp.type = type;
|
||||
}
|
||||
return newOp;
|
||||
}
|
||||
|
||||
function addSetOp(op, key, value){
|
||||
if (op.updateOne.update.$set){
|
||||
op.updateOne.update.$set[key] = value;
|
||||
} else {
|
||||
op.updateOne.update.$set = {[key]: value};
|
||||
}
|
||||
}
|
||||
|
||||
function addUnsetOp(op, key){
|
||||
if (op.updateOne.update.$unset){
|
||||
op.updateOne.update.$unset[key] = 1;
|
||||
} else {
|
||||
op.updateOne.update.$unset = {[key]: 1};
|
||||
}
|
||||
}
|
||||
|
||||
// We use this instead of bulkWriteProperties because it functions with latency
|
||||
// compensation without needing to roll back changes, which causes multiple
|
||||
// expensive redraws of the character sheet
|
||||
function writePropertiesSequentially(bulkWriteOps){
|
||||
bulkWriteOps.forEach(op => {
|
||||
let updateOneOrMany = op.updateOne || op.updateMany;
|
||||
CreatureProperties.update(updateOneOrMany.filter, updateOneOrMany.update, {
|
||||
// The bulk code is bypassing validation, so do the same here
|
||||
// selector: {type: op.type} // include this if bypass is off
|
||||
bypassCollection2: true,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// This is more efficient on the database, but significantly less efficient
|
||||
// in the UI because of incompatibility with latency compensation. If the
|
||||
// duplicate redraws can be fixed, this is a strictly better way of processing
|
||||
// writes
|
||||
function bulkWriteProperties(bulkWriteOps){
|
||||
if (!bulkWriteOps.length) return;
|
||||
// bulkWrite is only available on the server
|
||||
if (Meteor.isServer){
|
||||
CreatureProperties.rawCollection().bulkWrite(
|
||||
bulkWriteOps,
|
||||
{ordered : false},
|
||||
function(e){
|
||||
if (e) {
|
||||
console.error('Bulk write failed: ');
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
);
|
||||
} else {
|
||||
writePropertiesSequentially(bulkWriteOps);
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,16 @@
|
||||
import buildCreatureComputation from './computation/buildCreatureComputation.js';
|
||||
import computeCreatureComputation from './computation/computeCreatureComputation.js';
|
||||
import writeAlteredProperties from './computation/writeComputation/writeAlteredProperties.js';
|
||||
|
||||
export default function computeCreature(creatureId){
|
||||
const computation = buildCreatureComputation(creatureId);
|
||||
computeCreatureComputation(computation);
|
||||
// TODO: writeCreatureComputation(computation);
|
||||
writeAlteredProperties(computation);
|
||||
}
|
||||
|
||||
// For now just recompute the whole creature, later only recompute a single
|
||||
// For now just recompute the whole creature, TODO only recompute a single
|
||||
// connected section of the depdendency graph
|
||||
export function computeCreatureDependencyGroup(property){
|
||||
let creatureId = property.ancestors[0].id;
|
||||
const computation = buildCreatureComputation(creatureId);
|
||||
computeCreatureComputation(computation);
|
||||
// TODO: writeCreatureComputation(computation);
|
||||
computeCreature(creatureId);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import evaluateString from '/imports/api/creature/computation/afterComputation/evaluateString.js';
|
||||
// import evaluateString from '/imports/api/creature/computation/afterComputation/evaluateString.js';
|
||||
import damagePropertiesByName from '/imports/api/creature/creatureProperties/methods/damagePropertiesByName.js';
|
||||
|
||||
export default function applyAdjustment({
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import evaluateString from '/imports/api/creature/computation/afterComputation/evaluateString.js';
|
||||
// import evaluateString from '/imports/api/creature/computation/afterComputation/evaluateString.js';
|
||||
import dealDamage from '/imports/api/creature/creatureProperties/methods/dealDamage.js';
|
||||
import {insertCreatureLog} from '/imports/api/creature/log/CreatureLogs.js';
|
||||
import { CompilationContext } from '/imports/parser/parser.js';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import evaluateString from '/imports/api/creature/computation/afterComputation/evaluateString.js';
|
||||
// import evaluateString from '/imports/api/creature/computation/afterComputation/evaluateString.js';
|
||||
|
||||
export default function applyRoll({
|
||||
prop,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import evaluateString from '/imports/api/creature/computation/afterComputation/evaluateString.js';
|
||||
// import evaluateString from '/imports/api/creature/computation/afterComputation/evaluateString.js';
|
||||
import CreaturesProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
|
||||
import roll from '/imports/parser/roll.js';
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import evaluateString from '/imports/api/creature/computation/afterComputation/evaluateString.js';
|
||||
// import evaluateString from '/imports/api/creature/computation/afterComputation/evaluateString.js';
|
||||
|
||||
export default function applyToggle({
|
||||
prop,
|
||||
|
||||
@@ -8,7 +8,7 @@ import { RefSchema } from '/imports/api/parenting/ChildSchema.js';
|
||||
import { assertDocEditPermission } from '/imports/api/sharing/sharingPermissions.js';
|
||||
import fetchDocByRef from '/imports/api/parenting/fetchDocByRef.js';
|
||||
import getCollectionByName from '/imports/api/parenting/getCollectionByName.js';
|
||||
import { computeCreature } from '/imports/api/engine/computeCreature.js';
|
||||
import computeCreature from '/imports/api/engine/computeCreature.js';
|
||||
|
||||
const organizeDoc = new ValidatedMethod({
|
||||
name: 'organize.organizeDoc',
|
||||
|
||||
@@ -3,7 +3,7 @@ import Creatures from '/imports/api/creature/creatures/Creatures.js';
|
||||
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
|
||||
import CreatureLogs from '/imports/api/creature/log/CreatureLogs.js';
|
||||
import { assertViewPermission } from '/imports/api/creature/creatures/creaturePermissions.js';
|
||||
import { computeCreature } from '/imports/api/engine/computeCreature.js';
|
||||
import computeCreature from '/imports/api/engine/computeCreature.js';
|
||||
import VERSION from '/imports/constants/VERSION.js';
|
||||
|
||||
let schema = new SimpleSchema({
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
<template lang="html">
|
||||
<markdown-text
|
||||
:markdown="computedValue"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script lang="js">
|
||||
import MarkdownText from '/imports/ui/components/MarkdownText.vue';
|
||||
//import embedInlineCalculations from '/imports/api/creature/computation/afterComputation/embedInlineCalculations.js';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
MarkdownText,
|
||||
},
|
||||
props: {
|
||||
string: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
calculations: {
|
||||
type: Array,
|
||||
default(){
|
||||
return [];
|
||||
},
|
||||
},
|
||||
inactive: Boolean,
|
||||
},
|
||||
computed: {
|
||||
computedValue(){
|
||||
if (this.inactive) return this.string;
|
||||
//return embedInlineCalculations(this.string, this.calculations);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="css">
|
||||
.computed {
|
||||
display: inline-block;
|
||||
}
|
||||
.computed.symbols-are-errors .math-symbol {
|
||||
color: red;
|
||||
}
|
||||
.computed.code {
|
||||
font-family: monospace,monospace;
|
||||
}
|
||||
.computed .math-binary-operator {
|
||||
margin: 0 6px;
|
||||
}
|
||||
</style>
|
||||
@@ -187,7 +187,7 @@ import LibraryNodes from '/imports/api/library/LibraryNodes.js';
|
||||
import DialogBase from '/imports/ui/dialogStack/DialogBase.vue';
|
||||
import TreeNodeView from '/imports/ui/properties/treeNodeViews/TreeNodeView.vue';
|
||||
import PropertyDescription from '/imports/ui/properties/viewers/shared/PropertyDescription.vue'
|
||||
import evaluateString from '/imports/api/creature/computation/afterComputation/evaluateString.js';
|
||||
// import evaluateString from '/imports/api/creature/computation/afterComputation/evaluateString.js';
|
||||
import getSlotFillFilter from '/imports/api/creature/creatureProperties/methods/getSlotFillFilter.js'
|
||||
import Libraries from '/imports/api/library/Libraries.js';
|
||||
import LibraryNodeExpansionContent from '/imports/ui/library/LibraryNodeExpansionContent.vue';
|
||||
|
||||
@@ -11,10 +11,8 @@
|
||||
<v-spacer />
|
||||
</template>
|
||||
<v-card-text v-if="model.summary">
|
||||
<computed
|
||||
:string="model.summary"
|
||||
:calculations="model.summaryCalculations"
|
||||
:inactive="model.inactive"
|
||||
<PropertyDescription
|
||||
:model="model.summary"
|
||||
/>
|
||||
</v-card-text>
|
||||
</toolbar-card>
|
||||
@@ -22,12 +20,12 @@
|
||||
|
||||
<script lang="js">
|
||||
import ToolbarCard from '/imports/ui/components/ToolbarCard.vue';
|
||||
import EmbedInlineComputations from '/imports/ui/components/computation/EmbedInlineComputations.vue';
|
||||
import PropertyDescription from '/imports/ui/properties/viewers/shared/PropertyDescription.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ToolbarCard,
|
||||
Computed: EmbedInlineComputations,
|
||||
PropertyDescription,
|
||||
},
|
||||
props: {
|
||||
model: {
|
||||
|
||||
@@ -1,32 +1,37 @@
|
||||
<template lang="html">
|
||||
<computed
|
||||
v-if="string"
|
||||
class="property-description"
|
||||
:string="string"
|
||||
:calculations="calculations"
|
||||
:inactive="inactive"
|
||||
<markdown-text
|
||||
v-if="model"
|
||||
:markdown="model.value"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script lang="js">
|
||||
import EmbedInlineComputations from '/imports/ui/components/computation/EmbedInlineComputations.vue';
|
||||
import MarkdownText from '/imports/ui/components/MarkdownText.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Computed: EmbedInlineComputations,
|
||||
MarkdownText,
|
||||
},
|
||||
props: {
|
||||
string: {
|
||||
type: String,
|
||||
default: '',
|
||||
model: {
|
||||
type: Object,
|
||||
default: undefined,
|
||||
},
|
||||
calculations: {
|
||||
type: Array,
|
||||
default(){
|
||||
return [];
|
||||
},
|
||||
},
|
||||
inactive: Boolean,
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="css">
|
||||
.computed {
|
||||
display: inline-block;
|
||||
}
|
||||
.computed.symbols-are-errors .math-symbol {
|
||||
color: red;
|
||||
}
|
||||
.computed.code {
|
||||
font-family: monospace,monospace;
|
||||
}
|
||||
.computed .math-binary-operator {
|
||||
margin: 0 6px;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user