scheduler 0.16.1 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build-info.json +5 -5
- package/cjs/scheduler-tracing.development.js +8 -88
- package/cjs/scheduler-tracing.production.min.js +2 -2
- package/cjs/scheduler-tracing.profiling.min.js +6 -5
- package/cjs/scheduler-unstable_mock.development.js +70 -80
- package/cjs/scheduler-unstable_mock.production.min.js +12 -12
- package/cjs/scheduler.development.js +106 -270
- package/cjs/scheduler.production.min.js +12 -13
- package/package.json +1 -1
- package/umd/scheduler-tracing.development.js +2 -2
- package/umd/scheduler-tracing.production.min.js +2 -2
- package/umd/scheduler-tracing.profiling.min.js +2 -2
- package/umd/scheduler-unstable_mock.development.js +671 -681
- package/umd/scheduler-unstable_mock.production.min.js +10 -10
- package/umd/scheduler.development.js +2 -2
- package/umd/scheduler.production.min.js +2 -2
- package/umd/scheduler.profiling.min.js +2 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @license React v0.
|
|
1
|
+
/** @license React v0.19.0
|
|
2
2
|
* scheduler-unstable_mock.development.js
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
@@ -10,770 +10,778 @@
|
|
|
10
10
|
'use strict';
|
|
11
11
|
|
|
12
12
|
(function (global, factory) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
|
|
14
|
+
typeof define === 'function' && define.amd ? define(['exports'], factory) :
|
|
15
|
+
(global = global || self, factory(global.SchedulerMock = {}));
|
|
16
16
|
}(this, (function (exports) { 'use strict';
|
|
17
17
|
|
|
18
|
-
var enableSchedulerDebugging = false;
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
var
|
|
22
|
-
|
|
23
|
-
var
|
|
24
|
-
var
|
|
25
|
-
var
|
|
26
|
-
var
|
|
27
|
-
var
|
|
28
|
-
var
|
|
29
|
-
var
|
|
30
|
-
var
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
didStop = true;
|
|
49
|
-
return true;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
return false;
|
|
53
|
-
}
|
|
54
|
-
function getCurrentTime() {
|
|
55
|
-
return currentTime;
|
|
56
|
-
}
|
|
57
|
-
function forceFrameRate() {// No-op
|
|
58
|
-
}
|
|
59
|
-
// Should only be used via an assertion helper that inspects the yielded values.
|
|
60
|
-
|
|
61
|
-
function unstable_flushNumberOfYields(count) {
|
|
62
|
-
if (isFlushing) {
|
|
63
|
-
throw new Error('Already flushing work.');
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
if (scheduledCallback !== null) {
|
|
67
|
-
var cb = scheduledCallback;
|
|
68
|
-
expectedNumberOfYields = count;
|
|
69
|
-
isFlushing = true;
|
|
18
|
+
var enableSchedulerDebugging = false;
|
|
19
|
+
var enableProfiling = true;
|
|
20
|
+
|
|
21
|
+
var currentTime = 0;
|
|
22
|
+
var scheduledCallback = null;
|
|
23
|
+
var scheduledTimeout = null;
|
|
24
|
+
var timeoutTime = -1;
|
|
25
|
+
var yieldedValues = null;
|
|
26
|
+
var expectedNumberOfYields = -1;
|
|
27
|
+
var didStop = false;
|
|
28
|
+
var isFlushing = false;
|
|
29
|
+
var needsPaint = false;
|
|
30
|
+
var shouldYieldForPaint = false;
|
|
31
|
+
function requestHostCallback(callback) {
|
|
32
|
+
scheduledCallback = callback;
|
|
33
|
+
}
|
|
34
|
+
function requestHostTimeout(callback, ms) {
|
|
35
|
+
scheduledTimeout = callback;
|
|
36
|
+
timeoutTime = currentTime + ms;
|
|
37
|
+
}
|
|
38
|
+
function cancelHostTimeout() {
|
|
39
|
+
scheduledTimeout = null;
|
|
40
|
+
timeoutTime = -1;
|
|
41
|
+
}
|
|
42
|
+
function shouldYieldToHost() {
|
|
43
|
+
if (expectedNumberOfYields !== -1 && yieldedValues !== null && yieldedValues.length >= expectedNumberOfYields || shouldYieldForPaint && needsPaint) {
|
|
44
|
+
// We yielded at least as many values as expected. Stop flushing.
|
|
45
|
+
didStop = true;
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
70
48
|
|
|
71
|
-
|
|
72
|
-
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
function getCurrentTime() {
|
|
52
|
+
return currentTime;
|
|
53
|
+
}
|
|
54
|
+
function forceFrameRate() {// No-op
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function unstable_flushNumberOfYields(count) {
|
|
58
|
+
if (isFlushing) {
|
|
59
|
+
throw new Error('Already flushing work.');
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (scheduledCallback !== null) {
|
|
63
|
+
var cb = scheduledCallback;
|
|
64
|
+
expectedNumberOfYields = count;
|
|
65
|
+
isFlushing = true;
|
|
66
|
+
|
|
67
|
+
try {
|
|
68
|
+
var hasMoreWork = true;
|
|
73
69
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
70
|
+
do {
|
|
71
|
+
hasMoreWork = cb(true, currentTime);
|
|
72
|
+
} while (hasMoreWork && !didStop);
|
|
77
73
|
|
|
78
|
-
|
|
79
|
-
|
|
74
|
+
if (!hasMoreWork) {
|
|
75
|
+
scheduledCallback = null;
|
|
76
|
+
}
|
|
77
|
+
} finally {
|
|
78
|
+
expectedNumberOfYields = -1;
|
|
79
|
+
didStop = false;
|
|
80
|
+
isFlushing = false;
|
|
80
81
|
}
|
|
81
|
-
} finally {
|
|
82
|
-
expectedNumberOfYields = -1;
|
|
83
|
-
didStop = false;
|
|
84
|
-
isFlushing = false;
|
|
85
82
|
}
|
|
86
83
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
}
|
|
84
|
+
function unstable_flushUntilNextPaint() {
|
|
85
|
+
if (isFlushing) {
|
|
86
|
+
throw new Error('Already flushing work.');
|
|
87
|
+
}
|
|
92
88
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
89
|
+
if (scheduledCallback !== null) {
|
|
90
|
+
var cb = scheduledCallback;
|
|
91
|
+
shouldYieldForPaint = true;
|
|
92
|
+
needsPaint = false;
|
|
93
|
+
isFlushing = true;
|
|
98
94
|
|
|
99
|
-
|
|
100
|
-
|
|
95
|
+
try {
|
|
96
|
+
var hasMoreWork = true;
|
|
101
97
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
98
|
+
do {
|
|
99
|
+
hasMoreWork = cb(true, currentTime);
|
|
100
|
+
} while (hasMoreWork && !didStop);
|
|
105
101
|
|
|
106
|
-
|
|
107
|
-
|
|
102
|
+
if (!hasMoreWork) {
|
|
103
|
+
scheduledCallback = null;
|
|
104
|
+
}
|
|
105
|
+
} finally {
|
|
106
|
+
shouldYieldForPaint = false;
|
|
107
|
+
didStop = false;
|
|
108
|
+
isFlushing = false;
|
|
108
109
|
}
|
|
109
|
-
} finally {
|
|
110
|
-
shouldYieldForPaint = false;
|
|
111
|
-
didStop = false;
|
|
112
|
-
isFlushing = false;
|
|
113
110
|
}
|
|
114
111
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
}
|
|
112
|
+
function unstable_flushExpired() {
|
|
113
|
+
if (isFlushing) {
|
|
114
|
+
throw new Error('Already flushing work.');
|
|
115
|
+
}
|
|
120
116
|
|
|
121
|
-
|
|
122
|
-
|
|
117
|
+
if (scheduledCallback !== null) {
|
|
118
|
+
isFlushing = true;
|
|
123
119
|
|
|
124
|
-
|
|
125
|
-
|
|
120
|
+
try {
|
|
121
|
+
var hasMoreWork = scheduledCallback(false, currentTime);
|
|
126
122
|
|
|
127
|
-
|
|
128
|
-
|
|
123
|
+
if (!hasMoreWork) {
|
|
124
|
+
scheduledCallback = null;
|
|
125
|
+
}
|
|
126
|
+
} finally {
|
|
127
|
+
isFlushing = false;
|
|
129
128
|
}
|
|
130
|
-
} finally {
|
|
131
|
-
isFlushing = false;
|
|
132
129
|
}
|
|
133
130
|
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
}
|
|
131
|
+
function unstable_flushAllWithoutAsserting() {
|
|
132
|
+
// Returns false if no work was flushed.
|
|
133
|
+
if (isFlushing) {
|
|
134
|
+
throw new Error('Already flushing work.');
|
|
135
|
+
}
|
|
140
136
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
137
|
+
if (scheduledCallback !== null) {
|
|
138
|
+
var cb = scheduledCallback;
|
|
139
|
+
isFlushing = true;
|
|
144
140
|
|
|
145
|
-
|
|
146
|
-
|
|
141
|
+
try {
|
|
142
|
+
var hasMoreWork = true;
|
|
147
143
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
144
|
+
do {
|
|
145
|
+
hasMoreWork = cb(true, currentTime);
|
|
146
|
+
} while (hasMoreWork);
|
|
151
147
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
148
|
+
if (!hasMoreWork) {
|
|
149
|
+
scheduledCallback = null;
|
|
150
|
+
}
|
|
155
151
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
152
|
+
return true;
|
|
153
|
+
} finally {
|
|
154
|
+
isFlushing = false;
|
|
155
|
+
}
|
|
156
|
+
} else {
|
|
157
|
+
return false;
|
|
159
158
|
}
|
|
160
|
-
} else {
|
|
161
|
-
return false;
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
function unstable_clearYields() {
|
|
165
|
-
if (yieldedValues === null) {
|
|
166
|
-
return [];
|
|
167
159
|
}
|
|
160
|
+
function unstable_clearYields() {
|
|
161
|
+
if (yieldedValues === null) {
|
|
162
|
+
return [];
|
|
163
|
+
}
|
|
168
164
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
}
|
|
173
|
-
function unstable_flushAll() {
|
|
174
|
-
if (yieldedValues !== null) {
|
|
175
|
-
throw new Error('Log is not empty. Assert on the log of yielded values before ' + 'flushing additional work.');
|
|
165
|
+
var values = yieldedValues;
|
|
166
|
+
yieldedValues = null;
|
|
167
|
+
return values;
|
|
176
168
|
}
|
|
169
|
+
function unstable_flushAll() {
|
|
170
|
+
if (yieldedValues !== null) {
|
|
171
|
+
throw new Error('Log is not empty. Assert on the log of yielded values before ' + 'flushing additional work.');
|
|
172
|
+
}
|
|
177
173
|
|
|
178
|
-
|
|
174
|
+
unstable_flushAllWithoutAsserting();
|
|
179
175
|
|
|
180
|
-
|
|
181
|
-
|
|
176
|
+
if (yieldedValues !== null) {
|
|
177
|
+
throw new Error('While flushing work, something yielded a value. Use an ' + 'assertion helper to assert on the log of yielded values, e.g. ' + 'expect(Scheduler).toFlushAndYield([...])');
|
|
178
|
+
}
|
|
182
179
|
}
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
180
|
+
function unstable_yieldValue(value) {
|
|
181
|
+
if (yieldedValues === null) {
|
|
182
|
+
yieldedValues = [value];
|
|
183
|
+
} else {
|
|
184
|
+
yieldedValues.push(value);
|
|
185
|
+
}
|
|
189
186
|
}
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
currentTime += ms;
|
|
187
|
+
function unstable_advanceTime(ms) {
|
|
188
|
+
currentTime += ms;
|
|
193
189
|
|
|
194
|
-
if (!isFlushing) {
|
|
195
190
|
if (scheduledTimeout !== null && timeoutTime <= currentTime) {
|
|
196
191
|
scheduledTimeout(currentTime);
|
|
197
192
|
timeoutTime = -1;
|
|
198
193
|
scheduledTimeout = null;
|
|
199
194
|
}
|
|
195
|
+
}
|
|
196
|
+
function requestPaint() {
|
|
197
|
+
needsPaint = true;
|
|
198
|
+
}
|
|
200
199
|
|
|
201
|
-
|
|
200
|
+
function push(heap, node) {
|
|
201
|
+
var index = heap.length;
|
|
202
|
+
heap.push(node);
|
|
203
|
+
siftUp(heap, node, index);
|
|
204
|
+
}
|
|
205
|
+
function peek(heap) {
|
|
206
|
+
var first = heap[0];
|
|
207
|
+
return first === undefined ? null : first;
|
|
202
208
|
}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
needsPaint = true;
|
|
206
|
-
}
|
|
209
|
+
function pop(heap) {
|
|
210
|
+
var first = heap[0];
|
|
207
211
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
heap.push(node);
|
|
211
|
-
siftUp(heap, node, index);
|
|
212
|
-
}
|
|
213
|
-
function peek(heap) {
|
|
214
|
-
var first = heap[0];
|
|
215
|
-
return first === undefined ? null : first;
|
|
216
|
-
}
|
|
217
|
-
function pop(heap) {
|
|
218
|
-
var first = heap[0];
|
|
212
|
+
if (first !== undefined) {
|
|
213
|
+
var last = heap.pop();
|
|
219
214
|
|
|
220
|
-
|
|
221
|
-
|
|
215
|
+
if (last !== first) {
|
|
216
|
+
heap[0] = last;
|
|
217
|
+
siftDown(heap, last, 0);
|
|
218
|
+
}
|
|
222
219
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
220
|
+
return first;
|
|
221
|
+
} else {
|
|
222
|
+
return null;
|
|
226
223
|
}
|
|
227
|
-
|
|
228
|
-
return first;
|
|
229
|
-
} else {
|
|
230
|
-
return null;
|
|
231
224
|
}
|
|
232
|
-
}
|
|
233
225
|
|
|
234
|
-
function siftUp(heap, node, i) {
|
|
235
|
-
|
|
226
|
+
function siftUp(heap, node, i) {
|
|
227
|
+
var index = i;
|
|
236
228
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
229
|
+
while (true) {
|
|
230
|
+
var parentIndex = index - 1 >>> 1;
|
|
231
|
+
var parent = heap[parentIndex];
|
|
240
232
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
233
|
+
if (parent !== undefined && compare(parent, node) > 0) {
|
|
234
|
+
// The parent is larger. Swap positions.
|
|
235
|
+
heap[parentIndex] = node;
|
|
236
|
+
heap[index] = parent;
|
|
237
|
+
index = parentIndex;
|
|
238
|
+
} else {
|
|
239
|
+
// The parent is smaller. Exit.
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
249
242
|
}
|
|
250
243
|
}
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
function siftDown(heap, node, i) {
|
|
254
|
-
var index = i;
|
|
255
|
-
var length = heap.length;
|
|
256
|
-
|
|
257
|
-
while (index < length) {
|
|
258
|
-
var leftIndex = (index + 1) * 2 - 1;
|
|
259
|
-
var left = heap[leftIndex];
|
|
260
|
-
var rightIndex = leftIndex + 1;
|
|
261
|
-
var right = heap[rightIndex]; // If the left or right node is smaller, swap with the smaller of those.
|
|
262
244
|
|
|
263
|
-
|
|
264
|
-
|
|
245
|
+
function siftDown(heap, node, i) {
|
|
246
|
+
var index = i;
|
|
247
|
+
var length = heap.length;
|
|
248
|
+
|
|
249
|
+
while (index < length) {
|
|
250
|
+
var leftIndex = (index + 1) * 2 - 1;
|
|
251
|
+
var left = heap[leftIndex];
|
|
252
|
+
var rightIndex = leftIndex + 1;
|
|
253
|
+
var right = heap[rightIndex]; // If the left or right node is smaller, swap with the smaller of those.
|
|
254
|
+
|
|
255
|
+
if (left !== undefined && compare(left, node) < 0) {
|
|
256
|
+
if (right !== undefined && compare(right, left) < 0) {
|
|
257
|
+
heap[index] = right;
|
|
258
|
+
heap[rightIndex] = node;
|
|
259
|
+
index = rightIndex;
|
|
260
|
+
} else {
|
|
261
|
+
heap[index] = left;
|
|
262
|
+
heap[leftIndex] = node;
|
|
263
|
+
index = leftIndex;
|
|
264
|
+
}
|
|
265
|
+
} else if (right !== undefined && compare(right, node) < 0) {
|
|
265
266
|
heap[index] = right;
|
|
266
267
|
heap[rightIndex] = node;
|
|
267
268
|
index = rightIndex;
|
|
268
269
|
} else {
|
|
269
|
-
|
|
270
|
-
heap[leftIndex] = node;
|
|
271
|
-
index = leftIndex;
|
|
272
|
-
}
|
|
273
|
-
} else if (right !== undefined && compare(right, node) < 0) {
|
|
274
|
-
heap[index] = right;
|
|
275
|
-
heap[rightIndex] = node;
|
|
276
|
-
index = rightIndex;
|
|
277
|
-
} else {
|
|
278
|
-
// Neither child is smaller. Exit.
|
|
279
|
-
return;
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
function compare(a, b) {
|
|
285
|
-
// Compare sort index first, then task id.
|
|
286
|
-
var diff = a.sortIndex - b.sortIndex;
|
|
287
|
-
return diff !== 0 ? diff : a.id - b.id;
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
// TODO: Use symbols?
|
|
291
|
-
var NoPriority = 0;
|
|
292
|
-
var ImmediatePriority = 1;
|
|
293
|
-
var UserBlockingPriority = 2;
|
|
294
|
-
var NormalPriority = 3;
|
|
295
|
-
var LowPriority = 4;
|
|
296
|
-
var IdlePriority = 5;
|
|
297
|
-
|
|
298
|
-
var runIdCounter = 0;
|
|
299
|
-
var mainThreadIdCounter = 0;
|
|
300
|
-
var profilingStateSize = 4;
|
|
301
|
-
var sharedProfilingBuffer = enableProfiling ? // $FlowFixMe Flow doesn't know about SharedArrayBuffer
|
|
302
|
-
typeof SharedArrayBuffer === 'function' ? new SharedArrayBuffer(profilingStateSize * Int32Array.BYTES_PER_ELEMENT) : // $FlowFixMe Flow doesn't know about ArrayBuffer
|
|
303
|
-
typeof ArrayBuffer === 'function' ? new ArrayBuffer(profilingStateSize * Int32Array.BYTES_PER_ELEMENT) : null // Don't crash the init path on IE9
|
|
304
|
-
: null;
|
|
305
|
-
var profilingState = enableProfiling && sharedProfilingBuffer !== null ? new Int32Array(sharedProfilingBuffer) : []; // We can't read this but it helps save bytes for null checks
|
|
306
|
-
|
|
307
|
-
var PRIORITY = 0;
|
|
308
|
-
var CURRENT_TASK_ID = 1;
|
|
309
|
-
var CURRENT_RUN_ID = 2;
|
|
310
|
-
var QUEUE_SIZE = 3;
|
|
311
|
-
|
|
312
|
-
if (enableProfiling) {
|
|
313
|
-
profilingState[PRIORITY] = NoPriority; // This is maintained with a counter, because the size of the priority queue
|
|
314
|
-
// array might include canceled tasks.
|
|
315
|
-
|
|
316
|
-
profilingState[QUEUE_SIZE] = 0;
|
|
317
|
-
profilingState[CURRENT_TASK_ID] = 0;
|
|
318
|
-
} // Bytes per element is 4
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
var INITIAL_EVENT_LOG_SIZE = 131072;
|
|
322
|
-
var MAX_EVENT_LOG_SIZE = 524288; // Equivalent to 2 megabytes
|
|
323
|
-
|
|
324
|
-
var eventLogSize = 0;
|
|
325
|
-
var eventLogBuffer = null;
|
|
326
|
-
var eventLog = null;
|
|
327
|
-
var eventLogIndex = 0;
|
|
328
|
-
var TaskStartEvent = 1;
|
|
329
|
-
var TaskCompleteEvent = 2;
|
|
330
|
-
var TaskErrorEvent = 3;
|
|
331
|
-
var TaskCancelEvent = 4;
|
|
332
|
-
var TaskRunEvent = 5;
|
|
333
|
-
var TaskYieldEvent = 6;
|
|
334
|
-
var SchedulerSuspendEvent = 7;
|
|
335
|
-
var SchedulerResumeEvent = 8;
|
|
336
|
-
|
|
337
|
-
function logEvent(entries) {
|
|
338
|
-
if (eventLog !== null) {
|
|
339
|
-
var offset = eventLogIndex;
|
|
340
|
-
eventLogIndex += entries.length;
|
|
341
|
-
|
|
342
|
-
if (eventLogIndex + 1 > eventLogSize) {
|
|
343
|
-
eventLogSize *= 2;
|
|
344
|
-
|
|
345
|
-
if (eventLogSize > MAX_EVENT_LOG_SIZE) {
|
|
346
|
-
console.error("Scheduler Profiling: Event log exceeded maximum size. Don't " + 'forget to call `stopLoggingProfilingEvents()`.');
|
|
347
|
-
stopLoggingProfilingEvents();
|
|
270
|
+
// Neither child is smaller. Exit.
|
|
348
271
|
return;
|
|
349
272
|
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
function compare(a, b) {
|
|
277
|
+
// Compare sort index first, then task id.
|
|
278
|
+
var diff = a.sortIndex - b.sortIndex;
|
|
279
|
+
return diff !== 0 ? diff : a.id - b.id;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// TODO: Use symbols?
|
|
283
|
+
var NoPriority = 0;
|
|
284
|
+
var ImmediatePriority = 1;
|
|
285
|
+
var UserBlockingPriority = 2;
|
|
286
|
+
var NormalPriority = 3;
|
|
287
|
+
var LowPriority = 4;
|
|
288
|
+
var IdlePriority = 5;
|
|
289
|
+
|
|
290
|
+
var runIdCounter = 0;
|
|
291
|
+
var mainThreadIdCounter = 0;
|
|
292
|
+
var profilingStateSize = 4;
|
|
293
|
+
var sharedProfilingBuffer = // $FlowFixMe Flow doesn't know about SharedArrayBuffer
|
|
294
|
+
typeof SharedArrayBuffer === 'function' ? new SharedArrayBuffer(profilingStateSize * Int32Array.BYTES_PER_ELEMENT) : // $FlowFixMe Flow doesn't know about ArrayBuffer
|
|
295
|
+
typeof ArrayBuffer === 'function' ? new ArrayBuffer(profilingStateSize * Int32Array.BYTES_PER_ELEMENT) : null // Don't crash the init path on IE9
|
|
296
|
+
;
|
|
297
|
+
var profilingState = sharedProfilingBuffer !== null ? new Int32Array(sharedProfilingBuffer) : []; // We can't read this but it helps save bytes for null checks
|
|
350
298
|
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
eventLog.set(entries, offset);
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
function startLoggingProfilingEvents() {
|
|
362
|
-
eventLogSize = INITIAL_EVENT_LOG_SIZE;
|
|
363
|
-
eventLogBuffer = new ArrayBuffer(eventLogSize * 4);
|
|
364
|
-
eventLog = new Int32Array(eventLogBuffer);
|
|
365
|
-
eventLogIndex = 0;
|
|
366
|
-
}
|
|
367
|
-
function stopLoggingProfilingEvents() {
|
|
368
|
-
var buffer = eventLogBuffer;
|
|
369
|
-
eventLogSize = 0;
|
|
370
|
-
eventLogBuffer = null;
|
|
371
|
-
eventLog = null;
|
|
372
|
-
eventLogIndex = 0;
|
|
373
|
-
return buffer;
|
|
374
|
-
}
|
|
375
|
-
function markTaskStart(task, time) {
|
|
376
|
-
if (enableProfiling) {
|
|
377
|
-
profilingState[QUEUE_SIZE]++;
|
|
299
|
+
var PRIORITY = 0;
|
|
300
|
+
var CURRENT_TASK_ID = 1;
|
|
301
|
+
var CURRENT_RUN_ID = 2;
|
|
302
|
+
var QUEUE_SIZE = 3;
|
|
378
303
|
|
|
304
|
+
{
|
|
305
|
+
profilingState[PRIORITY] = NoPriority; // This is maintained with a counter, because the size of the priority queue
|
|
306
|
+
// array might include canceled tasks.
|
|
307
|
+
|
|
308
|
+
profilingState[QUEUE_SIZE] = 0;
|
|
309
|
+
profilingState[CURRENT_TASK_ID] = 0;
|
|
310
|
+
} // Bytes per element is 4
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
var INITIAL_EVENT_LOG_SIZE = 131072;
|
|
314
|
+
var MAX_EVENT_LOG_SIZE = 524288; // Equivalent to 2 megabytes
|
|
315
|
+
|
|
316
|
+
var eventLogSize = 0;
|
|
317
|
+
var eventLogBuffer = null;
|
|
318
|
+
var eventLog = null;
|
|
319
|
+
var eventLogIndex = 0;
|
|
320
|
+
var TaskStartEvent = 1;
|
|
321
|
+
var TaskCompleteEvent = 2;
|
|
322
|
+
var TaskErrorEvent = 3;
|
|
323
|
+
var TaskCancelEvent = 4;
|
|
324
|
+
var TaskRunEvent = 5;
|
|
325
|
+
var TaskYieldEvent = 6;
|
|
326
|
+
var SchedulerSuspendEvent = 7;
|
|
327
|
+
var SchedulerResumeEvent = 8;
|
|
328
|
+
|
|
329
|
+
function logEvent(entries) {
|
|
379
330
|
if (eventLog !== null) {
|
|
380
|
-
|
|
331
|
+
var offset = eventLogIndex;
|
|
332
|
+
eventLogIndex += entries.length;
|
|
333
|
+
|
|
334
|
+
if (eventLogIndex + 1 > eventLogSize) {
|
|
335
|
+
eventLogSize *= 2;
|
|
336
|
+
|
|
337
|
+
if (eventLogSize > MAX_EVENT_LOG_SIZE) {
|
|
338
|
+
// Using console['error'] to evade Babel and ESLint
|
|
339
|
+
console['error']("Scheduler Profiling: Event log exceeded maximum size. Don't " + 'forget to call `stopLoggingProfilingEvents()`.');
|
|
340
|
+
stopLoggingProfilingEvents();
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
var newEventLog = new Int32Array(eventLogSize * 4);
|
|
345
|
+
newEventLog.set(eventLog);
|
|
346
|
+
eventLogBuffer = newEventLog.buffer;
|
|
347
|
+
eventLog = newEventLog;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
eventLog.set(entries, offset);
|
|
381
351
|
}
|
|
382
352
|
}
|
|
383
|
-
}
|
|
384
|
-
function markTaskCompleted(task, time) {
|
|
385
|
-
if (enableProfiling) {
|
|
386
|
-
profilingState[PRIORITY] = NoPriority;
|
|
387
|
-
profilingState[CURRENT_TASK_ID] = 0;
|
|
388
|
-
profilingState[QUEUE_SIZE]--;
|
|
389
353
|
|
|
390
|
-
|
|
391
|
-
|
|
354
|
+
function startLoggingProfilingEvents() {
|
|
355
|
+
eventLogSize = INITIAL_EVENT_LOG_SIZE;
|
|
356
|
+
eventLogBuffer = new ArrayBuffer(eventLogSize * 4);
|
|
357
|
+
eventLog = new Int32Array(eventLogBuffer);
|
|
358
|
+
eventLogIndex = 0;
|
|
359
|
+
}
|
|
360
|
+
function stopLoggingProfilingEvents() {
|
|
361
|
+
var buffer = eventLogBuffer;
|
|
362
|
+
eventLogSize = 0;
|
|
363
|
+
eventLogBuffer = null;
|
|
364
|
+
eventLog = null;
|
|
365
|
+
eventLogIndex = 0;
|
|
366
|
+
return buffer;
|
|
367
|
+
}
|
|
368
|
+
function markTaskStart(task, ms) {
|
|
369
|
+
{
|
|
370
|
+
profilingState[QUEUE_SIZE]++;
|
|
371
|
+
|
|
372
|
+
if (eventLog !== null) {
|
|
373
|
+
// performance.now returns a float, representing milliseconds. When the
|
|
374
|
+
// event is logged, it's coerced to an int. Convert to microseconds to
|
|
375
|
+
// maintain extra degrees of precision.
|
|
376
|
+
logEvent([TaskStartEvent, ms * 1000, task.id, task.priorityLevel]);
|
|
377
|
+
}
|
|
392
378
|
}
|
|
393
379
|
}
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
380
|
+
function markTaskCompleted(task, ms) {
|
|
381
|
+
{
|
|
382
|
+
profilingState[PRIORITY] = NoPriority;
|
|
383
|
+
profilingState[CURRENT_TASK_ID] = 0;
|
|
384
|
+
profilingState[QUEUE_SIZE]--;
|
|
398
385
|
|
|
399
|
-
|
|
400
|
-
|
|
386
|
+
if (eventLog !== null) {
|
|
387
|
+
logEvent([TaskCompleteEvent, ms * 1000, task.id]);
|
|
388
|
+
}
|
|
401
389
|
}
|
|
402
390
|
}
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
profilingState[PRIORITY] = NoPriority;
|
|
407
|
-
profilingState[CURRENT_TASK_ID] = 0;
|
|
408
|
-
profilingState[QUEUE_SIZE]--;
|
|
391
|
+
function markTaskCanceled(task, ms) {
|
|
392
|
+
{
|
|
393
|
+
profilingState[QUEUE_SIZE]--;
|
|
409
394
|
|
|
410
|
-
|
|
411
|
-
|
|
395
|
+
if (eventLog !== null) {
|
|
396
|
+
logEvent([TaskCancelEvent, ms * 1000, task.id]);
|
|
397
|
+
}
|
|
412
398
|
}
|
|
413
399
|
}
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
profilingState[CURRENT_TASK_ID] = task.id;
|
|
420
|
-
profilingState[CURRENT_RUN_ID] = runIdCounter;
|
|
400
|
+
function markTaskErrored(task, ms) {
|
|
401
|
+
{
|
|
402
|
+
profilingState[PRIORITY] = NoPriority;
|
|
403
|
+
profilingState[CURRENT_TASK_ID] = 0;
|
|
404
|
+
profilingState[QUEUE_SIZE]--;
|
|
421
405
|
|
|
422
|
-
|
|
423
|
-
|
|
406
|
+
if (eventLog !== null) {
|
|
407
|
+
logEvent([TaskErrorEvent, ms * 1000, task.id]);
|
|
408
|
+
}
|
|
424
409
|
}
|
|
425
410
|
}
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
411
|
+
function markTaskRun(task, ms) {
|
|
412
|
+
{
|
|
413
|
+
runIdCounter++;
|
|
414
|
+
profilingState[PRIORITY] = task.priorityLevel;
|
|
415
|
+
profilingState[CURRENT_TASK_ID] = task.id;
|
|
416
|
+
profilingState[CURRENT_RUN_ID] = runIdCounter;
|
|
432
417
|
|
|
433
|
-
|
|
434
|
-
|
|
418
|
+
if (eventLog !== null) {
|
|
419
|
+
logEvent([TaskRunEvent, ms * 1000, task.id, runIdCounter]);
|
|
420
|
+
}
|
|
435
421
|
}
|
|
436
422
|
}
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
423
|
+
function markTaskYield(task, ms) {
|
|
424
|
+
{
|
|
425
|
+
profilingState[PRIORITY] = NoPriority;
|
|
426
|
+
profilingState[CURRENT_TASK_ID] = 0;
|
|
427
|
+
profilingState[CURRENT_RUN_ID] = 0;
|
|
441
428
|
|
|
442
|
-
|
|
443
|
-
|
|
429
|
+
if (eventLog !== null) {
|
|
430
|
+
logEvent([TaskYieldEvent, ms * 1000, task.id, runIdCounter]);
|
|
431
|
+
}
|
|
444
432
|
}
|
|
445
433
|
}
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
434
|
+
function markSchedulerSuspended(ms) {
|
|
435
|
+
{
|
|
436
|
+
mainThreadIdCounter++;
|
|
437
|
+
|
|
438
|
+
if (eventLog !== null) {
|
|
439
|
+
logEvent([SchedulerSuspendEvent, ms * 1000, mainThreadIdCounter]);
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
function markSchedulerUnsuspended(ms) {
|
|
444
|
+
{
|
|
445
|
+
if (eventLog !== null) {
|
|
446
|
+
logEvent([SchedulerResumeEvent, ms * 1000, mainThreadIdCounter]);
|
|
447
|
+
}
|
|
451
448
|
}
|
|
452
449
|
}
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
/* eslint-disable no-var */
|
|
456
|
-
// Math.pow(2, 30) - 1
|
|
457
|
-
// 0b111111111111111111111111111111
|
|
458
450
|
|
|
459
|
-
|
|
451
|
+
/* eslint-disable no-var */
|
|
452
|
+
// Math.pow(2, 30) - 1
|
|
453
|
+
// 0b111111111111111111111111111111
|
|
460
454
|
|
|
461
|
-
var
|
|
455
|
+
var maxSigned31BitInt = 1073741823; // Times out immediately
|
|
462
456
|
|
|
463
|
-
var
|
|
464
|
-
var NORMAL_PRIORITY_TIMEOUT = 5000;
|
|
465
|
-
var LOW_PRIORITY_TIMEOUT = 10000; // Never times out
|
|
457
|
+
var IMMEDIATE_PRIORITY_TIMEOUT = -1; // Eventually times out
|
|
466
458
|
|
|
467
|
-
var
|
|
459
|
+
var USER_BLOCKING_PRIORITY = 250;
|
|
460
|
+
var NORMAL_PRIORITY_TIMEOUT = 5000;
|
|
461
|
+
var LOW_PRIORITY_TIMEOUT = 10000; // Never times out
|
|
468
462
|
|
|
469
|
-
var
|
|
470
|
-
var timerQueue = []; // Incrementing id counter. Used to maintain insertion order.
|
|
463
|
+
var IDLE_PRIORITY = maxSigned31BitInt; // Tasks are stored on a min heap
|
|
471
464
|
|
|
472
|
-
var
|
|
465
|
+
var taskQueue = [];
|
|
466
|
+
var timerQueue = []; // Incrementing id counter. Used to maintain insertion order.
|
|
473
467
|
|
|
474
|
-
var
|
|
475
|
-
var currentTask = null;
|
|
476
|
-
var currentPriorityLevel = NormalPriority; // This is set while performing work, to prevent re-entrancy.
|
|
468
|
+
var taskIdCounter = 1; // Pausing the scheduler is useful for debugging.
|
|
469
|
+
var currentTask = null;
|
|
470
|
+
var currentPriorityLevel = NormalPriority; // This is set while performing work, to prevent re-entrancy.
|
|
477
471
|
|
|
478
|
-
var isPerformingWork = false;
|
|
479
|
-
var isHostCallbackScheduled = false;
|
|
480
|
-
var isHostTimeoutScheduled = false;
|
|
472
|
+
var isPerformingWork = false;
|
|
473
|
+
var isHostCallbackScheduled = false;
|
|
474
|
+
var isHostTimeoutScheduled = false;
|
|
481
475
|
|
|
482
|
-
function advanceTimers(currentTime) {
|
|
483
|
-
|
|
484
|
-
|
|
476
|
+
function advanceTimers(currentTime) {
|
|
477
|
+
// Check for tasks that are no longer delayed and add them to the queue.
|
|
478
|
+
var timer = peek(timerQueue);
|
|
485
479
|
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
480
|
+
while (timer !== null) {
|
|
481
|
+
if (timer.callback === null) {
|
|
482
|
+
// Timer was cancelled.
|
|
483
|
+
pop(timerQueue);
|
|
484
|
+
} else if (timer.startTime <= currentTime) {
|
|
485
|
+
// Timer fired. Transfer to the task queue.
|
|
486
|
+
pop(timerQueue);
|
|
487
|
+
timer.sortIndex = timer.expirationTime;
|
|
488
|
+
push(taskQueue, timer);
|
|
495
489
|
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
490
|
+
{
|
|
491
|
+
markTaskStart(timer, currentTime);
|
|
492
|
+
timer.isQueued = true;
|
|
493
|
+
}
|
|
494
|
+
} else {
|
|
495
|
+
// Remaining timers are pending.
|
|
496
|
+
return;
|
|
499
497
|
}
|
|
500
|
-
} else {
|
|
501
|
-
// Remaining timers are pending.
|
|
502
|
-
return;
|
|
503
|
-
}
|
|
504
498
|
|
|
505
|
-
|
|
499
|
+
timer = peek(timerQueue);
|
|
500
|
+
}
|
|
506
501
|
}
|
|
507
|
-
}
|
|
508
502
|
|
|
509
|
-
function handleTimeout(currentTime) {
|
|
510
|
-
|
|
511
|
-
|
|
503
|
+
function handleTimeout(currentTime) {
|
|
504
|
+
isHostTimeoutScheduled = false;
|
|
505
|
+
advanceTimers(currentTime);
|
|
512
506
|
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
507
|
+
if (!isHostCallbackScheduled) {
|
|
508
|
+
if (peek(taskQueue) !== null) {
|
|
509
|
+
isHostCallbackScheduled = true;
|
|
510
|
+
requestHostCallback(flushWork);
|
|
511
|
+
} else {
|
|
512
|
+
var firstTimer = peek(timerQueue);
|
|
519
513
|
|
|
520
|
-
|
|
521
|
-
|
|
514
|
+
if (firstTimer !== null) {
|
|
515
|
+
requestHostTimeout(handleTimeout, firstTimer.startTime - currentTime);
|
|
516
|
+
}
|
|
522
517
|
}
|
|
523
518
|
}
|
|
524
519
|
}
|
|
525
|
-
}
|
|
526
520
|
|
|
527
|
-
function flushWork(hasTimeRemaining, initialTime) {
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
521
|
+
function flushWork(hasTimeRemaining, initialTime) {
|
|
522
|
+
{
|
|
523
|
+
markSchedulerUnsuspended(initialTime);
|
|
524
|
+
} // We'll need a host callback the next time work is scheduled.
|
|
531
525
|
|
|
532
526
|
|
|
533
|
-
|
|
527
|
+
isHostCallbackScheduled = false;
|
|
534
528
|
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
529
|
+
if (isHostTimeoutScheduled) {
|
|
530
|
+
// We scheduled a timeout but it's no longer needed. Cancel it.
|
|
531
|
+
isHostTimeoutScheduled = false;
|
|
532
|
+
cancelHostTimeout();
|
|
533
|
+
}
|
|
540
534
|
|
|
541
|
-
|
|
542
|
-
|
|
535
|
+
isPerformingWork = true;
|
|
536
|
+
var previousPriorityLevel = currentPriorityLevel;
|
|
543
537
|
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
538
|
+
try {
|
|
539
|
+
if (enableProfiling) {
|
|
540
|
+
try {
|
|
541
|
+
return workLoop(hasTimeRemaining, initialTime);
|
|
542
|
+
} catch (error) {
|
|
543
|
+
if (currentTask !== null) {
|
|
544
|
+
var currentTime = getCurrentTime();
|
|
545
|
+
markTaskErrored(currentTask, currentTime);
|
|
546
|
+
currentTask.isQueued = false;
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
throw error;
|
|
553
550
|
}
|
|
554
|
-
|
|
555
|
-
|
|
551
|
+
} else {
|
|
552
|
+
// No catch in prod codepath.
|
|
553
|
+
return workLoop(hasTimeRemaining, initialTime);
|
|
556
554
|
}
|
|
557
|
-
}
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
} finally {
|
|
562
|
-
currentTask = null;
|
|
563
|
-
currentPriorityLevel = previousPriorityLevel;
|
|
564
|
-
isPerformingWork = false;
|
|
555
|
+
} finally {
|
|
556
|
+
currentTask = null;
|
|
557
|
+
currentPriorityLevel = previousPriorityLevel;
|
|
558
|
+
isPerformingWork = false;
|
|
565
559
|
|
|
566
|
-
|
|
567
|
-
|
|
560
|
+
{
|
|
561
|
+
var _currentTime = getCurrentTime();
|
|
568
562
|
|
|
569
|
-
|
|
563
|
+
markSchedulerSuspended(_currentTime);
|
|
564
|
+
}
|
|
570
565
|
}
|
|
571
566
|
}
|
|
572
|
-
}
|
|
573
|
-
|
|
574
|
-
function workLoop(hasTimeRemaining, initialTime) {
|
|
575
|
-
var currentTime = initialTime;
|
|
576
|
-
advanceTimers(currentTime);
|
|
577
|
-
currentTask = peek(taskQueue);
|
|
578
|
-
|
|
579
|
-
while (currentTask !== null && !(enableSchedulerDebugging && isSchedulerPaused)) {
|
|
580
|
-
if (currentTask.expirationTime > currentTime && (!hasTimeRemaining || shouldYieldToHost())) {
|
|
581
|
-
// This currentTask hasn't expired, and we've reached the deadline.
|
|
582
|
-
break;
|
|
583
|
-
}
|
|
584
567
|
|
|
585
|
-
|
|
568
|
+
function workLoop(hasTimeRemaining, initialTime) {
|
|
569
|
+
var currentTime = initialTime;
|
|
570
|
+
advanceTimers(currentTime);
|
|
571
|
+
currentTask = peek(taskQueue);
|
|
586
572
|
|
|
587
|
-
|
|
588
|
-
currentTask.
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
var continuationCallback = callback(didUserCallbackTimeout);
|
|
593
|
-
currentTime = getCurrentTime();
|
|
573
|
+
while (currentTask !== null && !(enableSchedulerDebugging )) {
|
|
574
|
+
if (currentTask.expirationTime > currentTime && (!hasTimeRemaining || shouldYieldToHost())) {
|
|
575
|
+
// This currentTask hasn't expired, and we've reached the deadline.
|
|
576
|
+
break;
|
|
577
|
+
}
|
|
594
578
|
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
579
|
+
var callback = currentTask.callback;
|
|
580
|
+
|
|
581
|
+
if (callback !== null) {
|
|
582
|
+
currentTask.callback = null;
|
|
583
|
+
currentPriorityLevel = currentTask.priorityLevel;
|
|
584
|
+
var didUserCallbackTimeout = currentTask.expirationTime <= currentTime;
|
|
585
|
+
markTaskRun(currentTask, currentTime);
|
|
586
|
+
var continuationCallback = callback(didUserCallbackTimeout);
|
|
587
|
+
currentTime = getCurrentTime();
|
|
588
|
+
|
|
589
|
+
if (typeof continuationCallback === 'function') {
|
|
590
|
+
currentTask.callback = continuationCallback;
|
|
591
|
+
markTaskYield(currentTask, currentTime);
|
|
592
|
+
} else {
|
|
593
|
+
{
|
|
594
|
+
markTaskCompleted(currentTask, currentTime);
|
|
595
|
+
currentTask.isQueued = false;
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
if (currentTask === peek(taskQueue)) {
|
|
599
|
+
pop(taskQueue);
|
|
600
|
+
}
|
|
602
601
|
}
|
|
603
602
|
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
603
|
+
advanceTimers(currentTime);
|
|
604
|
+
} else {
|
|
605
|
+
pop(taskQueue);
|
|
607
606
|
}
|
|
608
607
|
|
|
609
|
-
|
|
610
|
-
}
|
|
611
|
-
pop(taskQueue);
|
|
612
|
-
}
|
|
608
|
+
currentTask = peek(taskQueue);
|
|
609
|
+
} // Return whether there's additional work
|
|
613
610
|
|
|
614
|
-
currentTask = peek(taskQueue);
|
|
615
|
-
} // Return whether there's additional work
|
|
616
611
|
|
|
612
|
+
if (currentTask !== null) {
|
|
613
|
+
return true;
|
|
614
|
+
} else {
|
|
615
|
+
var firstTimer = peek(timerQueue);
|
|
617
616
|
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
var firstTimer = peek(timerQueue);
|
|
617
|
+
if (firstTimer !== null) {
|
|
618
|
+
requestHostTimeout(handleTimeout, firstTimer.startTime - currentTime);
|
|
619
|
+
}
|
|
622
620
|
|
|
623
|
-
|
|
624
|
-
requestHostTimeout(handleTimeout, firstTimer.startTime - currentTime);
|
|
621
|
+
return false;
|
|
625
622
|
}
|
|
626
|
-
|
|
627
|
-
return false;
|
|
628
623
|
}
|
|
629
|
-
}
|
|
630
624
|
|
|
631
|
-
function unstable_runWithPriority(priorityLevel, eventHandler) {
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
625
|
+
function unstable_runWithPriority(priorityLevel, eventHandler) {
|
|
626
|
+
switch (priorityLevel) {
|
|
627
|
+
case ImmediatePriority:
|
|
628
|
+
case UserBlockingPriority:
|
|
629
|
+
case NormalPriority:
|
|
630
|
+
case LowPriority:
|
|
631
|
+
case IdlePriority:
|
|
632
|
+
break;
|
|
639
633
|
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
634
|
+
default:
|
|
635
|
+
priorityLevel = NormalPriority;
|
|
636
|
+
}
|
|
643
637
|
|
|
644
|
-
|
|
645
|
-
|
|
638
|
+
var previousPriorityLevel = currentPriorityLevel;
|
|
639
|
+
currentPriorityLevel = priorityLevel;
|
|
646
640
|
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
641
|
+
try {
|
|
642
|
+
return eventHandler();
|
|
643
|
+
} finally {
|
|
644
|
+
currentPriorityLevel = previousPriorityLevel;
|
|
645
|
+
}
|
|
651
646
|
}
|
|
652
|
-
}
|
|
653
|
-
|
|
654
|
-
function unstable_next(eventHandler) {
|
|
655
|
-
var priorityLevel;
|
|
656
647
|
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
case UserBlockingPriority:
|
|
660
|
-
case NormalPriority:
|
|
661
|
-
// Shift down to normal priority
|
|
662
|
-
priorityLevel = NormalPriority;
|
|
663
|
-
break;
|
|
648
|
+
function unstable_next(eventHandler) {
|
|
649
|
+
var priorityLevel;
|
|
664
650
|
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
651
|
+
switch (currentPriorityLevel) {
|
|
652
|
+
case ImmediatePriority:
|
|
653
|
+
case UserBlockingPriority:
|
|
654
|
+
case NormalPriority:
|
|
655
|
+
// Shift down to normal priority
|
|
656
|
+
priorityLevel = NormalPriority;
|
|
657
|
+
break;
|
|
670
658
|
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
} finally {
|
|
677
|
-
currentPriorityLevel = previousPriorityLevel;
|
|
678
|
-
}
|
|
679
|
-
}
|
|
659
|
+
default:
|
|
660
|
+
// Anything lower than normal priority should remain at the current level.
|
|
661
|
+
priorityLevel = currentPriorityLevel;
|
|
662
|
+
break;
|
|
663
|
+
}
|
|
680
664
|
|
|
681
|
-
function unstable_wrapCallback(callback) {
|
|
682
|
-
var parentPriorityLevel = currentPriorityLevel;
|
|
683
|
-
return function () {
|
|
684
|
-
// This is a fork of runWithPriority, inlined for performance.
|
|
685
665
|
var previousPriorityLevel = currentPriorityLevel;
|
|
686
|
-
currentPriorityLevel =
|
|
666
|
+
currentPriorityLevel = priorityLevel;
|
|
687
667
|
|
|
688
668
|
try {
|
|
689
|
-
return
|
|
669
|
+
return eventHandler();
|
|
690
670
|
} finally {
|
|
691
671
|
currentPriorityLevel = previousPriorityLevel;
|
|
692
672
|
}
|
|
693
|
-
}
|
|
694
|
-
}
|
|
673
|
+
}
|
|
695
674
|
|
|
696
|
-
function
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
675
|
+
function unstable_wrapCallback(callback) {
|
|
676
|
+
var parentPriorityLevel = currentPriorityLevel;
|
|
677
|
+
return function () {
|
|
678
|
+
// This is a fork of runWithPriority, inlined for performance.
|
|
679
|
+
var previousPriorityLevel = currentPriorityLevel;
|
|
680
|
+
currentPriorityLevel = parentPriorityLevel;
|
|
700
681
|
|
|
701
|
-
|
|
702
|
-
|
|
682
|
+
try {
|
|
683
|
+
return callback.apply(this, arguments);
|
|
684
|
+
} finally {
|
|
685
|
+
currentPriorityLevel = previousPriorityLevel;
|
|
686
|
+
}
|
|
687
|
+
};
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
function timeoutForPriorityLevel(priorityLevel) {
|
|
691
|
+
switch (priorityLevel) {
|
|
692
|
+
case ImmediatePriority:
|
|
693
|
+
return IMMEDIATE_PRIORITY_TIMEOUT;
|
|
703
694
|
|
|
704
|
-
|
|
705
|
-
|
|
695
|
+
case UserBlockingPriority:
|
|
696
|
+
return USER_BLOCKING_PRIORITY;
|
|
706
697
|
|
|
707
|
-
|
|
708
|
-
|
|
698
|
+
case IdlePriority:
|
|
699
|
+
return IDLE_PRIORITY;
|
|
709
700
|
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
701
|
+
case LowPriority:
|
|
702
|
+
return LOW_PRIORITY_TIMEOUT;
|
|
703
|
+
|
|
704
|
+
case NormalPriority:
|
|
705
|
+
default:
|
|
706
|
+
return NORMAL_PRIORITY_TIMEOUT;
|
|
707
|
+
}
|
|
713
708
|
}
|
|
714
|
-
}
|
|
715
709
|
|
|
716
|
-
function unstable_scheduleCallback(priorityLevel, callback, options) {
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
710
|
+
function unstable_scheduleCallback(priorityLevel, callback, options) {
|
|
711
|
+
var currentTime = getCurrentTime();
|
|
712
|
+
var startTime;
|
|
713
|
+
var timeout;
|
|
720
714
|
|
|
721
|
-
|
|
722
|
-
|
|
715
|
+
if (typeof options === 'object' && options !== null) {
|
|
716
|
+
var delay = options.delay;
|
|
723
717
|
|
|
724
|
-
|
|
725
|
-
|
|
718
|
+
if (typeof delay === 'number' && delay > 0) {
|
|
719
|
+
startTime = currentTime + delay;
|
|
720
|
+
} else {
|
|
721
|
+
startTime = currentTime;
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
timeout = typeof options.timeout === 'number' ? options.timeout : timeoutForPriorityLevel(priorityLevel);
|
|
726
725
|
} else {
|
|
726
|
+
timeout = timeoutForPriorityLevel(priorityLevel);
|
|
727
727
|
startTime = currentTime;
|
|
728
728
|
}
|
|
729
729
|
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
730
|
+
var expirationTime = startTime + timeout;
|
|
731
|
+
var newTask = {
|
|
732
|
+
id: taskIdCounter++,
|
|
733
|
+
callback: callback,
|
|
734
|
+
priorityLevel: priorityLevel,
|
|
735
|
+
startTime: startTime,
|
|
736
|
+
expirationTime: expirationTime,
|
|
737
|
+
sortIndex: -1
|
|
738
|
+
};
|
|
739
|
+
|
|
740
|
+
{
|
|
741
|
+
newTask.isQueued = false;
|
|
742
|
+
}
|
|
735
743
|
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
priorityLevel: priorityLevel,
|
|
741
|
-
startTime: startTime,
|
|
742
|
-
expirationTime: expirationTime,
|
|
743
|
-
sortIndex: -1
|
|
744
|
-
};
|
|
744
|
+
if (startTime > currentTime) {
|
|
745
|
+
// This is a delayed task.
|
|
746
|
+
newTask.sortIndex = startTime;
|
|
747
|
+
push(timerQueue, newTask);
|
|
745
748
|
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
+
if (peek(taskQueue) === null && newTask === peek(timerQueue)) {
|
|
750
|
+
// All tasks are delayed, and this is the task with the earliest delay.
|
|
751
|
+
if (isHostTimeoutScheduled) {
|
|
752
|
+
// Cancel an existing timeout.
|
|
753
|
+
cancelHostTimeout();
|
|
754
|
+
} else {
|
|
755
|
+
isHostTimeoutScheduled = true;
|
|
756
|
+
} // Schedule a timeout.
|
|
749
757
|
|
|
750
|
-
if (startTime > currentTime) {
|
|
751
|
-
// This is a delayed task.
|
|
752
|
-
newTask.sortIndex = startTime;
|
|
753
|
-
push(timerQueue, newTask);
|
|
754
758
|
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
} else {
|
|
761
|
-
isHostTimeoutScheduled = true;
|
|
762
|
-
} // Schedule a timeout.
|
|
759
|
+
requestHostTimeout(handleTimeout, startTime - currentTime);
|
|
760
|
+
}
|
|
761
|
+
} else {
|
|
762
|
+
newTask.sortIndex = expirationTime;
|
|
763
|
+
push(taskQueue, newTask);
|
|
763
764
|
|
|
765
|
+
{
|
|
766
|
+
markTaskStart(newTask, currentTime);
|
|
767
|
+
newTask.isQueued = true;
|
|
768
|
+
} // Schedule a host callback, if needed. If we're already performing work,
|
|
769
|
+
// wait until the next time we yield.
|
|
764
770
|
|
|
765
|
-
|
|
771
|
+
|
|
772
|
+
if (!isHostCallbackScheduled && !isPerformingWork) {
|
|
773
|
+
isHostCallbackScheduled = true;
|
|
774
|
+
requestHostCallback(flushWork);
|
|
775
|
+
}
|
|
766
776
|
}
|
|
767
|
-
} else {
|
|
768
|
-
newTask.sortIndex = expirationTime;
|
|
769
|
-
push(taskQueue, newTask);
|
|
770
777
|
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
newTask.isQueued = true;
|
|
774
|
-
} // Schedule a host callback, if needed. If we're already performing work,
|
|
775
|
-
// wait until the next time we yield.
|
|
778
|
+
return newTask;
|
|
779
|
+
}
|
|
776
780
|
|
|
781
|
+
function unstable_pauseExecution() {
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
function unstable_continueExecution() {
|
|
777
785
|
|
|
778
786
|
if (!isHostCallbackScheduled && !isPerformingWork) {
|
|
779
787
|
isHostCallbackScheduled = true;
|
|
@@ -781,87 +789,69 @@ function unstable_scheduleCallback(priorityLevel, callback, options) {
|
|
|
781
789
|
}
|
|
782
790
|
}
|
|
783
791
|
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
exports.
|
|
838
|
-
exports.
|
|
839
|
-
exports.
|
|
840
|
-
exports.
|
|
841
|
-
exports.
|
|
842
|
-
exports.
|
|
843
|
-
exports.
|
|
844
|
-
exports.
|
|
845
|
-
exports.
|
|
846
|
-
exports.
|
|
847
|
-
exports.
|
|
848
|
-
exports.unstable_IdlePriority = IdlePriority;
|
|
849
|
-
exports.unstable_LowPriority = LowPriority;
|
|
850
|
-
exports.unstable_runWithPriority = unstable_runWithPriority;
|
|
851
|
-
exports.unstable_next = unstable_next;
|
|
852
|
-
exports.unstable_scheduleCallback = unstable_scheduleCallback;
|
|
853
|
-
exports.unstable_cancelCallback = unstable_cancelCallback;
|
|
854
|
-
exports.unstable_wrapCallback = unstable_wrapCallback;
|
|
855
|
-
exports.unstable_getCurrentPriorityLevel = unstable_getCurrentPriorityLevel;
|
|
856
|
-
exports.unstable_shouldYield = unstable_shouldYield;
|
|
857
|
-
exports.unstable_requestPaint = unstable_requestPaint;
|
|
858
|
-
exports.unstable_continueExecution = unstable_continueExecution;
|
|
859
|
-
exports.unstable_pauseExecution = unstable_pauseExecution;
|
|
860
|
-
exports.unstable_getFirstCallbackNode = unstable_getFirstCallbackNode;
|
|
861
|
-
exports.unstable_now = getCurrentTime;
|
|
862
|
-
exports.unstable_forceFrameRate = forceFrameRate;
|
|
863
|
-
exports.unstable_Profiling = unstable_Profiling;
|
|
864
|
-
|
|
865
|
-
Object.defineProperty(exports, '__esModule', { value: true });
|
|
792
|
+
function unstable_getFirstCallbackNode() {
|
|
793
|
+
return peek(taskQueue);
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
function unstable_cancelCallback(task) {
|
|
797
|
+
{
|
|
798
|
+
if (task.isQueued) {
|
|
799
|
+
var currentTime = getCurrentTime();
|
|
800
|
+
markTaskCanceled(task, currentTime);
|
|
801
|
+
task.isQueued = false;
|
|
802
|
+
}
|
|
803
|
+
} // Null out the callback to indicate the task has been canceled. (Can't
|
|
804
|
+
// remove from the queue because you can't remove arbitrary nodes from an
|
|
805
|
+
// array based heap, only the first one.)
|
|
806
|
+
|
|
807
|
+
|
|
808
|
+
task.callback = null;
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
function unstable_getCurrentPriorityLevel() {
|
|
812
|
+
return currentPriorityLevel;
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
function unstable_shouldYield() {
|
|
816
|
+
var currentTime = getCurrentTime();
|
|
817
|
+
advanceTimers(currentTime);
|
|
818
|
+
var firstTask = peek(taskQueue);
|
|
819
|
+
return firstTask !== currentTask && currentTask !== null && firstTask !== null && firstTask.callback !== null && firstTask.startTime <= currentTime && firstTask.expirationTime < currentTask.expirationTime || shouldYieldToHost();
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
var unstable_requestPaint = requestPaint;
|
|
823
|
+
var unstable_Profiling = {
|
|
824
|
+
startLoggingProfilingEvents: startLoggingProfilingEvents,
|
|
825
|
+
stopLoggingProfilingEvents: stopLoggingProfilingEvents,
|
|
826
|
+
sharedProfilingBuffer: sharedProfilingBuffer
|
|
827
|
+
} ;
|
|
828
|
+
|
|
829
|
+
exports.unstable_IdlePriority = IdlePriority;
|
|
830
|
+
exports.unstable_ImmediatePriority = ImmediatePriority;
|
|
831
|
+
exports.unstable_LowPriority = LowPriority;
|
|
832
|
+
exports.unstable_NormalPriority = NormalPriority;
|
|
833
|
+
exports.unstable_Profiling = unstable_Profiling;
|
|
834
|
+
exports.unstable_UserBlockingPriority = UserBlockingPriority;
|
|
835
|
+
exports.unstable_advanceTime = unstable_advanceTime;
|
|
836
|
+
exports.unstable_cancelCallback = unstable_cancelCallback;
|
|
837
|
+
exports.unstable_clearYields = unstable_clearYields;
|
|
838
|
+
exports.unstable_continueExecution = unstable_continueExecution;
|
|
839
|
+
exports.unstable_flushAll = unstable_flushAll;
|
|
840
|
+
exports.unstable_flushAllWithoutAsserting = unstable_flushAllWithoutAsserting;
|
|
841
|
+
exports.unstable_flushExpired = unstable_flushExpired;
|
|
842
|
+
exports.unstable_flushNumberOfYields = unstable_flushNumberOfYields;
|
|
843
|
+
exports.unstable_flushUntilNextPaint = unstable_flushUntilNextPaint;
|
|
844
|
+
exports.unstable_forceFrameRate = forceFrameRate;
|
|
845
|
+
exports.unstable_getCurrentPriorityLevel = unstable_getCurrentPriorityLevel;
|
|
846
|
+
exports.unstable_getFirstCallbackNode = unstable_getFirstCallbackNode;
|
|
847
|
+
exports.unstable_next = unstable_next;
|
|
848
|
+
exports.unstable_now = getCurrentTime;
|
|
849
|
+
exports.unstable_pauseExecution = unstable_pauseExecution;
|
|
850
|
+
exports.unstable_requestPaint = unstable_requestPaint;
|
|
851
|
+
exports.unstable_runWithPriority = unstable_runWithPriority;
|
|
852
|
+
exports.unstable_scheduleCallback = unstable_scheduleCallback;
|
|
853
|
+
exports.unstable_shouldYield = unstable_shouldYield;
|
|
854
|
+
exports.unstable_wrapCallback = unstable_wrapCallback;
|
|
855
|
+
exports.unstable_yieldValue = unstable_yieldValue;
|
|
866
856
|
|
|
867
857
|
})));
|