diff --git a/src/core/AnimatedCallFunc.js b/src/core/AnimatedCallFunc.js index 176197dc0de..44f2d65b49b 100644 --- a/src/core/AnimatedCallFunc.js +++ b/src/core/AnimatedCallFunc.js @@ -1,9 +1,10 @@ -import AnimatedNode from './AnimatedNode'; +import AnimatedNode, { getCallID, setCallID } from './AnimatedNode'; import { adapt } from './AnimatedBlock'; import { val } from '../val'; import invariant from 'fbjs/lib/invariant'; class AnimatedCallFunc extends AnimatedNode { + _previousCallID; _what; _args; _params; @@ -39,8 +40,11 @@ class AnimatedCallFunc extends AnimatedNode { } beginContext() { + this._previousCallID = getCallID(); + setCallID(getCallID() + '/' + this.__nodeID); + this._params.forEach((param, index) => { - param.beginContext(this._args[index]); + param.beginContext(this._args[index], this._previousCallID); }); } @@ -48,6 +52,7 @@ class AnimatedCallFunc extends AnimatedNode { this._params.forEach((param, index) => { param.endContext(); }); + setCallID(this._previousCallID); } __onEvaluate() { diff --git a/src/core/AnimatedNode.js b/src/core/AnimatedNode.js index 34165ac8b20..2d9e041ed89 100644 --- a/src/core/AnimatedNode.js +++ b/src/core/AnimatedNode.js @@ -5,6 +5,16 @@ const UPDATED_NODES = []; let loopID = 1; let propUpdatesEnqueued = null; +let nodeCount = 0; +let callID = ""; + +export function getCallID() { + return callID; +} + +export function setCallID(nextCallID) { + callID = nextCallID; +} function sanitizeConfig(config) { if (Platform.OS === 'web') { @@ -52,9 +62,13 @@ function runPropUpdates() { loopID += 1; } -let nodeCount = 0; - export default class AnimatedNode { + + __nodeID; + __lastLoopID = { "": -1 }; + __memoizedValue = { "": null }; + __children = []; + constructor(nodeConfig, inputNodes) { this.__nodeID = ++nodeCount; this.__nodeConfig = sanitizeConfig(nodeConfig); @@ -91,26 +105,23 @@ export default class AnimatedNode { this.__nativeTearDown(); } - __lastLoopID = 0; - __memoizedValue = null; - - __children = []; - __getValue() { - if (this.__lastLoopID < loopID) { - this.__lastLoopID = loopID; - return (this.__memoizedValue = this.__onEvaluate()); + if (!(callID in this.__lastLoopID) || this.__lastLoopID[callID] < loopID) { + this.__lastLoopID[callID] = loopID; + const result = this.__onEvaluate(); + this.__memoizedValue[callID] = result; + return result; } - return this.__memoizedValue; + return this.__memoizedValue[callID]; } __forceUpdateCache(newValue) { - this.__memoizedValue = newValue; + this.__memoizedValue[callID] = newValue; this.__markUpdated(); } __dangerouslyRescheduleEvaluate() { - this.__lastLoopID = 0; + this.__lastLoopID[callID] = -1; this.__markUpdated(); } diff --git a/src/core/AnimatedParam.js b/src/core/AnimatedParam.js index c1dd9ffea24..c5a898b2045 100644 --- a/src/core/AnimatedParam.js +++ b/src/core/AnimatedParam.js @@ -1,17 +1,19 @@ import invariant from 'fbjs/lib/invariant'; -import AnimatedNode from './AnimatedNode'; +import AnimatedNode, { getCallID, setCallID } from './AnimatedNode'; import AnimatedClock from './AnimatedClock'; import { val } from '../val'; export class AnimatedParam extends AnimatedNode { argsStack = []; - + _prevCallID; + constructor() { super({ type: 'param' }, []); this.__attach(); } - beginContext(ref) { + beginContext(ref, prevCallID) { + this._prevCallID = prevCallID; this.argsStack.push(ref); } @@ -28,15 +30,22 @@ export class AnimatedParam extends AnimatedNode { setValue(value) { const top = this._getTopNode(); if (top.setValue) { + const callID = getCallID(); + setCallID(this._prevCallID); top.setValue(value); + setCallID(callID); } else { throw new Error(`param: setValue(${value}) failed because the top element has no known method for updating it's current value.`) } } __onEvaluate() { + const callID = getCallID(); + setCallID(this._prevCallID); const top = this._getTopNode(); - return val(top); + const value = val(top); + setCallID(callID); + return value; } start() { @@ -59,11 +68,15 @@ export class AnimatedParam extends AnimatedNode { isRunning() { const node = this._getTopNode(); + + if (node instanceof AnimatedParam) { + return node.isRunning() + } invariant( - node instanceof AnimatedClock || node instanceof AnimatedParam, + node instanceof AnimatedClock, `param: top node should be of type AnimatedClock but got ${node}` ); - return node.isRunning() + return node.isStarted(); } } diff --git a/src/core/AnimatedValue.js b/src/core/AnimatedValue.js index e4da2bd3c26..877e92433c3 100644 --- a/src/core/AnimatedValue.js +++ b/src/core/AnimatedValue.js @@ -23,7 +23,7 @@ export default class AnimatedValue extends InternalAnimatedValue { } toString() { - return `AnimatedValue, id: ${super.__nodeID}`; + return `AnimatedValue, id: ${this.__nodeID}`; } interpolate(config) {