Skip to content

Commit

Permalink
fix initialization routines
Browse files Browse the repository at this point in the history
in initialization, we need to update all of the leaf inputs. sometimes,
there are leaf inputs with overlapping outputs. previously, we would
trigger an update for each input, which would then trigger an update
for each of its outputs. now, we skip triggering updates to outputs if
they have already been covered by a separate input.
  • Loading branch information
chriddyp committed Feb 1, 2018
1 parent f140955 commit 1c191a1
Showing 1 changed file with 46 additions and 14 deletions.
60 changes: 46 additions & 14 deletions src/actions/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import {
contains,
findIndex,
findLastIndex,
flatten,
flip,
has,
intersection,
isEmpty,
Expand All @@ -16,6 +18,7 @@ import {
merge,
pluck,
propEq,
reject,
slice,
sort,
type,
Expand Down Expand Up @@ -65,8 +68,8 @@ function triggerDefaultState(dispatch, getState) {
}
});

reduceInputIds(inputNodeIds, InputGraph).forEach(nodeId => {
const [componentId, componentProp] = nodeId.split('.');
reduceInputIds(inputNodeIds, InputGraph).forEach(inputOutput => {
const [componentId, componentProp] = inputOutput.input.split('.');
// Get the initial property
const propLens = lensPath(
concat(getState().paths[componentId],
Expand All @@ -79,8 +82,10 @@ function triggerDefaultState(dispatch, getState) {

dispatch(notifyObservers({
id: componentId,
props: {[componentProp]: propValue}
props: {[componentProp]: propValue},
excludedOutputs: inputOutput.excludedOutputs
}));

});

}
Expand Down Expand Up @@ -136,20 +141,38 @@ function reduceInputIds(nodeIds, InputGraph) {
*/
const inputOutputPairs = nodeIds.map(nodeId => ({
input: nodeId,
outputs: InputGraph.dependenciesOf(nodeId)
// TODO - Does this include grandchildren?
outputs: InputGraph.dependenciesOf(nodeId),
excludedOutputs: []
}));

const sortedInputOutputPairs = sort(
(a, b) => b.outputs.length - a.outputs.length,
inputOutputPairs
);

const uniquePairs = sortedInputOutputPairs.filter((pair, i) => !contains(
pair.outputs,
pluck('outputs', slice(i + 1, Infinity, sortedInputOutputPairs))
));
/*
* In some cases, we may have unique outputs but inputs that could
* trigger components to update multiple times.
*
* For example, [A, B] => C and [A, D] => E
* The unique inputs might be [A, B, D] but that is redudant.
* We only need to update B and D or just A.
*
* In these cases, we'll supply an additional list of outputs
* to exclude.
*/
sortedInputOutputPairs.forEach((pair, i) => {
const outputsThatWillBeUpdated = flatten(pluck(
'outputs', slice(0, i, sortedInputOutputPairs)));
pair.outputs.forEach(output => {
if (contains(output, outputsThatWillBeUpdated)) {
pair.excludedOutputs.push(output);
}
});
});

return pluck('input', uniquePairs);
return sortedInputOutputPairs;
}


Expand All @@ -159,15 +182,15 @@ export function notifyObservers(payload) {
const {
id,
event,
props
props,
excludedOutputs
} = payload

const {
graphs,
requestQueue,
} = getState();
const {EventGraph, InputGraph} = graphs;

/*
* Figure out all of the output id's that depend on this
* event or input.
Expand All @@ -192,6 +215,13 @@ export function notifyObservers(payload) {
});
}

if (excludedOutputs) {
outputObservers = reject(
flip(contains)(excludedOutputs),
outputObservers
);
}

if (isEmpty(outputObservers)) {
return;
}
Expand Down Expand Up @@ -630,11 +660,13 @@ function updateOutput(
keys(newProps), InputGraph);
const depOrder = InputGraph.overallOrder();
const sortedNewProps = sort((a, b) =>
depOrder.indexOf(a) - depOrder.indexOf(b),
depOrder.indexOf(a.input) - depOrder.indexOf(b.input),
reducedNodeIds
);
sortedNewProps.forEach(function(nodeId) {
dispatch(notifyObservers(newProps[nodeId]));
sortedNewProps.forEach(function(inputOutput) {
const payload = newProps[inputOutput.input];
payload.excludedOutputs = inputOutput.excludedOutputs;
dispatch(notifyObservers(payload));
});

// Dispatch updates to lone outputs
Expand Down

0 comments on commit 1c191a1

Please sign in to comment.