Skip to content

Commit

Permalink
Finished initial tree traversal optimisation (#7).
Browse files Browse the repository at this point in the history
  • Loading branch information
hexus committed Feb 10, 2019
1 parent 55231ba commit 9506e79
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 94 deletions.
8 changes: 4 additions & 4 deletions build/index.js

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions build/old.js

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions build/pragma.js

Large diffs are not rendered by default.

29 changes: 15 additions & 14 deletions src/data/fields.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,9 @@ const fields = [
}
},
{
path: 'templates.class.levels',
type: 'number',
name: 'Levels',
path: 'templates.class.levels',
type: 'number',
name: 'Levels',
options: {
min: 1
},
Expand All @@ -133,7 +133,7 @@ const fields = [
description: "The character's classes"
},
{
path: 'classes.level',
path: 'classes.level',
expression: 'sumBy($parent.list, "levels")'
},
{
Expand All @@ -143,11 +143,11 @@ const fields = [
editable: true // TODO: Rename to mutable.. or something else more appropriate
},
template: 'templates.class',
fixed: {
fixed: {
0: true // Always keep the first class
}
},

// Abilities
{
path: 'templates.ability',
Expand All @@ -167,7 +167,8 @@ const fields = [
expression: 'abilityModifier($parent.score)'
},
{
path: 'templates.ability.base'
path: 'templates.ability.base',
default: 10
},
{
path: 'templates.ability.racialBonus'
Expand All @@ -186,12 +187,12 @@ const fields = [
virtual: true
},
{
path: 'abilities',
parent: 'sections.abilities',
type: 'table',
path: 'abilities',
parent: 'sections.abilities',
type: 'table',
template: 'templates.ability',
fixed: ['str', 'dex', 'con', 'int', 'wis', 'cha'],
options: {
fixed: ['str', 'dex', 'con', 'int', 'wis', 'cha'],
options: {
showLabel: true,
headings: [
'Ability',
Expand Down Expand Up @@ -565,7 +566,7 @@ const fields = [
'cha': 'Charisma'
}
},
default: 'str',
default: 'str',
disabled: true
},
{
Expand Down Expand Up @@ -626,7 +627,7 @@ const fields = [
},
template: 'templates.skill',
merge: true,
fixed: [
fixed: [
'acrobatics', 'appraise', 'bluff', 'climb', 'craft', 'diplomacy',
'disableDevice', 'disguise', 'escapeArtist', 'fly', 'handleAnimal',
'heal', 'intimidate', 'knowledgeArcana', 'knowledgeDungeoneering',
Expand Down
108 changes: 52 additions & 56 deletions src/services/FormProcessor.js
Original file line number Diff line number Diff line change
Expand Up @@ -945,56 +945,41 @@ export default class FormProcessor

this.clearValueCache(path);

//console.time('diffFormData');
//let diff = this.diffFormData(data);
//console.timeEnd('diffFormData');

// Update the field and its children
//console.time('updatePath() ' + path);
traverseTree(
field,
(field) => {
// Pre-order operation
this.updateFieldInheritance(field, data);

// Skip omitted fields and their children
return !field.omit;
return this.preUpdateField(field, data);
},
(field) => {
// Post-order operation
// Update the current field and its dependencies
//console.log('updatePath() post', field.path);

// Skip fields that have already been visited
if (visited[field.path]) {
//console.warn('skipped visited field', field.path);
return;
}

// if (field.path &&
// (
// !has(diff.added, field.path) &&
// !has(diff.updated, field.path) &&
// !has(diff.deleted, field.path)
// )
// ) {
// return;
// }

this.applyDefaults([field]);

this.updateDataValue(field, data);

this.updateFieldValue(field, data);

this.updateFieldDependencies(field, data, visited);
this.updateField(field, data);

visited[field.path] = true;
}
);
//console.timeEnd('updatePath() ' + path);

// TODO: Update parent fields and their dependencies
// Update parent fields and their dependencies
let i;
let ancestors = this.getFieldAncestors(field);

for (i = 0; i < ancestors.length; i++) {
if (visited[ancestors[i].path]) {
//console.log('skipped visited ancestor', field.path, ancestors[i].path, visited);
continue;
}

this.updateField(ancestors[i], data, visited);

visited[ancestors[i].path] = true;
}
//console.timeEnd('updatePath() ' + path);
}

/**
Expand All @@ -1018,31 +1003,35 @@ export default class FormProcessor
}
}

/**
* Pre-order update the given field with the given data.
*
* @protected
* @param {Field} field - The field to update.
* @param {Object} data - The data to update with.
* @returns {boolean}
*/
preUpdateField(field, data)
{
this.updateFieldInheritance(field, data);

return !field.omit;
}

/**
* Update the given field with the given data.
*
* Recursively descends into child fields and updates dependent fields,
* including parents.
*
* @protected
* @param {Field} field - The fields to update.
* @param {Object} data - The data to update with.
* @param {number} [direction=BOTH] - Update direction (UP: -1, BOTH: 0, DOWN: 1)
* @param {Field} field - The field to update.
* @param {Object} data - The data to update with.
* @param {Object} [visited={}] - Map of fields already visited.
*/
updateField(field, data, direction = BOTH)
updateField(field, data, visited = {})
{
if (!field) {
return;
}

this.clearValueCache(field.path);

// Update the field's children
this.updateFieldInheritance(field, data);

if (!field.omit) {
//this.updateFields(field.children, data);
}
//console.log('updateField()', field.path);

// Apply default values
this.applyDefaults([field]);
Expand All @@ -1052,6 +1041,9 @@ export default class FormProcessor

// Update the field's value (and update all fields dependent on this one)
this.updateFieldValue(field, data);

// Update the fields that are dependent upon the value of this field
this.updateFieldDependencies(field, data, visited);
}

/**
Expand All @@ -1077,15 +1069,17 @@ export default class FormProcessor
* Update a field using the given data.
*
* @protected
* @param {Field} field - The field to update.
* @param {Object} data - The data to update with.
* @param {Field} field - The field to update.
* @param {Object} data - The data to update with.
*/
updateFieldValue(field, data)
{
if (!field) {
return;
}

//console.log('updateFieldValue()', field.path);

// Update the field value
field.value = get(data, field.path);
}
Expand All @@ -1100,9 +1094,6 @@ export default class FormProcessor
*/
updateFieldDependencies(field, data, visited = {})
{
// Update parent field values
this.updateFieldAncestorValues(field, data);

// Update the field's expression dependencies
let dependencies = this.getFieldExpressionDependencies(field);

Expand Down Expand Up @@ -1471,7 +1462,7 @@ export default class FormProcessor
*
* TODO: The naming and existence of this method doesn't quite make sense.
* You'd expect it to remove the field(s) too, considering updatePath().
* Refactor!
* Refactor?
*
* @protected
* @param {string} path - The path to remove.
Expand All @@ -1497,16 +1488,21 @@ export default class FormProcessor
*
* @protected
* @param {Field[]} fields - The fields to remove.
* @return {Field[]} The removed fields.
*/
removeFields(fields)
{
if (!Array.isArray(fields) || !fields.length) {
return;
return [];
}

let removed = [];

for (let i = 0; i < fields.length; i++) {
this.removeField(fields[i]);
removed.push(this.removeField(fields[i]));
}

return removed;
}

/**
Expand Down
4 changes: 0 additions & 4 deletions src/tags/character-sheet.tag
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,6 @@
this.on('mount', this.sync);
this.on('update', this.sync);

this.root.sync = () => {
this.sync();
};

this.root.update = () => {
this.update();
};
Expand Down
34 changes: 23 additions & 11 deletions src/tags/pragma.tag
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@
// Define properties
this.form = new FormProcessor([]);
this.state = null;
this.fields = null;

if (window && this.opts.debug) {
window.pragma = this.form;
}

// Define event handlers
this.add = function (event) {
Expand All @@ -39,7 +44,9 @@
this.edit = function (event) {
let { name, value } = event.detail;

this.form.setValue(this.state, name, value);
value = this.form.setValue(this.state, name, value);

event.detail.value = value;
};

this.remove = function (event) {
Expand All @@ -52,16 +59,24 @@
let fields = this.opts.fields || this.root.fields || {};
let functions = this.opts.functions || this.root.functions || {};
let defaults = this.opts.defaults || this.root.defaults || {};
this.state = this.opts.state || this.root.state || {};
let state = this.opts.state || this.root.state || {};

this.form.setDefaults(defaults);
this.form.addFunctions(functions);
console.time('setFields');
this.form.setFields(fields);
console.timeEnd('setFields');
console.time('update');
this.form.update(this.state);
console.timeEnd('update');

if (fields !== this.fields) {
console.time('setFields');
this.fields = fields;
this.form.setFields(fields);
console.timeEnd('setFields');
}

if (state !== this.state) {
console.time('update');
this.state = state;
this.form.update(this.state);
console.timeEnd('update');
}
};

this.root.sync = () => {
Expand All @@ -72,10 +87,7 @@
this.update();
};

//this.sync();
this.on('mount', this.sync);
this.on('update', this.sync);

window.pragma = this.form;
</script>
</pragma>

0 comments on commit 9506e79

Please sign in to comment.