Skip to content

Commit

Permalink
Use RootTag field to configure type of root
Browse files Browse the repository at this point in the history
There are three types of roots: Legacy, Batched, and Concurrent.
  • Loading branch information
acdlite committed Apr 29, 2019
1 parent 944dd85 commit 4f5545b
Show file tree
Hide file tree
Showing 13 changed files with 73 additions and 74 deletions.
3 changes: 2 additions & 1 deletion packages/react-art/src/ReactART.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import React from 'react';
import ReactVersion from 'shared/ReactVersion';
import {LegacyRoot} from 'shared/ReactRootTags';
import {
createContainer,
updateContainer,
Expand Down Expand Up @@ -65,7 +66,7 @@ class Surface extends React.Component {

this._surface = Mode.Surface(+width, +height, this._tagRef);

this._mountNode = createContainer(this._surface);
this._mountNode = createContainer(this._surface, LegacyRoot, false);
updateContainer(this.props.children, this._mountNode, this);
}

Expand Down
17 changes: 6 additions & 11 deletions packages/react-dom/src/client/ReactDOM.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
*/

import type {ReactNodeList} from 'shared/ReactTypes';
import type {RootTag} from 'shared/ReactRootTags';
// TODO: This type is shared between the reconciler and ReactDOM, but will
// eventually be lifted out to the renderer.
import type {
Expand Down Expand Up @@ -52,6 +53,7 @@ import {
accumulateTwoPhaseDispatches,
accumulateDirectDispatches,
} from 'events/EventPropagators';
import {LegacyRoot, ConcurrentRoot} from 'shared/ReactRootTags';
import {has as hasInstance} from 'shared/ReactInstanceMap';
import ReactVersion from 'shared/ReactVersion';
import ReactSharedInternals from 'shared/ReactSharedInternals';
Expand Down Expand Up @@ -361,13 +363,8 @@ ReactWork.prototype._onCommit = function(): void {
}
};

function ReactRoot(
container: DOMContainer,
isConcurrent: boolean,
hydrate: boolean,
) {
const isBatched = false;
const root = createContainer(container, isBatched, isConcurrent, hydrate);
function ReactRoot(container: DOMContainer, tag: RootTag, hydrate: boolean) {
const root = createContainer(container, tag, hydrate);
this._internalRoot = root;
}
ReactRoot.prototype.render = function(
Expand Down Expand Up @@ -532,9 +529,7 @@ function legacyCreateRootFromDOMContainer(
);
}
}
// Legacy roots are not async by default.
const isConcurrent = false;
return new ReactRoot(container, isConcurrent, shouldHydrate);
return new ReactRoot(container, LegacyRoot, shouldHydrate);
}

function legacyRenderSubtreeIntoContainer(
Expand Down Expand Up @@ -850,7 +845,7 @@ function createRoot(container: DOMContainer, options?: RootOptions): ReactRoot {
container._reactHasBeenPassedToCreateRootDEV = true;
}
const hydrate = options != null && options.hydrate === true;
return new ReactRoot(container, true, hydrate);
return new ReactRoot(container, ConcurrentRoot, hydrate);
}

