(root: FiberRoot, renderLanes: Lanes)
| 421 | } |
| 422 | |
| 423 | export function getEntangledLanes(root: FiberRoot, renderLanes: Lanes): Lanes { |
| 424 | let entangledLanes = renderLanes; |
| 425 | |
| 426 | if ((entangledLanes & InputContinuousLane) !== NoLanes) { |
| 427 | // When updates are sync by default, we entangle continuous priority updates |
| 428 | // and default updates, so they render in the same batch. The only reason |
| 429 | // they use separate lanes is because continuous updates should interrupt |
| 430 | // transitions, but default updates should not. |
| 431 | entangledLanes |= entangledLanes & DefaultLane; |
| 432 | } |
| 433 | |
| 434 | // Check for entangled lanes and add them to the batch. |
| 435 | // |
| 436 | // A lane is said to be entangled with another when it's not allowed to render |
| 437 | // in a batch that does not also include the other lane. Typically we do this |
| 438 | // when multiple updates have the same source, and we only want to respond to |
| 439 | // the most recent event from that source. |
| 440 | // |
| 441 | // Note that we apply entanglements *after* checking for partial work above. |
| 442 | // This means that if a lane is entangled during an interleaved event while |
| 443 | // it's already rendering, we won't interrupt it. This is intentional, since |
| 444 | // entanglement is usually "best effort": we'll try our best to render the |
| 445 | // lanes in the same batch, but it's not worth throwing out partially |
| 446 | // completed work in order to do it. |
| 447 | // TODO: Reconsider this. The counter-argument is that the partial work |
| 448 | // represents an intermediate state, which we don't want to show to the user. |
| 449 | // And by spending extra time finishing it, we're increasing the amount of |
| 450 | // time it takes to show the final state, which is what they are actually |
| 451 | // waiting for. |
| 452 | // |
| 453 | // For those exceptions where entanglement is semantically important, |
| 454 | // we should ensure that there is no partial work at the |
| 455 | // time we apply the entanglement. |
| 456 | const allEntangledLanes = root.entangledLanes; |
| 457 | if (allEntangledLanes !== NoLanes) { |
| 458 | const entanglements = root.entanglements; |
| 459 | let lanes = entangledLanes & allEntangledLanes; |
| 460 | while (lanes > 0) { |
| 461 | const index = pickArbitraryLaneIndex(lanes); |
| 462 | const lane = 1 << index; |
| 463 | |
| 464 | entangledLanes |= entanglements[index]; |
| 465 | |
| 466 | lanes &= ~lane; |
| 467 | } |
| 468 | } |
| 469 | |
| 470 | return entangledLanes; |
| 471 | } |
| 472 | |
| 473 | function computeExpirationTime(lane: Lane, currentTime: number) { |
| 474 | switch (lane) { |
no test coverage detected