Skip to content

Commit

Permalink
LayoutAnimations: fix index consistency crash
Browse files Browse the repository at this point in the history
Summary:
Unfortunately LayoutAnimations index adjustment is a bit tricky. There was one (hopefully only one!) remaining issue where a specific series of delayed removes, inserts, and removes would trip up index adjustment. Namely in this case: Preexisting delayed removes, and then a later animated commit with immediate inserts followed by higher-index removes.

This case is now resolved and I took time to test and verify other index adjustment paths.

Changelog: [Internal]

Reviewed By: mdvacca

Differential Revision: D22709915

fbshipit-source-id: 16ba5bb358608d384f44628dbb6cc691deb8164a
  • Loading branch information
JoshuaGross authored and facebook-github-bot committed Jul 24, 2020
1 parent 9d3cefb commit c38b506
Showing 1 changed file with 14 additions and 5 deletions.
19 changes: 14 additions & 5 deletions ReactCommon/fabric/animations/LayoutAnimationKeyFrameManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -600,7 +600,7 @@ LayoutAnimationKeyFrameManager::pullTransaction(
mutation.type == ShadowViewMutation::Type::Insert) {
// Indices for immediate INSERT mutations must be adjusted to insert
// at higher indices if previous animations have deferred removals
// before the insertion indect
// before the insertion index
// TODO: refactor to reduce code duplication
if (mutation.type == ShadowViewMutation::Type::Insert) {
int adjustedIndex = mutation.index;
Expand Down Expand Up @@ -766,12 +766,14 @@ LayoutAnimationKeyFrameManager::pullTransaction(
// tree hierarchy).
{
int adjustedIndex = mutation.index;
int adjustment = 0;
for (auto &otherMutation : mutations) {
if (otherMutation.type == ShadowViewMutation::Type::Insert &&
otherMutation.parentShadowView.tag == parentTag) {
if (otherMutation.index <= adjustedIndex &&
!mutatedViewIsVirtual(otherMutation)) {
otherMutation.parentShadowView.tag == parentTag &&
!mutatedViewIsVirtual(otherMutation)) {
if (otherMutation.index <= adjustedIndex) {
adjustedIndex++;
adjustment++;
} else {
// If we are delaying this remove instruction, conversely,
// we must adjust upward the insertion index of any INSERT
Expand Down Expand Up @@ -802,9 +804,16 @@ LayoutAnimationKeyFrameManager::pullTransaction(
}
const auto &delayedFinalMutation =
*animatedKeyFrame.finalMutationForKeyFrame;

// Note: we add the "adjustment" we've accumulated to the
// `delayedFinalMutation.index` before comparing. Since
// "adjustment" is caused by Insert MountItems that we are
// about to execute, but haven't yet, the delayed mutation's
// index *will* be adjusted right after this.
if (delayedFinalMutation.type ==
ShadowViewMutation::Type::Remove &&
delayedFinalMutation.index <= adjustedIndex) {
(delayedFinalMutation.index + adjustment) <=
adjustedIndex) {
adjustedIndex++;
}
}
Expand Down

0 comments on commit c38b506

Please sign in to comment.