Skip to content

Commit

Permalink
Added naive scheduleDeferredCallback implementation for RN (facebook#…
Browse files Browse the repository at this point in the history
…11362)

* Added naive scheduleDeferredCallback implementation for RN

* Fixed ReactNative shim's expected @provideModule
  • Loading branch information
bvaughn authored Oct 25, 2017
1 parent 396eb86 commit c86ae4b
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 9 deletions.
12 changes: 5 additions & 7 deletions packages/react-native-renderer/src/ReactNativeFiberRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const deepFreezeAndThrowOnMutationInDev = require('deepFreezeAndThrowOnMutationI
const ReactNativeAttributePayload = require('./ReactNativeAttributePayload');
const ReactNativeComponentTree = require('./ReactNativeComponentTree');
const ReactNativeFiberHostComponent = require('./ReactNativeFiberHostComponent');
const ReactNativeFrameScheduling = require('./ReactNativeFrameScheduling');
const ReactNativeTagHandles = require('./ReactNativeTagHandles');
const ReactNativeViewConfigRegistry = require('./ReactNativeViewConfigRegistry');
const {
Expand Down Expand Up @@ -157,6 +158,8 @@ const NativeRenderer = ReactFiberReconciler({
return instance;
},

now: ReactNativeFrameScheduling.now,

prepareForCommit(): void {
// Noop
},
Expand All @@ -176,12 +179,12 @@ const NativeRenderer = ReactFiberReconciler({
// Noop
},

scheduleDeferredCallback: ReactNativeFrameScheduling.scheduleDeferredCallback,

shouldDeprioritizeSubtree(type: string, props: Props): boolean {
return false;
},

scheduleDeferredCallback: global.requestIdleCallback,

shouldSetTextContent(type: string, props: Props): boolean {
// TODO (bvaughn) Revisit this decision.
// Always returning false simplifies the createInstance() implementation,
Expand All @@ -194,11 +197,6 @@ const NativeRenderer = ReactFiberReconciler({

useSyncScheduling: true,

now(): number {
// TODO: Enable expiration by implementing this method.
return 0;
},

mutation: {
appendChild(
parentInstance: Instance,
Expand Down
65 changes: 65 additions & 0 deletions packages/react-native-renderer/src/ReactNativeFrameScheduling.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/

'use strict';

import type {Deadline} from 'react-reconciler';

const hasNativePerformanceNow =
typeof performance === 'object' && typeof performance.now === 'function';

const now = hasNativePerformanceNow
? () => performance.now()
: () => Date.now();

type Callback = (deadline: Deadline) => void;

let isCallbackScheduled: boolean = false;
let scheduledCallback: Callback | null = null;
let frameDeadline: number = 0;

const frameDeadlineObject: Deadline = {
timeRemaining: () => frameDeadline - now(),
};

function setTimeoutCallback() {
isCallbackScheduled = false;

// TODO (bvaughn) Hard-coded 5ms unblocks initial async testing.
// React API probably changing to boolean rather than time remaining.
// Longer-term plan is to rewrite this using shared memory,
// And just return the value of the bit as the boolean.
frameDeadline = now() + 5;

const callback = scheduledCallback;
scheduledCallback = null;
if (callback !== null) {
callback(frameDeadlineObject);
}
}

// RN has a poor polyfill for requestIdleCallback so we aren't using it.
// This implementation is only intended for short-term use anyway.
// We also don't implement cancel functionality b'c Fiber doesn't currently need it.
function scheduleDeferredCallback(callback: Callback): number {
// We assume only one callback is scheduled at a time b'c that's how Fiber works.
scheduledCallback = callback;

if (!isCallbackScheduled) {
isCallbackScheduled = true;
setTimeout(setTimeoutCallback, 1);
}

return 0;
}

module.exports = {
now,
scheduleDeferredCallback,
};
4 changes: 2 additions & 2 deletions scripts/rollup/shims/react-native/ReactNative.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ import type {ReactNativeType} from 'ReactNativeTypes';
let ReactNative;

if (__DEV__) {
ReactNative = require('ReactNativeFiber-dev');
ReactNative = require('ReactNativeRenderer-dev');
} else {
ReactNative = require('ReactNativeFiber-prod');
ReactNative = require('ReactNativeRenderer-prod');
}

module.exports = (ReactNative: ReactNativeType);

0 comments on commit c86ae4b

Please sign in to comment.