Skip to content

Commit e38b2c2

Browse files
committed
[scheduler] Deadline object -> shouldYield
Instead of using a requestIdleCallback-style deadline object, expose a method Scheduler.shouldYield that returns true if there's a higher priority event in the queue.
1 parent 21a79a1 commit e38b2c2

16 files changed

Lines changed: 206 additions & 248 deletions

packages/react-art/src/ReactARTHostConfig.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
export {
99
unstable_now as now,
1010
unstable_scheduleCallback as scheduleDeferredCallback,
11+
unstable_shouldYield as shouldYield,
1112
unstable_cancelCallback as cancelDeferredCallback,
1213
} from 'scheduler';
1314
import Transform from 'art/core/transform';

packages/react-dom/src/client/ReactDOMHostConfig.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ export type NoTimeout = -1;
6565
export {
6666
unstable_now as now,
6767
unstable_scheduleCallback as scheduleDeferredCallback,
68+
unstable_shouldYield as shouldYield,
6869
unstable_cancelCallback as cancelDeferredCallback,
6970
} from 'scheduler';
7071

packages/react-native-renderer/src/ReactFabricHostConfig.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,7 @@ export const scheduleDeferredCallback =
332332
ReactNativeFrameScheduling.scheduleDeferredCallback;
333333
export const cancelDeferredCallback =
334334
ReactNativeFrameScheduling.cancelDeferredCallback;
335+
export const shouldYield = ReactNativeFrameScheduling.shouldYield;
335336

336337
export const scheduleTimeout = setTimeout;
337338
export const cancelTimeout = clearTimeout;

packages/react-native-renderer/src/ReactNativeFrameScheduling.js

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,16 @@
77
* @flow
88
*/
99

10-
import type {Deadline} from 'react-reconciler/src/ReactFiberScheduler';
11-
1210
const hasNativePerformanceNow =
1311
typeof performance === 'object' && typeof performance.now === 'function';
1412

1513
const now = hasNativePerformanceNow
1614
? () => performance.now()
1715
: () => Date.now();
1816

19-
type Callback = (deadline: Deadline) => void;
20-
21-
let scheduledCallback: Callback | null = null;
17+
let scheduledCallback: (() => mixed) | null = null;
2218
let frameDeadline: number = 0;
2319

24-
const frameDeadlineObject: Deadline = {
25-
timeRemaining: () => frameDeadline - now(),
26-
didTimeout: false,
27-
};
28-
2920
function setTimeoutCallback() {
3021
// TODO (bvaughn) Hard-coded 5ms unblocks initial async testing.
3122
// React API probably changing to boolean rather than time remaining.
@@ -36,15 +27,15 @@ function setTimeoutCallback() {
3627
const callback = scheduledCallback;
3728
scheduledCallback = null;
3829
if (callback !== null) {
39-
callback(frameDeadlineObject);
30+
callback();
4031
}
4132
}
4233

4334
// RN has a poor polyfill for requestIdleCallback so we aren't using it.
4435
// This implementation is only intended for short-term use anyway.
4536
// We also don't implement cancel functionality b'c Fiber doesn't currently need it.
4637
function scheduleDeferredCallback(
47-
callback: Callback,
38+
callback: () => mixed,
4839
options?: {timeout: number},
4940
): number {
5041
// We assume only one callback is scheduled at a time b'c that's how Fiber works.
@@ -58,4 +49,8 @@ function cancelDeferredCallback(callbackID: number) {
5849
clearTimeout((callbackID: any)); // Timeouts are always numbers on RN
5950
}
6051

61-
export {now, scheduleDeferredCallback, cancelDeferredCallback};
52+
function shouldYield() {
53+
return frameDeadline <= now();
54+
}
55+
56+
export {now, scheduleDeferredCallback, cancelDeferredCallback, shouldYield};

packages/react-native-renderer/src/ReactNativeHostConfig.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,7 @@ export const scheduleDeferredCallback =
238238
ReactNativeFrameScheduling.scheduleDeferredCallback;
239239
export const cancelDeferredCallback =
240240
ReactNativeFrameScheduling.cancelDeferredCallback;
241+
export const shouldYield = ReactNativeFrameScheduling.shouldYield;
241242

242243
export const scheduleTimeout = setTimeout;
243244
export const cancelTimeout = clearTimeout;

packages/react-noop-renderer/src/createReactNoop.js

Lines changed: 37 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {
271271
scheduledCallbackTimeout === -1 ||
272272
scheduledCallbackTimeout > newTimeout
273273
) {
274-
scheduledCallbackTimeout = newTimeout;
274+
scheduledCallbackTimeout = elapsedTimeInMs + newTimeout;
275275
}
276276
}
277277
return 0;
@@ -285,6 +285,8 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {
285285
scheduledCallbackTimeout = -1;
286286
},
287287

288+
shouldYield,
289+
288290
scheduleTimeout: setTimeout,
289291
cancelTimeout: clearTimeout,
290292
noTimeout: -1,
@@ -407,35 +409,44 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {
407409

408410
let yieldedValues = null;
409411

412+
let didYield;
410413
let unitsRemaining;
411414

415+
function shouldYield() {
416+
if (
417+
scheduledCallbackTimeout === -1 ||
418+
elapsedTimeInMs > scheduledCallbackTimeout
419+
) {
420+
return false;
421+
} else {
422+
if (didYield || yieldedValues !== null) {
423+
return true;
424+
}
425+
if (unitsRemaining-- > 0) {
426+
return false;
427+
}
428+
didYield = true;
429+
return true;
430+
}
431+
}
432+
412433
function* flushUnitsOfWork(n: number): Generator<Array<mixed>, void, void> {
413-
let didStop = false;
414-
while (!didStop && scheduledCallback !== null) {
415-
let cb = scheduledCallback;
416-
scheduledCallback = null;
417-
unitsRemaining = n;
418-
cb({
419-
timeRemaining() {
420-
if (yieldedValues !== null) {
421-
return 0;
422-
}
423-
if (unitsRemaining-- > 0) {
424-
return 999;
425-
}
426-
didStop = true;
427-
return 0;
428-
},
429-
didTimeout:
430-
scheduledCallbackTimeout !== -1 &&
431-
elapsedTimeInMs > scheduledCallbackTimeout,
432-
});
433-
434-
if (yieldedValues !== null) {
435-
const values = yieldedValues;
436-
yieldedValues = null;
437-
yield values;
434+
unitsRemaining = n + 1;
435+
didYield = false;
436+
try {
437+
while (!didYield && scheduledCallback !== null) {
438+
let cb = scheduledCallback;
439+
scheduledCallback = null;
440+
cb();
441+
if (yieldedValues !== null) {
442+
const values = yieldedValues;
443+
yieldedValues = null;
444+
yield values;
445+
}
438446
}
447+
} finally {
448+
unitsRemaining = -1;
449+
didYield = false;
439450
}
440451
}
441452

0 commit comments

Comments
 (0)