1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 | 'use strict';
|
11 |
|
12 | var ReactFiberBeginWork = require('./ReactFiberBeginWork');
|
13 | var ReactFiberCompleteWork = require('./ReactFiberCompleteWork');
|
14 | var ReactFiberCommitWork = require('./ReactFiberCommitWork');
|
15 |
|
16 | var _require = require('./ReactFiber'),
|
17 | cloneFiber = _require.cloneFiber;
|
18 |
|
19 | var _require2 = require('./ReactPriorityLevel'),
|
20 | NoWork = _require2.NoWork,
|
21 | LowPriority = _require2.LowPriority,
|
22 | AnimationPriority = _require2.AnimationPriority,
|
23 | SynchronousPriority = _require2.SynchronousPriority;
|
24 |
|
25 | var timeHeuristicForUnitOfWork = 1;
|
26 |
|
27 | module.exports = function (config) {
|
28 |
|
29 |
|
30 | var scheduler = void 0;
|
31 | function getScheduler() {
|
32 | return scheduler;
|
33 | }
|
34 |
|
35 | var _ReactFiberBeginWork = ReactFiberBeginWork(config, getScheduler),
|
36 | beginWork = _ReactFiberBeginWork.beginWork;
|
37 |
|
38 | var _ReactFiberCompleteWo = ReactFiberCompleteWork(config),
|
39 | completeWork = _ReactFiberCompleteWo.completeWork;
|
40 |
|
41 | var _ReactFiberCommitWork = ReactFiberCommitWork(config),
|
42 | commitWork = _ReactFiberCommitWork.commitWork;
|
43 |
|
44 | var scheduleAnimationCallback = config.scheduleAnimationCallback;
|
45 | var scheduleDeferredCallback = config.scheduleDeferredCallback;
|
46 |
|
47 |
|
48 | var defaultPriority = LowPriority;
|
49 |
|
50 |
|
51 | var nextUnitOfWork = null;
|
52 | var nextPriorityLevel = NoWork;
|
53 |
|
54 |
|
55 | var nextScheduledRoot = null;
|
56 | var lastScheduledRoot = null;
|
57 |
|
58 | function findNextUnitOfWork() {
|
59 |
|
60 | while (nextScheduledRoot && nextScheduledRoot.current.pendingWorkPriority === NoWork) {
|
61 | nextScheduledRoot.isScheduled = false;
|
62 | if (nextScheduledRoot === lastScheduledRoot) {
|
63 | nextScheduledRoot = null;
|
64 | lastScheduledRoot = null;
|
65 | nextPriorityLevel = NoWork;
|
66 | return null;
|
67 | }
|
68 | nextScheduledRoot = nextScheduledRoot.nextScheduledRoot;
|
69 | }
|
70 |
|
71 |
|
72 | var root = nextScheduledRoot;
|
73 | var highestPriorityRoot = null;
|
74 | var highestPriorityLevel = NoWork;
|
75 | while (root) {
|
76 | if (highestPriorityLevel === NoWork || highestPriorityLevel > root.current.pendingWorkPriority) {
|
77 | highestPriorityLevel = root.current.pendingWorkPriority;
|
78 | highestPriorityRoot = root;
|
79 | }
|
80 |
|
81 | root = root.nextScheduledRoot;
|
82 | }
|
83 | if (highestPriorityRoot) {
|
84 | nextPriorityLevel = highestPriorityLevel;
|
85 | return cloneFiber(highestPriorityRoot.current, highestPriorityLevel);
|
86 | }
|
87 |
|
88 | nextPriorityLevel = NoWork;
|
89 | return null;
|
90 | }
|
91 |
|
92 | function commitAllWork(finishedWork) {
|
93 |
|
94 |
|
95 | var effectfulFiber = finishedWork.firstEffect;
|
96 | while (effectfulFiber) {
|
97 | var current = effectfulFiber.alternate;
|
98 | commitWork(current, effectfulFiber);
|
99 | var next = effectfulFiber.nextEffect;
|
100 |
|
101 |
|
102 |
|
103 |
|
104 | effectfulFiber.nextEffect = null;
|
105 | effectfulFiber = next;
|
106 | }
|
107 | }
|
108 |
|
109 | function resetWorkPriority(workInProgress) {
|
110 | var newPriority = NoWork;
|
111 |
|
112 |
|
113 |
|
114 | var child = workInProgress.progressedChild;
|
115 | while (child) {
|
116 |
|
117 | if (child.pendingWorkPriority !== NoWork && (newPriority === NoWork || newPriority > child.pendingWorkPriority)) {
|
118 | newPriority = child.pendingWorkPriority;
|
119 | }
|
120 | child = child.sibling;
|
121 | }
|
122 | workInProgress.pendingWorkPriority = newPriority;
|
123 | }
|
124 |
|
125 | function completeUnitOfWork(workInProgress) {
|
126 | while (true) {
|
127 |
|
128 |
|
129 |
|
130 |
|
131 | var current = workInProgress.alternate;
|
132 | var next = completeWork(current, workInProgress);
|
133 |
|
134 | resetWorkPriority(workInProgress);
|
135 |
|
136 |
|
137 |
|
138 | workInProgress.pendingProps = null;
|
139 | workInProgress.updateQueue = null;
|
140 |
|
141 | var returnFiber = workInProgress['return'];
|
142 |
|
143 | if (returnFiber) {
|
144 |
|
145 |
|
146 |
|
147 | if (!returnFiber.firstEffect) {
|
148 | returnFiber.firstEffect = workInProgress.firstEffect;
|
149 | }
|
150 | if (workInProgress.lastEffect) {
|
151 | if (returnFiber.lastEffect) {
|
152 | returnFiber.lastEffect.nextEffect = workInProgress.firstEffect;
|
153 | }
|
154 | returnFiber.lastEffect = workInProgress.lastEffect;
|
155 | }
|
156 | }
|
157 |
|
158 | if (next) {
|
159 |
|
160 | return next;
|
161 | } else if (workInProgress.sibling) {
|
162 |
|
163 | return workInProgress.sibling;
|
164 | } else if (returnFiber) {
|
165 |
|
166 | workInProgress = returnFiber;
|
167 | continue;
|
168 | } else {
|
169 |
|
170 | var _root = workInProgress.stateNode;
|
171 | if (_root.current === workInProgress) {
|
172 | throw new Error('Cannot commit the same tree as before. This is probably a bug ' + 'related to the return field.');
|
173 | }
|
174 | _root.current = workInProgress;
|
175 |
|
176 |
|
177 |
|
178 |
|
179 | commitAllWork(workInProgress);
|
180 | var nextWork = findNextUnitOfWork();
|
181 |
|
182 |
|
183 |
|
184 |
|
185 |
|
186 |
|
187 |
|
188 | return nextWork;
|
189 | }
|
190 | }
|
191 | }
|
192 |
|
193 | function performUnitOfWork(workInProgress) {
|
194 |
|
195 |
|
196 |
|
197 |
|
198 | var current = workInProgress.alternate;
|
199 | var next = beginWork(current, workInProgress, nextPriorityLevel);
|
200 |
|
201 | if (next) {
|
202 |
|
203 | return next;
|
204 | } else {
|
205 |
|
206 | return completeUnitOfWork(workInProgress);
|
207 | }
|
208 | }
|
209 |
|
210 | function performDeferredWork(deadline) {
|
211 | if (!nextUnitOfWork) {
|
212 | nextUnitOfWork = findNextUnitOfWork();
|
213 | }
|
214 | while (nextUnitOfWork) {
|
215 | if (deadline.timeRemaining() > timeHeuristicForUnitOfWork) {
|
216 | nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
|
217 | if (!nextUnitOfWork) {
|
218 |
|
219 | nextUnitOfWork = findNextUnitOfWork();
|
220 | }
|
221 | } else {
|
222 | scheduleDeferredCallback(performDeferredWork);
|
223 | return;
|
224 | }
|
225 | }
|
226 | }
|
227 |
|
228 | function scheduleDeferredWork(root, priority) {
|
229 |
|
230 |
|
231 |
|
232 | if (priority <= nextPriorityLevel) {
|
233 | nextUnitOfWork = null;
|
234 | }
|
235 |
|
236 |
|
237 | if (root.current.pendingWorkPriority === NoWork || priority <= root.current.pendingWorkPriority) {
|
238 | root.current.pendingWorkPriority = priority;
|
239 | }
|
240 |
|
241 | if (root.isScheduled) {
|
242 |
|
243 | return;
|
244 | }
|
245 | root.isScheduled = true;
|
246 | if (lastScheduledRoot) {
|
247 |
|
248 | lastScheduledRoot.nextScheduledRoot = root;
|
249 | lastScheduledRoot = root;
|
250 | } else {
|
251 |
|
252 | nextScheduledRoot = root;
|
253 | lastScheduledRoot = root;
|
254 | scheduleDeferredCallback(performDeferredWork);
|
255 | }
|
256 | }
|
257 |
|
258 | function performAnimationWork() {
|
259 |
|
260 | nextUnitOfWork = findNextUnitOfWork();
|
261 | while (nextUnitOfWork && nextPriorityLevel !== NoWork) {
|
262 | nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
|
263 | if (!nextUnitOfWork) {
|
264 |
|
265 | nextUnitOfWork = findNextUnitOfWork();
|
266 | }
|
267 |
|
268 | if (nextPriorityLevel > AnimationPriority) {
|
269 | scheduleDeferredCallback(performDeferredWork);
|
270 | return;
|
271 | }
|
272 | }
|
273 | }
|
274 |
|
275 | function scheduleAnimationWork(root, priorityLevel) {
|
276 |
|
277 | if (root.current.pendingWorkPriority === NoWork || priorityLevel <= root.current.pendingWorkPriority) {
|
278 | root.current.pendingWorkPriority = priorityLevel;
|
279 | }
|
280 |
|
281 | if (root.isScheduled) {
|
282 |
|
283 | return;
|
284 | }
|
285 | root.isScheduled = true;
|
286 | if (lastScheduledRoot) {
|
287 |
|
288 | lastScheduledRoot.nextScheduledRoot = root;
|
289 | lastScheduledRoot = root;
|
290 | } else {
|
291 |
|
292 | nextScheduledRoot = root;
|
293 | lastScheduledRoot = root;
|
294 | scheduleAnimationCallback(performAnimationWork);
|
295 | }
|
296 | }
|
297 |
|
298 | function scheduleWork(root) {
|
299 | if (defaultPriority === SynchronousPriority) {
|
300 | throw new Error('Not implemented yet');
|
301 | }
|
302 |
|
303 | if (defaultPriority === NoWork) {
|
304 | return;
|
305 | }
|
306 | if (defaultPriority > AnimationPriority) {
|
307 | scheduleDeferredWork(root, defaultPriority);
|
308 | return;
|
309 | }
|
310 | scheduleAnimationWork(root, defaultPriority);
|
311 | }
|
312 |
|
313 | function performWithPriority(priorityLevel, fn) {
|
314 | var previousDefaultPriority = defaultPriority;
|
315 | defaultPriority = priorityLevel;
|
316 | try {
|
317 | fn();
|
318 | } finally {
|
319 | defaultPriority = previousDefaultPriority;
|
320 | }
|
321 | }
|
322 |
|
323 | scheduler = {
|
324 | scheduleWork: scheduleWork,
|
325 | scheduleDeferredWork: scheduleDeferredWork,
|
326 | performWithPriority: performWithPriority
|
327 | };
|
328 | return scheduler;
|
329 | }; |
\ | No newline at end of file |