Replaced expensive getActiveProperties with cheaper filter by inactive field
This commit is contained in:
@@ -3,7 +3,7 @@ import { RateLimiterMixin } from 'ddp-rate-limiter-mixin';
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import { assertEditPermission } from '/imports/api/creature/creaturePermissions.js';
|
||||
import Creatures from '/imports/api/creature/Creatures.js';
|
||||
import getActiveProperties from '/imports/api/creature/getActiveProperties.js';
|
||||
import CreatureProperties from '/imports/api/creature/CreatureProperties.js';
|
||||
|
||||
export const recomputeDamageMultipliers = new ValidatedMethod({
|
||||
|
||||
@@ -31,9 +31,13 @@ export const recomputeDamageMultipliers = new ValidatedMethod({
|
||||
|
||||
export function recomputeDamageMultipliersById(creatureId){
|
||||
if (!creatureId) throw 'Creature ID is required';
|
||||
let props = getActiveProperties({
|
||||
ancestorId: creatureId,
|
||||
filter: {type: 'damageMultiplier'},
|
||||
let props = CreatureProperties.find({
|
||||
'ancestors.id': creatureId,
|
||||
type: 'damageMultiplier',
|
||||
removed: {$ne: true},
|
||||
inactive: {$ne: true},
|
||||
}, {
|
||||
sort: {order: 1}
|
||||
});
|
||||
|
||||
// Count of how many weakness, resistances and immunities each damage type has
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
import Creatures from '/imports/api/creature/Creatures.js';
|
||||
import CreatureProperties from '/imports/api/creature/CreatureProperties.js';
|
||||
|
||||
export default function getActiveProperties({
|
||||
ancestorId,
|
||||
filter = {},
|
||||
options = {sort: {order: 1}},
|
||||
includeUntoggled = false,
|
||||
includeUnprepared = false,
|
||||
includeUnequipped = false,
|
||||
excludeAncestors,
|
||||
}){
|
||||
filter = getActivePropertyFilter({
|
||||
ancestorId,
|
||||
filter,
|
||||
includeUntoggled,
|
||||
includeUnprepared,
|
||||
includeUnequipped,
|
||||
excludeAncestors,
|
||||
});
|
||||
return CreatureProperties.find(filter, options).fetch();
|
||||
}
|
||||
|
||||
export function getActivePropertyFilter({
|
||||
ancestorId,
|
||||
filter = {},
|
||||
includeUntoggled = false,
|
||||
includeUnprepared = false,
|
||||
includeUnequipped = false,
|
||||
excludeAncestors = [],
|
||||
}){
|
||||
if (!ancestorId){
|
||||
throw 'Ancestor Id is required to get active properties'
|
||||
}
|
||||
// First get ids of disabled properties, unequiped items, unapplied buffs
|
||||
let disabledAncestorsFilter = {
|
||||
'ancestors.id': ancestorId,
|
||||
$or: [
|
||||
{disabled: true}, // Everything can be disabled
|
||||
{applied: false}, // Buffs can be applied
|
||||
],
|
||||
};
|
||||
if (!includeUnequipped){
|
||||
disabledAncestorsFilter.$or.push({type: 'item', equipped: {$ne: true}});
|
||||
}
|
||||
if (!includeUntoggled){
|
||||
disabledAncestorsFilter.$or.push({toggleResult: false});
|
||||
}
|
||||
if (!includeUnprepared){
|
||||
disabledAncestorsFilter.$or.push({
|
||||
type: 'spell',
|
||||
prepared: {$ne: true},
|
||||
alwaysPrepared: {$ne: true}
|
||||
});
|
||||
}
|
||||
let disabledAncestorIds = CreatureProperties.find(disabledAncestorsFilter, {
|
||||
fields: {_id: 1},
|
||||
}).map(prop => prop._id);
|
||||
|
||||
// Then get the ids of creatures that are children of this creature
|
||||
// to isolate their decendent properties
|
||||
Creatures.find({
|
||||
'ancestors.id': ancestorId,
|
||||
}, {
|
||||
fields: {_id: 1},
|
||||
}).forEach(subCreature => {
|
||||
disabledAncestorIds.push(subCreature._id);
|
||||
});
|
||||
|
||||
// Get all the properties that are decendents of the ancestor of interest but
|
||||
// aren't from the excluded decendents
|
||||
if (filter['ancestors.id'] && Meteor.isClient){
|
||||
console.warn('Filtering on ancestor id is ignored')
|
||||
}
|
||||
filter['ancestors.id'] = {
|
||||
$eq: ancestorId,
|
||||
$nin: disabledAncestorIds.concat(excludeAncestors),
|
||||
};
|
||||
// Get properties that aren't removed
|
||||
filter.removed = {$ne: true};
|
||||
// Don't include the disabled ancestors themselves either
|
||||
filter._id = {
|
||||
$nin: disabledAncestorIds,
|
||||
}
|
||||
return filter;
|
||||
}
|
||||
@@ -3,7 +3,6 @@ import { ValidatedMethod } from 'meteor/mdg:validated-method';
|
||||
import { RateLimiterMixin } from 'ddp-rate-limiter-mixin';
|
||||
import Creatures from '/imports/api/creature/Creatures.js';
|
||||
import CreatureProperties from '/imports/api/creature/CreatureProperties.js';
|
||||
import getActiveProperties, { getActivePropertyFilter } from '/imports/api/creature/getActiveProperties.js';
|
||||
import { assertEditPermission } from '/imports/api/creature/creaturePermissions.js';
|
||||
import { recomputeCreatureById } from '/imports/api/creature/computation/recomputeCreature.js';
|
||||
|
||||
@@ -43,11 +42,12 @@ const restCreature = new ValidatedMethod({
|
||||
resetFilter = {$in: ['shortRest', 'longRest']}
|
||||
}
|
||||
// Only apply to active properties
|
||||
let filter = getActivePropertyFilter({
|
||||
filter: {reset: resetFilter},
|
||||
ancestorId: creatureId,
|
||||
includeUntoggled: true,
|
||||
});
|
||||
let filter = {
|
||||
'ancestors.id': creatureId,
|
||||
reset: resetFilter,
|
||||
removed: {$ne: true},
|
||||
inactive: {$ne: true},
|
||||
};
|
||||
// update all attribute's damage
|
||||
filter.type = 'attribute';
|
||||
CreatureProperties.update(filter, {
|
||||
@@ -70,14 +70,18 @@ const restCreature = new ValidatedMethod({
|
||||
});
|
||||
// Reset half hit dice on a long rest, starting with the highest dice
|
||||
if (restType === 'longRest'){
|
||||
let hitDice = getActiveProperties({
|
||||
ancestorId: creatureId,
|
||||
filter: {type: 'attribute', attributeType: 'hitDice'},
|
||||
options: {fields: {
|
||||
let hitDice = CreatureProperties.find({
|
||||
'ancestors.id': creatureId,
|
||||
type: 'attribute',
|
||||
attributeType: 'hitDice',
|
||||
removed: {$ne: true},
|
||||
inactive: {$ne: true},
|
||||
}, {
|
||||
fields: {
|
||||
hitDiceSize: 1,
|
||||
damage: 1,
|
||||
value: 1,
|
||||
}},
|
||||
}
|
||||
});
|
||||
// Use a collator to do sorting in natural order
|
||||
let collator = new Intl.Collator('en', {
|
||||
|
||||
@@ -55,7 +55,7 @@ export default {
|
||||
},
|
||||
meteor: {
|
||||
name(){
|
||||
let creature = Creatures.findOne(this.id);
|
||||
let creature = Creatures.findOne(this.id, {fields: {name: 1}});
|
||||
return creature && creature.name;
|
||||
},
|
||||
},
|
||||
|
||||
@@ -114,7 +114,6 @@ import Creatures from '/imports/api/creature/Creatures.js';
|
||||
import CreatureProperties from '/imports/api/creature/CreatureProperties.js';
|
||||
import ColumnLayout from '/imports/ui/components/ColumnLayout.vue';
|
||||
import NoteCard from '/imports/ui/properties/components/persona/NoteCard.vue';
|
||||
import getActiveProperties from '/imports/api/creature/getActiveProperties.js';
|
||||
import Slots from '/imports/ui/creature/slots/Slots.vue';
|
||||
import ToolbarCard from '/imports/ui/components/ToolbarCard.vue';
|
||||
|
||||
@@ -171,9 +170,13 @@ export default {
|
||||
return Creatures.findOne(this.creatureId);
|
||||
},
|
||||
classLevels(){
|
||||
return getActiveProperties({
|
||||
ancestorId: this.creatureId,
|
||||
filter: {type: 'classLevel'},
|
||||
return CreatureProperties.find({
|
||||
'ancestors.id': this.creatureId,
|
||||
type: 'classLevel',
|
||||
removed: {$ne: true},
|
||||
inactive: {$ne: true},
|
||||
}, {
|
||||
sort: {order: 1}
|
||||
});
|
||||
},
|
||||
},
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import getActiveProperties from '/imports/api/creature/getActiveProperties.js';
|
||||
import CreatureProperties from '/imports/api/creature/CreatureProperties.js';
|
||||
import ColumnLayout from '/imports/ui/components/ColumnLayout.vue';
|
||||
import FeatureCard from '/imports/ui/properties/components/features/FeatureCard.vue';
|
||||
|
||||
@@ -33,11 +33,13 @@ import getActiveProperties from '/imports/api/creature/getActiveProperties.js';
|
||||
},
|
||||
meteor: {
|
||||
features(){
|
||||
return getActiveProperties({
|
||||
ancestorId: this.creatureId,
|
||||
filter: {
|
||||
type: 'feature',
|
||||
},
|
||||
return CreatureProperties.find({
|
||||
'ancestors.id': this.creatureId,
|
||||
type: 'feature',
|
||||
removed: {$ne: true},
|
||||
inactive: {$ne: true},
|
||||
}, {
|
||||
sort: {order: 1}
|
||||
});
|
||||
},
|
||||
},
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
<script>
|
||||
import ColumnLayout from '/imports/ui/components/ColumnLayout.vue';
|
||||
import getActiveProperties from '/imports/api/creature/getActiveProperties.js';
|
||||
import CreatureProperties from '/imports/api/creature/CreatureProperties.js';
|
||||
import SpellListCard from '/imports/ui/properties/components/spells/SpellListCard.vue';
|
||||
import SpellList from '/imports/ui/properties/components/spells/SpellList.vue';
|
||||
|
||||
@@ -48,35 +48,42 @@ export default {
|
||||
}},
|
||||
meteor: {
|
||||
spellLists(){
|
||||
return getActiveProperties({
|
||||
ancestorId: this.creatureId,
|
||||
filter: {
|
||||
type: 'spellList',
|
||||
},
|
||||
return CreatureProperties.find({
|
||||
'ancestors.id': this.creatureId,
|
||||
type: 'spellList',
|
||||
removed: {$ne: true},
|
||||
inactive: {$ne: true},
|
||||
}, {
|
||||
sort: {order: 1}
|
||||
});
|
||||
},
|
||||
spellsWithoutList(){
|
||||
return getActiveProperties({
|
||||
ancestorId: this.creatureId,
|
||||
excludeAncestors: this.spellListIds,
|
||||
filter: {
|
||||
type: 'spell',
|
||||
},
|
||||
options: {
|
||||
sort: {
|
||||
level: 1,
|
||||
order: 1,
|
||||
},
|
||||
return CreatureProperties.find({
|
||||
'ancestors.id': {
|
||||
$eq: this.creatureId,
|
||||
$nin: this.spellListIds,
|
||||
},
|
||||
type: 'spell',
|
||||
removed: {$ne: true},
|
||||
inactive: {$ne: true},
|
||||
}, {
|
||||
sort: {
|
||||
level: 1,
|
||||
order: 1,
|
||||
}
|
||||
});
|
||||
},
|
||||
spellListsWithoutAncestorSpellLists(){
|
||||
return getActiveProperties({
|
||||
ancestorId: this.creatureId,
|
||||
excludeAncestors: this.spellListIds,
|
||||
filter: {
|
||||
type: 'spellList',
|
||||
return CreatureProperties.find({
|
||||
'ancestors.id': {
|
||||
$eq: this.creatureId,
|
||||
$nin: this.spellListIds,
|
||||
},
|
||||
type: 'spellList',
|
||||
removed: {$ne: true},
|
||||
inactive: {$ne: true},
|
||||
}, {
|
||||
sort: {order: 1}
|
||||
});
|
||||
},
|
||||
},
|
||||
|
||||
@@ -322,7 +322,7 @@
|
||||
import SpellSlotListTile from '/imports/ui/properties/components/attributes/SpellSlotListTile.vue';
|
||||
import ActionCard from '/imports/ui/properties/components/actions/ActionCard.vue';
|
||||
import RestButton from '/imports/ui/creature/RestButton.vue';
|
||||
import getActiveProperties from '/imports/api/creature/getActiveProperties.js';
|
||||
import CreatureProperties from '/imports/api/creature/CreatureProperties.js';
|
||||
import castSpellWithSlot from '/imports/api/creature/actions/castSpellWithSlot.js';
|
||||
|
||||
const getProperties = function(creature, filter,){
|
||||
@@ -330,10 +330,11 @@
|
||||
if (creature.settings.hideUnusedStats){
|
||||
filter.hide = {$ne: true};
|
||||
}
|
||||
return getActiveProperties({
|
||||
ancestorId: creature._id,
|
||||
filter,
|
||||
options: {sort: {order: 1}},
|
||||
filter['ancestors.id'] = creature._id;
|
||||
filter.removed = {$ne: true};
|
||||
filter.inactive = {$ne: true};
|
||||
return CreatureProperties.find(filter, {
|
||||
sort: {order: 1}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -422,9 +423,12 @@
|
||||
},
|
||||
attacks(){
|
||||
let props = getProperties(this.creature, {type: 'attack'}).map(attack => {
|
||||
attack.children = getActiveProperties({
|
||||
ancestorId: attack._id,
|
||||
options: {sort: {order: 1}},
|
||||
attack.children = CreatureProperties.find({
|
||||
'ancestors.id': attack._id,
|
||||
removed: {$ne: true},
|
||||
inactive: {$ne: true},
|
||||
}, {
|
||||
sort: {order: 1}
|
||||
});
|
||||
return attack;
|
||||
});
|
||||
|
||||
@@ -59,7 +59,6 @@ import {
|
||||
softRemoveProperty,
|
||||
restoreProperty
|
||||
} from '/imports/api/creature/CreatureProperties.js';
|
||||
import getActiveProperties from '/imports/api/creature/getActiveProperties.js';
|
||||
import getPropertyTitle from '/imports/ui/properties/shared/getPropertyTitle.js';
|
||||
|
||||
export default {
|
||||
@@ -122,15 +121,17 @@ export default {
|
||||
},
|
||||
meteor: {
|
||||
slots(){
|
||||
return getActiveProperties({
|
||||
ancestorId: this.creatureId,
|
||||
filter: {
|
||||
type: 'propertySlot',
|
||||
$or: [
|
||||
{slotConditionResult: true},
|
||||
{slotConditionResult: {$exists: false}},
|
||||
],
|
||||
}
|
||||
return CreatureProperties.find({
|
||||
'ancestors.id': this.creatureId,
|
||||
type: 'propertySlot',
|
||||
$or: [
|
||||
{slotConditionResult: true},
|
||||
{slotConditionResult: {$exists: false}},
|
||||
],
|
||||
removed: {$ne: true},
|
||||
inactive: {$ne: true},
|
||||
}, {
|
||||
sort: {order: 1}
|
||||
}).map(slot => {
|
||||
if (
|
||||
!this.showHiddenSlots &&
|
||||
|
||||
@@ -90,8 +90,8 @@
|
||||
<script>
|
||||
import { getPropertyName } from '/imports/constants/PROPERTIES.js';
|
||||
import numberToSignedString from '/imports/ui/utility/numberToSignedString.js';
|
||||
import CreatureProperties from '/imports/api/creature/CreatureProperties.js';
|
||||
import doAction from '/imports/api/creature/actions/doAction.js';
|
||||
import getActiveProperties from '/imports/api/creature/getActiveProperties.js';
|
||||
import TreeNodeView from '/imports/ui/properties/treeNodeViews/TreeNodeView.vue';
|
||||
import AttributeConsumedView from '/imports/ui/properties/components/actions/AttributeConsumedView.vue';
|
||||
import ItemConsumedView from '/imports/ui/properties/components/actions/ItemConsumedView.vue';
|
||||
@@ -161,10 +161,12 @@ export default {
|
||||
},
|
||||
meteor: {
|
||||
children(){
|
||||
return getActiveProperties({
|
||||
ancestorId: this.model._id,
|
||||
filter: {'parent.id': this.model._id},
|
||||
options: {sort: {order: 1}},
|
||||
return CreatureProperties.find({
|
||||
'parent.id': this.model._id,
|
||||
removed: {$ne: true},
|
||||
inactive: {$ne: true},
|
||||
}, {
|
||||
sort: {order: 1}
|
||||
});
|
||||
},
|
||||
},
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
<script>
|
||||
import ItemTreeNode from '/imports/ui/properties/treeNodeViews/ItemTreeNode.vue';
|
||||
import getActiveProperties from '/imports/api/creature/getActiveProperties.js';
|
||||
import CreatureProperties from '/imports/api/creature/CreatureProperties.js';
|
||||
import { selectAmmoItem } from '/imports/api/creature/CreatureProperties.js';
|
||||
import { findIndex } from 'lodash';
|
||||
export default {
|
||||
@@ -39,15 +39,16 @@ export default {
|
||||
},
|
||||
meteor: {
|
||||
items(){
|
||||
return getActiveProperties({
|
||||
ancestorId: this.action.ancestors[0].id,
|
||||
filter: {
|
||||
tags: this.itemConsumed.tag,
|
||||
equipped: true,
|
||||
},
|
||||
options: {
|
||||
fields: {equipped: false},
|
||||
}
|
||||
return CreatureProperties.find({
|
||||
'ancestors.id': this.action.ancestors[0].id,
|
||||
type: 'item',
|
||||
equipped: true,
|
||||
tags: this.itemConsumed.tag,
|
||||
removed: {$ne: true},
|
||||
inactive: {$ne: true},
|
||||
}, {
|
||||
sort: {order: 1},
|
||||
fields: {equipped: false},
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
import Creatures from '/imports/api/creature/Creatures.js';
|
||||
import { damageProperty } from '/imports/api/creature/CreatureProperties.js';
|
||||
import HealthBarCard from '/imports/ui/properties/components/attributes/HealthBarCard.vue';
|
||||
import getActiveProperties from '/imports/api/creature/getActiveProperties.js';
|
||||
import CreatureProperties from '/imports/api/creature/CreatureProperties.js';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
@@ -30,16 +30,17 @@
|
||||
let creature = this.creature;
|
||||
if (!creature) return;
|
||||
let filter = {
|
||||
'ancestors.id': creature._id,
|
||||
type: 'attribute',
|
||||
attributeType: 'healthBar',
|
||||
removed: {$ne: true},
|
||||
inactive: {$ne: true},
|
||||
};
|
||||
if (creature.settings.hideUnusedStats){
|
||||
filter.hide = {$ne: true};
|
||||
}
|
||||
return getActiveProperties({
|
||||
ancestorId: creature._id,
|
||||
filter,
|
||||
options: {sort: {order: 1}},
|
||||
return CreatureProperties.find(filter, {
|
||||
sort: {order: 1}
|
||||
});
|
||||
},
|
||||
},
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
<script>
|
||||
import ToolbarCard from '/imports/ui/components/ToolbarCard.vue';
|
||||
import SpellList from '/imports/ui/properties/components/spells/SpellList.vue';
|
||||
import getActiveProperties from '/imports/api/creature/getActiveProperties.js';
|
||||
import CreatureProperties from '/imports/api/creature/CreatureProperties.js';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
@@ -79,29 +79,32 @@ export default {
|
||||
}},
|
||||
meteor: {
|
||||
spells(){
|
||||
return getActiveProperties({
|
||||
ancestorId: this.model._id,
|
||||
filter: {
|
||||
type: 'spell',
|
||||
},
|
||||
options: {
|
||||
sort: {
|
||||
level: 1,
|
||||
order: 1,
|
||||
},
|
||||
},
|
||||
includeUnprepared: this.preparingSpells,
|
||||
let filter = {
|
||||
'ancestors.id': this.model._id,
|
||||
type: 'spell',
|
||||
removed: {$ne: true},
|
||||
};
|
||||
if (this.preparingSpells){
|
||||
filter.deactivatedByAncestor = {$ne: true};
|
||||
} else {
|
||||
filter.inactive = {$ne: true};
|
||||
}
|
||||
return CreatureProperties.find(filter, {
|
||||
sort: {
|
||||
level: 1,
|
||||
order: 1,
|
||||
}
|
||||
});
|
||||
},
|
||||
numPrepared(){
|
||||
return getActiveProperties({
|
||||
ancestorId: this.model._id,
|
||||
filter: {
|
||||
type: 'spell',
|
||||
prepared: true,
|
||||
alwaysPrepared: {$ne: true},
|
||||
},
|
||||
}).length;
|
||||
return CreatureProperties.find({
|
||||
'ancestors.id': this.model._id,
|
||||
type: 'spell',
|
||||
removed: {$ne: true},
|
||||
prepared: true,
|
||||
alwaysPrepared: {$ne: true},
|
||||
deactivatedByAncestor: {$ne: true},
|
||||
}).count();
|
||||
},
|
||||
preparedError(){
|
||||
if (!this.model.maxPrepared) return;
|
||||
|
||||
@@ -9,14 +9,18 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import getActiveProperties from '/imports/api/creature/getActiveProperties.js';
|
||||
import CreatureProperties from '/imports/api/creature/CreatureProperties.js';
|
||||
import ActionCard from '/imports/ui/properties/components/actions/ActionCard.vue';
|
||||
|
||||
function getProperties(ancestorId, type){
|
||||
if (!ancestorId) return [];
|
||||
return getActiveProperties({
|
||||
ancestorId,
|
||||
filter: {type},
|
||||
return CreatureProperties.find({
|
||||
'ancestors.id': ancestorId,
|
||||
type,
|
||||
removed: {$ne: true},
|
||||
inactive: {$ne: true},
|
||||
}, {
|
||||
sort: {order: 1}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user