if (enableStableConcurrentModeAPIs) {
Expand Down
17 changes: 6 additions & 11 deletions packages/react-dom/src/fire/ReactFire.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
// console.log('Hello from Fire entry point.');

import type {ReactNodeList} from 'shared/ReactTypes';
import type {RootTag} from 'shared/ReactRootTags';
// TODO: This type is shared between the reconciler and ReactDOM, but will
// eventually be lifted out to the renderer.
import type {
Expand Down Expand Up @@ -58,6 +59,7 @@ import {
accumulateTwoPhaseDispatches,
accumulateDirectDispatches,
} from 'events/EventPropagators';
import {LegacyRoot, ConcurrentRoot} from 'shared/ReactRootTags';
import {has as hasInstance} from 'shared/ReactInstanceMap';
import ReactVersion from 'shared/ReactVersion';
import ReactSharedInternals from 'shared/ReactSharedInternals';
Expand Down Expand Up @@ -367,13 +369,8 @@ ReactWork.prototype._onCommit = function(): void {
}
};

function ReactRoot(
container: DOMContainer,
isConcurrent: boolean,
hydrate: boolean,
) {
const isBatched = false;
const root = createContainer(container, isBatched, isConcurrent, hydrate);
function ReactRoot(container: DOMContainer, tag: RootTag, hydrate: boolean) {
const root = createContainer(container, tag, hydrate);
this._internalRoot = root;
}
ReactRoot.prototype.render = function(
Expand Down Expand Up @@ -538,9 +535,7 @@ function legacyCreateRootFromDOMContainer(
);
}
}
// Legacy roots are not async by default.
const isConcurrent = false;
return new ReactRoot(container, isConcurrent, shouldHydrate);
return new ReactRoot(container, LegacyRoot, shouldHydrate);
}

function legacyRenderSubtreeIntoContainer(
Expand Down Expand Up @@ -856,7 +851,7 @@ function createRoot(container: DOMContainer, options?: RootOptions): ReactRoot {
container._reactHasBeenPassedToCreateRootDEV = true;
}
const hydrate = options != null && options.hydrate === true;
return new ReactRoot(container, true, hydrate);
return new ReactRoot(container, ConcurrentRoot, hydrate);
}

