From c6db7f73bebd135dcb2dce2eaebed64c54627727 Mon Sep 17 00:00:00 2001 From: Andrew Clark Date: Thu, 4 Aug 2016 14:27:55 -0700 Subject: [PATCH] Rename stateQueue -> updateQueue Also cleans up some types. --- src/renderers/shared/fiber/ReactFiber.js | 10 ++-- .../shared/fiber/ReactFiberBeginWork.js | 40 ++++++++-------- .../shared/fiber/ReactFiberScheduler.js | 4 +- ...StateQueue.js => ReactFiberUpdateQueue.js} | 47 +++++++++++-------- 4 files changed, 54 insertions(+), 47 deletions(-) rename src/renderers/shared/fiber/{ReactFiberStateQueue.js => ReactFiberUpdateQueue.js} (51%) diff --git a/src/renderers/shared/fiber/ReactFiber.js b/src/renderers/shared/fiber/ReactFiber.js index d6dc2bf337..495c615c95 100644 --- a/src/renderers/shared/fiber/ReactFiber.js +++ b/src/renderers/shared/fiber/ReactFiber.js @@ -15,7 +15,7 @@ import type { ReactCoroutine, ReactYield } from 'ReactCoroutine'; import type { TypeOfWork } from 'ReactTypeOfWork'; import type { PriorityLevel } from 'ReactPriorityLevel'; -import type { StateQueue } from 'ReactFiberStateQueue'; +import type { UpdateQueue } from 'ReactFiberUpdateQueue'; var ReactTypeOfWork = require('ReactTypeOfWork'); var { @@ -78,7 +78,7 @@ export type Fiber = Instance & { // TODO: I think that there is a way to merge pendingProps and memoizedProps. memoizedProps: any, // The props used to create the output. // A queue of local state updates. - stateQueue: ?StateQueue, + updateQueue: ?UpdateQueue, // The state used to create the output. This is a full state object. memoizedState: any, // Output is the return value of this fiber, or a linked list of return values @@ -156,7 +156,7 @@ var createFiber = function(tag : TypeOfWork, key : null | string) : Fiber { pendingProps: null, memoizedProps: null, - stateQueue: null, + updateQueue: null, memoizedState: null, output: null, @@ -199,7 +199,7 @@ exports.cloneFiber = function(fiber : Fiber, priorityLevel : PriorityLevel) : Fi alt.sibling = fiber.sibling; // This should always be overridden. TODO: null alt.ref = fiber.ref; alt.pendingProps = fiber.pendingProps; // TODO: Pass as argument. - alt.stateQueue = fiber.stateQueue; + alt.updateQueue = fiber.updateQueue; alt.pendingWorkPriority = priorityLevel; alt.child = fiber.child; @@ -225,7 +225,7 @@ exports.cloneFiber = function(fiber : Fiber, priorityLevel : PriorityLevel) : Fi // pendingProps is here for symmetry but is unnecessary in practice for now. // TODO: Pass in the new pendingProps as an argument maybe? alt.pendingProps = fiber.pendingProps; - alt.stateQueue = fiber.stateQueue; + alt.updateQueue = fiber.updateQueue; alt.pendingWorkPriority = priorityLevel; alt.memoizedProps = fiber.memoizedProps; diff --git a/src/renderers/shared/fiber/ReactFiberBeginWork.js b/src/renderers/shared/fiber/ReactFiberBeginWork.js index 6cda6b7df8..36ee2b9d78 100644 --- a/src/renderers/shared/fiber/ReactFiberBeginWork.js +++ b/src/renderers/shared/fiber/ReactFiberBeginWork.js @@ -18,7 +18,7 @@ import type { FiberRoot } from 'ReactFiberRoot'; import type { HostConfig } from 'ReactFiberReconciler'; import type { Scheduler } from 'ReactFiberScheduler'; import type { PriorityLevel } from 'ReactPriorityLevel'; -import type { StateQueue } from 'ReactFiberStateQueue'; +import type { UpdateQueue } from 'ReactFiberUpdateQueue'; var { reconcileChildFibers, @@ -42,10 +42,10 @@ var { OffscreenPriority, } = require('ReactPriorityLevel'); var { - createStateQueue, + createUpdateQueue, addToQueue, - mergeStateQueue, -} = require('ReactFiberStateQueue'); + mergeUpdateQueue, +} = require('ReactFiberUpdateQueue'); var ReactInstanceMap = require('ReactInstanceMap'); module.exports = function(config : HostConfig, getScheduler : () => Scheduler) { @@ -115,13 +115,13 @@ module.exports = function(config : HostConfig, getSchedu return workInProgress.child; } - function scheduleUpdate(fiber: Fiber, stateQueue: StateQueue, priorityLevel : PriorityLevel): void { + function scheduleUpdate(fiber: Fiber, updateQueue: UpdateQueue, priorityLevel : PriorityLevel): void { const { scheduleLowPriWork } = getScheduler(); - fiber.stateQueue = stateQueue; + fiber.updateQueue = updateQueue; // Schedule update on the alternate as well, since we don't know which tree // is current. if (fiber.alternate !== null) { - fiber.alternate.stateQueue = stateQueue; + fiber.alternate.updateQueue = updateQueue; } while (true) { if (fiber.pendingWorkPriority === NoWork || @@ -151,10 +151,10 @@ module.exports = function(config : HostConfig, getSchedu const updater = { enqueueSetState(instance, partialState) { const fiber = ReactInstanceMap.get(instance); - const stateQueue = fiber.stateQueue ? - addToQueue(fiber.stateQueue, partialState) : - createStateQueue(partialState); - scheduleUpdate(fiber, stateQueue, LowPriority); + const updateQueue = fiber.updateQueue ? + addToQueue(fiber.updateQueue, partialState) : + createUpdateQueue(partialState); + scheduleUpdate(fiber, updateQueue, LowPriority); }, }; @@ -166,21 +166,22 @@ module.exports = function(config : HostConfig, getSchedu if (!props && current) { props = current.memoizedProps; } - // Compute the state using the memoized state and the pending state queue. - var stateQueue = workInProgress.stateQueue; - var state = current ? - mergeStateQueue(stateQueue, current.memoizedState, props) : - mergeStateQueue(stateQueue, null, props); + // Compute the state using the memoized state and the update queue. + var updateQueue = workInProgress.updateQueue; + var previousState = current ? current.memoizedState : null; + var state = updateQueue ? + mergeUpdateQueue(updateQueue, previousState, props) : + previousState; var instance = workInProgress.stateNode; if (!instance) { var ctor = workInProgress.type; workInProgress.stateNode = instance = new ctor(props); state = instance.state || null; - // The initial state must be added to the pending state queue in case + // The initial state must be added to the update queue in case // setState is called before the initial render. if (state !== null) { - workInProgress.stateQueue = createStateQueue(state); + workInProgress.updateQueue = createUpdateQueue(state); } // The instance needs access to the fiber so that it can schedule updates ReactInstanceMap.set(instance, workInProgress); @@ -331,8 +332,7 @@ module.exports = function(config : HostConfig, getSchedu workInProgress.memoizedProps !== null && workInProgress.pendingProps === workInProgress.memoizedProps )) && - workInProgress.stateQueue === null - ) { + workInProgress.updateQueue === null) { return bailoutOnAlreadyFinishedWork(current, workInProgress); } diff --git a/src/renderers/shared/fiber/ReactFiberScheduler.js b/src/renderers/shared/fiber/ReactFiberScheduler.js index 2136907d1a..122a64fcd5 100644 --- a/src/renderers/shared/fiber/ReactFiberScheduler.js +++ b/src/renderers/shared/fiber/ReactFiberScheduler.js @@ -143,9 +143,9 @@ module.exports = function(config : HostConfig) { // The work is now done. We don't need this anymore. This flags // to the system not to redo any work here. workInProgress.pendingProps = null; - workInProgress.stateQueue = null; + workInProgress.updateQueue = null; if (current) { - current.stateQueue = null; + current.updateQueue = null; } const returnFiber = workInProgress.return; diff --git a/src/renderers/shared/fiber/ReactFiberStateQueue.js b/src/renderers/shared/fiber/ReactFiberUpdateQueue.js similarity index 51% rename from src/renderers/shared/fiber/ReactFiberStateQueue.js rename to src/renderers/shared/fiber/ReactFiberUpdateQueue.js index d410f8d0d6..57329b2522 100644 --- a/src/renderers/shared/fiber/ReactFiberStateQueue.js +++ b/src/renderers/shared/fiber/ReactFiberUpdateQueue.js @@ -6,53 +6,59 @@ * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * - * @providesModule ReactFiberStateQueue + * @providesModule ReactFiberUpdateQueue * @flow */ 'use strict'; -type StateQueueNode = { +type UpdateQueueNode = { partialState: any, callback: ?Function, - next: ?StateQueueNode, + next: ?UpdateQueueNode, }; -export type StateQueue = StateQueueNode & { - tail: ?StateQueueNode +export type UpdateQueue = UpdateQueueNode & { + tail: UpdateQueueNode }; -exports.createStateQueue = function(partialState : mixed) : StateQueue { - return { +exports.createUpdateQueue = function(partialState : mixed) : UpdateQueue { + const queue = { partialState, callback: null, next: null, - tail: null, + tail: (null : any), }; + queue.tail = queue; + return queue; }; -exports.addToQueue = function(queue : StateQueue, partialState : mixed) : StateQueue { +exports.addToQueue = function(queue : UpdateQueue, partialState : mixed) : UpdateQueue { const node = { partialState, callback: null, next: null, }; - if (!queue.tail) { - queue.next = node; - } else { - queue.tail.next = node; - } + queue.tail.next = node; queue.tail = node; return queue; }; -exports.mergeStateQueue = function(queue : ?StateQueue, prevState : any, props : any) : any { - let node : ?StateQueueNode = queue; - if (!node) { - return prevState; +exports.callCallbacks = function(queue : UpdateQueue, partialState : mixed) { + let node : ?UpdateQueueNode = queue; + while (node) { + if (node.callback) { + const { callback } = node; + callback(); + } + node = node.next; } +}; + +exports.mergeUpdateQueue = function(queue : UpdateQueue, prevState : any, props : any) : any { + let node : ?UpdateQueueNode = queue; let state = Object.assign({}, prevState); - do { + while (node) { let partialState; if (typeof node.partialState === 'function') { const updateFn = node.partialState; @@ -61,6 +67,7 @@ exports.mergeStateQueue = function(queue : ?StateQueue, prevState : any, props : partialState = node.partialState; } state = Object.assign(state, partialState); - } while (node = node.next); + node = node.next; + } return state; };