if (enableStableConcurrentModeAPIs) {
Expand Down
3 changes: 2 additions & 1 deletion packages/react-native-renderer/src/ReactFabric.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import ReactNativeComponent from './ReactNativeComponent';
import {getClosestInstanceFromNode} from './ReactFabricComponentTree';
import {getInspectorDataForViewTag} from './ReactNativeFiberInspector';

import {LegacyRoot} from 'shared/ReactRootTags';
import ReactSharedInternals from 'shared/ReactSharedInternals';
import getComponentName from 'shared/getComponentName';
import warningWithoutStack from 'shared/warningWithoutStack';
Expand Down Expand Up @@ -119,7 +120,7 @@ const ReactFabric: ReactFabricType = {
if (!root) {
// TODO (bvaughn): If we decide to keep the wrapper component,
// We could create a wrapper for containerTag as well to reduce special casing.
root = createContainer(containerTag, false, false, false);
root = createContainer(containerTag, LegacyRoot, false);
roots.set(containerTag, root);
}
updateContainer(element, root, null, callback);
Expand Down
3 changes: 2 additions & 1 deletion packages/react-native-renderer/src/ReactNativeRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import {getClosestInstanceFromNode} from './ReactNativeComponentTree';
import {getInspectorDataForViewTag} from './ReactNativeFiberInspector';
import {setNativeProps} from './ReactNativeRendererSharedExports';

import {LegacyRoot} from 'shared/ReactRootTags';
import ReactSharedInternals from 'shared/ReactSharedInternals';
import getComponentName from 'shared/getComponentName';
import warningWithoutStack from 'shared/warningWithoutStack';
Expand Down Expand Up @@ -125,7 +126,7 @@ const ReactNativeRenderer: ReactNativeType = {
if (!root) {
// TODO (bvaughn): If we decide to keep the wrapper component,
// We could create a wrapper for containerTag as well to reduce special casing.
root = createContainer(containerTag, false, false, false);
root = createContainer(containerTag, LegacyRoot, false);
roots.set(containerTag, root);
}
updateContainer(element, root, null, callback);
Expand Down
38 changes: 8 additions & 30 deletions packages/react-noop-renderer/src/createReactNoop.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import type {Thenable} from 'react-reconciler/src/ReactFiberScheduler';
import type {Fiber} from 'react-reconciler/src/ReactFiber';
import type {UpdateQueue} from 'react-reconciler/src/ReactUpdateQueue';
import type {ReactNodeList} from 'shared/ReactTypes';
import type {RootTag} from 'shared/ReactRootTags';

import * as Scheduler from 'scheduler/unstable_mock';
import {createPortal} from 'shared/ReactPortal';
Expand All @@ -32,6 +33,7 @@ import enqueueTask from 'shared/enqueueTask';
import ReactSharedInternals from 'shared/ReactSharedInternals';
import warningWithoutStack from 'shared/warningWithoutStack';
import {enableEventAPI} from 'shared/ReactFeatureFlags';
import {ConcurrentRoot, BatchedRoot, LegacyRoot} from 'shared/ReactRootTags';

type EventTargetChildElement = {
type: string,
Expand Down Expand Up @@ -901,39 +903,27 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {
return getPendingChildren(container);
},

getOrCreateRootContainer(
rootID: string = DEFAULT_ROOT_ID,
isBatched: boolean,
isConcurrent: boolean,
) {
getOrCreateRootContainer(rootID: string = DEFAULT_ROOT_ID, tag: RootTag) {
let root = roots.get(rootID);
if (!root) {
const container = {rootID: rootID, pendingChildren: [], children: []};
rootContainers.set(rootID, container);
root = NoopRenderer.createContainer(
container,
isBatched,
isConcurrent,
false,
);
root = NoopRenderer.createContainer(container, tag, false);
roots.set(rootID, root);
}
return root.current.stateNode.containerInfo;
},

// TODO: Replace ReactNoop.render with createRoot + root.render
createRoot() {
const isBatched = true;
const isConcurrent = true;
const container = {
rootID: '' + idCounter++,
pendingChildren: [],
children: [],
};
const fiberRoot = NoopRenderer.createContainer(
container,
isBatched,
isConcurrent,
ConcurrentRoot,
false,
);
return {
Expand All @@ -951,17 +941,14 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {
},

createSyncRoot() {
const isBatched = true;
const isConcurrent = false;
const container = {
rootID: '' + idCounter++,
pendingChildren: [],
children: [],
};
const fiberRoot = NoopRenderer.createContainer(
container,
isBatched,
isConcurrent,
BatchedRoot,
false,
);
return {
Expand Down Expand Up @@ -1003,13 +990,7 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {

renderLegacySyncRoot(element: React$Element<any>, callback: ?Function) {
const rootID = DEFAULT_ROOT_ID;
const isBatched = false;
const isConcurrent = false;
const container = ReactNoop.getOrCreateRootContainer(
rootID,
isBatched,
isConcurrent,
);
const container = ReactNoop.getOrCreateRootContainer(rootID, LegacyRoot);
const root = roots.get(container.rootID);
NoopRenderer.updateContainer(element, root, null, callback);
},
Expand All @@ -1019,12 +1000,9 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {
rootID: string,
callback: ?Function,
) {
const isBatched = true;
const isConcurrent = true;
const container = ReactNoop.getOrCreateRootContainer(
rootID,
isBatched,
isConcurrent,
ConcurrentRoot,
);
const root = roots.get(container.rootID);
NoopRenderer.updateContainer(element, root, null, callback);
Expand Down
11 changes: 5 additions & 6 deletions packages/react-reconciler/src/ReactFiber.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import type {
ReactEventComponent,
ReactEventTarget,
} from 'shared/ReactTypes';
import type {RootTag} from 'shared/ReactRootTags';
import type {WorkTag} from 'shared/ReactWorkTags';
import type {TypeOfMode} from './ReactTypeOfMode';
import type {SideEffectTag} from 'shared/ReactSideEffectTags';
Expand All @@ -27,6 +28,7 @@ import invariant from 'shared/invariant';
import warningWithoutStack from 'shared/warningWithoutStack';
import {enableProfilerTimer, enableEventAPI} from 'shared/ReactFeatureFlags';
import {NoEffect} from 'shared/ReactSideEffectTags';
import {ConcurrentRoot, BatchedRoot} from 'shared/ReactRootTags';
import {
IndeterminateComponent,
ClassComponent,
Expand Down Expand Up @@ -435,14 +437,11 @@ export function createWorkInProgress(
return workInProgress;
}

export function createHostRootFiber(
isBatched: boolean,
isConcurrent: boolean,
): Fiber {
export function createHostRootFiber(tag: RootTag): Fiber {
let mode;
if (isConcurrent) {
if (tag === ConcurrentRoot) {
mode = ConcurrentMode | BatchedMode | StrictMode;
} else if (isBatched) {
} else if (tag === BatchedRoot) {
mode = BatchedMode | StrictMode;
} else {
mode = NoMode;
Expand Down
6 changes: 3 additions & 3 deletions packages/react-reconciler/src/ReactFiberReconciler.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import type {Fiber} from './ReactFiber';
import type {FiberRoot} from './ReactFiberRoot';
import type {RootTag} from 'shared/ReactRootTags';
import type {
Instance,
TextInstance,
Expand Down Expand Up @@ -273,11 +274,10 @@ function findHostInstanceWithWarning(

export function createContainer(
containerInfo: Container,
isBatched: boolean,
isConcurrent: boolean,
tag: RootTag,
hydrate: boolean,
): OpaqueRoot {
return createFiberRoot(containerInfo, isBatched, isConcurrent, hydrate);
return createFiberRoot(containerInfo, tag, hydrate);
}

export function updateContainer(
Expand Down
14 changes: 9 additions & 5 deletions packages/react-reconciler/src/ReactFiberRoot.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import type {Fiber} from './ReactFiber';
import type {ExpirationTime} from './ReactFiberExpirationTime';
import type {RootTag} from 'shared/ReactRootTags';
import type {TimeoutHandle, NoTimeout} from './ReactFiberHostConfig';
import type {Thenable} from './ReactFiberScheduler';
import type {Interaction} from 'scheduler/src/Tracing';
Expand All @@ -30,6 +31,9 @@ export type Batch = {
export type PendingInteractionMap = Map<ExpirationTime, Set<Interaction>>;

type BaseFiberRootProperties = {|
// The type of root (legacy, batched, concurrent, etc.)
tag: RootTag,

// Any additional information from the host associated with this root.
containerInfo: any,
// Used only by persistent updates.
Expand Down Expand Up @@ -89,7 +93,8 @@ export type FiberRoot = {
...ProfilingOnlyFiberRootProperties,
};

function FiberRootNode(containerInfo, hydrate) {
function FiberRootNode(containerInfo, tag, hydrate) {
this.tag = tag;
this.current = null;
this.containerInfo = containerInfo;
this.pendingChildren = null;
Expand All @@ -116,15 +121,14 @@ function FiberRootNode(containerInfo, hydrate) {

export function createFiberRoot(
containerInfo: any,
isBatched: boolean,
isConcurrent: boolean,
tag: RootTag,
hydrate: boolean,
): FiberRoot {
const root: FiberRoot = (new FiberRootNode(containerInfo, hydrate): any);
const root: FiberRoot = (new FiberRootNode(containerInfo, tag, hydrate): any);

// Cyclic construction. This cheats the type system right now because
// stateNode is any.
const uninitializedFiber = createHostRootFiber(isBatched, isConcurrent);
const uninitializedFiber = createHostRootFiber(tag);
root.current = uninitializedFiber;
uninitializedFiber.stateNode = root;

Expand Down
2 changes: 2 additions & 0 deletions packages/react-reconciler/src/ReactTypeOfMode.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ export type TypeOfMode = number;

export const NoMode = 0b0000;
export const StrictMode = 0b0001;
// TODO: Remove BatchedMode and ConcurrentMode by reading from the root
// tag instead
export const BatchedMode = 0b0010;
export const ConcurrentMode = 0b0100;
export const ProfileMode = 0b1000;
Loading

0 comments on commit 4f5545b

Please sign in to comment.