Commit Graph

19 Commits

Author SHA1 Message Date
Samuel Susla 51af7cdcde Use nested namespace name
Summary:
changelog: [internal]

Enable two new clang tidy checks:
- modernize-concat-nested-namespaces
- google-build-using-namespace

jest_e2e[run_all_tests]

Reviewed By: rshest

Differential Revision: D40020646

fbshipit-source-id: f3be80b5f829dd0ba376bdd70ed13332e114d48a
2022-10-13 05:07:59 -07:00
Pieter De Baets 13a0556aaa Remove deprecated ShadowNode type aliases
Summary:
Fix todo and inconsistency across codebase. It's better to have just one way to refer to these types.

Changelog: [Internal]

Reviewed By: philIip

Differential Revision: D37653146

fbshipit-source-id: e82f09caa6cd6eec5512b78f413708d9c04a7a83
2022-07-12 04:37:32 -07:00
Andres Suarez 8bd3edec88 Update copyright headers from Facebook to Meta
Reviewed By: aaronabramov

Differential Revision: D33367752

fbshipit-source-id: 4ce94d184485e5ee0a62cf67ad2d3ba16e285c8f
2021-12-30 15:11:21 -08:00
Joshua Gross 175b1ea636 Pass PropsParserContext to prop parsing layer
Summary: Changelog: [internal]

Reviewed By: mdvacca

Differential Revision: D29921232

fbshipit-source-id: ba045f545b564aedf1b287045a0e75428de30a0f
2021-07-28 20:18:20 -07:00
Joshua Gross 7d1d4dc064 Ship new C++ Differ in code
Summary:
The new C++ Differ has been validated on Android and iOS. Delete the old code path.

Changelog: [Internal]

Reviewed By: sammy-SC

Differential Revision: D28904330

fbshipit-source-id: 2e0d8682f6b2a79f9758ed8b7b92809060835815
2021-06-07 17:11:55 -07:00
Joshua Gross 967eeff86e Add unit tests for Layout Animations
Summary:
Add unit tests for Layout Animations.

This first batch generates a random mutation, then animates it to completion.

I found one issue with UPDATE+REMOVE+INSERT animation consistency. That shouldn't cause any crashes in production, but is a chance to improve consistency of mutations overall - and could in theory point to memory corruption, though it's somewhat unlikely.

I ran with randomized seeds, found issues, fixed them, re-ran to ensure issues were fixed, rinsed and repeated. At the end I was able to run dozens of times (with random seeds) and found nothing.

The next step is to repeatedly generate mutations that conflict with ongoing animations.

Changelog: [Internal]

Reviewed By: sammy-SC

Differential Revision: D28343750

fbshipit-source-id: c1c60d89a31be3ac05d57482f0af3c482b866abe
2021-05-11 12:11:35 -07:00
Joshua Gross 3a99c7cdbb Differ: add failing test case 1167342011 which covers an existing error
Summary:
Found by running random tests and extracting a failing seed.

This error existed in master (and existed prior to recent refactors) and will be fixed by the end of this stack.

Changelog: [Internal]

Reviewed By: sammy-SC

Differential Revision: D28003332

fbshipit-source-id: 9c4a10d236c24337b089c44e8c1beb22358cfb05
2021-04-26 11:59:10 -07:00
Joshua Gross 1b4a5176d7 Testing mechanism to find new failing Differ test-cases
Summary:
This code can be uncommented locally and run several times to discover new failing seeds.

Changelog: [Internal]

Reviewed By: sammy-SC

Differential Revision: D28003333

fbshipit-source-id: 6a3b6c08ae02bccc5c4d26067409ff6c736f8a89
2021-04-26 11:59:10 -07:00
Joshua Gross 66ba89921a Differ tests: use react_native_assert(false) instead of FAIL() to get logs upon test failure
Summary:
Calling `FAIL()` doesn't flush glog, but `react_native_assert(false)` does. Both will have the effect of failing the test.

Changelog: [Internal]

Reviewed By: sammy-SC

Differential Revision: D28003334

fbshipit-source-id: 802ad1f59e46eb048fd6ca95f5978eeaaad83f3a
2021-04-26 11:59:10 -07:00
Joshua Gross dc80b2dcb5 Add mounting layer test that stress-tests differ on (un)flattening
Summary:
Add mounting layer test that stress-tests differ on (un)flattening.

This fails before D27759380 and D27730952, and passes after.

Changelog: [Internal]

Reviewed By: mdvacca

Differential Revision: D27767219

fbshipit-source-id: a7e186e510f95792da6f98f80fcae5ff8ac74775
2021-04-14 19:50:10 -07:00
Joshua Gross 39b8233c93 Copy Differ implementation to new file, feature-flag-gate new differ
Summary:
Changes in following diffs will be gated by this feature flag.

The differ in the new file is copied from the current stable implementation and will not be modified until it's deleted.

Changelog: [Internal]

Reviewed By: sammy-SC, mdvacca

Differential Revision: D27775698

fbshipit-source-id: 03d9518ffd2b1f25712386c56a38bd2b4d839fc2
2021-04-14 19:50:09 -07:00
Joshua Gross 248704e8de Rename unit tests to match filenames
Summary:
Rename tests to match filenames so results appear correctly in console.

Changelog: [internal]

Reviewed By: PeteTheHeat

Differential Revision: D26306214

fbshipit-source-id: 58ce5ee0f5df5d7da38da8a2653a042ab7c26bb2
2021-02-09 22:43:44 -08:00
Andres Suarez 0f4f917663 Apply clang-format update fixes
Reviewed By: igorsugak

Differential Revision: D25861683

fbshipit-source-id: 616afca13ae64c76421053ce49286035e0687e36
2021-01-09 22:11:00 -08:00
Valentin Shergin 9a720ad47f Fabric: buildStubViewTreeWithoutUsingDifferentiator & buildStubViewTreeUsingDifferentiator
Summary:
After fixing `calculateShadowViewMutationsForNewTree` I realized that it will be even better to test Stacking Context and mutation instructions infra using both functions: `calculateShadowViewMutationsForNewTree` (used for testing) and the Differentiator itself. This diff implements it.

Now we have two similarly working functions with different implementations that we can use for testing Differentiator and other parts of the infra.

Changelog: [Internal] Fabric-specific internal change.

Reviewed By: sammy-SC

Differential Revision: D25576922

fbshipit-source-id: 7922e9ebfb9d6ef1792566554ba0c4a14f835ae2
2020-12-16 10:57:37 -08:00
Joshua Gross 6864e5f3ac Ship reparenting differ everywhere on iOS and Android
Summary:
The "reparenting differ" has been the default differ for several months; ship it by removing config and the old differ.

Some functions can't be deleted yet because unit testing relies on it heavily; this can be refactored in the future if we care a lot.

Changelog: [Internal]

Reviewed By: mdvacca

Differential Revision: D25257205

fbshipit-source-id: 6f1dcc490bb1efe3d12506addf5f0843ca48c5c6
2020-12-01 19:52:44 -08:00
generatedunixname89002005287564 3f85b83653 Daily arc lint --take CLANGFORMAT
Reviewed By: zertosh

Differential Revision: D23811656

fbshipit-source-id: 4104948d2e4db786998320bcfdb1598d4a497f2d
2020-09-21 04:38:18 -07:00
Joshua Gross 752e709b51 Additional differ test: flattening differ should not produce DELETE and CREATE mutation for the same tag in the same frame
Summary:
See additional assertion. Tests still pass, so no other change was necessary.

Changelog: [Internal]

Differential Revision: D23775553

fbshipit-source-id: 57d3191f25dd55ab4da189207f6d201a31b175e0
2020-09-18 16:38:33 -07:00
Joshua Gross 92091b8b31 New Flattening Differ
Summary:
# What is this?

For a very long time, we've discussed the possibility of detecting Node Reparenting in the Fabric Differ. Practically, from the developer perspective, ReactJS and React Native do not allow reparenting: nodes cannot be reparented, only deleted and then recreated with entirely new tags.

However, Fabric introduced the idea of View Flattening where views deemed unnecessary would be removed from the View hierarchy entirely. This is great and improves memory usage, except for one issue: if a View becomes unflattened, or becomes flattened, the entire tree underneath it must be rebuilt.

In a past diff we introduced a mechanism to detect sibling reordering cleverly, and produce a minimal instruction set. This diff is very similar: we know the invariants around flattening and unflattening of views and we take advantage of them to produce an optimal set of instructions efficiently.

# What's different from previous attempts?

No global maps! Those are slow!

This seems to work and (hopefully) might even improve performance, since way less work is being done on the UI thread in cases when views are (un)flattened.

This *only* does extra work when flattening/unflattening happens, which gives product engineers a little more control over perf.

# So, how's it work?

This algorithm is intuitively simple (I think) but tricky to pull off, because there are lots of edge-cases.

In short: In the past, that information was hidden from the Differ: the differ didn't know if views were being reparented, it would see them
as entirely new views or as views being deleted if a View was flattened or unflattened. We very subtly change the information given to the differ:
all nodes are visible to the differ, but marked as Flattened or Unflattened. Thus, when the differ compares two nodes in the "old" and "new" tree,
it can tell not just if there are updates to the node but if it has been unflattened or flattened as well.

For example, take this tree, where * indicates that a View is flattened:

```
         A
         +
    +----+---+
    B*       X
    +        +
    |        |
+---+--+     +
E      F     Y
```

When the Differ asks for the children of A, in the past it would get a list `[E, F, X]`. That is, B* and X are both its children, but since B is flattened, it is omitted entirely from the list and
its children are substituted.

Now, when the Differ asks for the children of A, we give it this list instead: `[B*, E, F, X]`. That is: we give it a list which includes B, but B is marked as flattened.

Another wrinkle: A node `X` could have its children flattened, but still be a concrete view: so flattening/unflattening is a different operation from making a view "concrete" or "unconcrete", which can change independently of flattening.

There is one additional wrinkle: because of zIndex/stacking order, the children of `B` might not actually appear after `B` in the list. Depending on zIndex, a tree that looks like this:

```
          A
          +
   +------+------+
   B*            C*
   +             +
   |             |
+--+--+       +--+--+
D     E       F     G
```

Could actually be linearized as: `[D G B* F C* E]` (as an extreme example; but basically all permutations as possible).

This is the reason, and the *only* reason that the inner Flattener/Unflattener

## The cases we need to handle

There are 7 cases/edge-cases of flattening and unflattening that we need to handle. Practically, all cases of reordering + flattening/unflattening, and taking recursive cases into account:

1. View A and A' (A in the old tree, A' in the new tree) are matched in the differ, and A* has been flattened or unflattened. These two cases are the easiest to handle.
2. View A' has been reordered with its siblings, and has been flattened or unflattened. These cases are slightly trickier to handle.
3. While flattening or unflattening, we encounter a child that has also been unflattened or flattened. So we need to handle four cases here in total: Flatten-Flatten, Flatten-Unflatten, Unflatten-Flatten, and Unflatten-Unflatten.

Other things to think about, also covered above:

1. Ordering. Views can be reordered and flattened/unflattened at the same time.
2. zIndex ordering: children in a certain order from the ShadowNode perspective may be stacked differently from a View perspective. We use the zIndex ordering for everything in the differ, and this prevents us from performing certain optimizations (see above: we cannot assume that children come after their parent in a list; they may come before, may be interwoven with children from other parents, etc).

# Perf Implications?

Practically, there should be very little negative overhead. There is some overhead in actually performing a flattening/unflattening operation, but... not much more than before. We don't use global maps, so the cost of flattening/unflattening is basically `O(number of nodes reparented)` - note that that's direct nodes reparented, *not* descendants.

tl;dr the perf hit should be similar to reordering, which is non-zero, but close to zero, and zero-cost for any diff operations on parts of the tree that don't involve flattening/unflattening. AFAICT this is very close to an ideal solution for that reason (but I wish it was simpler overall).

# In Summary?

I hope this works out and I think it could improve a number of things downstream: perf, LayoutAnimations, Bindings, certain crashes because of platform assumptions about mutations, etc.

Is it worth it? This new implementation is substantially harder to reason about, harder to read, and harder to understand. This is an important consideration. All I can say there is that I trust the test suite I've been using, but
the decreased readability is a big negative. Hopefully we can improve this in the future.

The rest is fiddly implementation details that I sincerely hope can be improved and simplified in the future.

# Followups?

The part that makes this algorithm the most expensive is that because of zIndex ordering, we cannot assume that children are linearized after their parents and so we rely more heavily on maps for the flattening/unflattening. Our TinyMap implementation should make these `find` operations fast enough unless trees' children are constantly being reordered, but it's still worth thinking of ways to make this even faster.

Changelog: [Internal]

Reviewed By: shergin, mdvacca

Differential Revision: D23259341

fbshipit-source-id: 35d9b90caf262d601a31996ea2cb37e329c61ffc
2020-08-24 13:09:12 -07:00
David Vacca 3093010ea5 move fabric to ReactCommon/react/renderer
Summary:
This diff moves fabric C++ code from ReactCommon/fabric to ReactCommon/react/renderer
As part of this diff I also refactored components, codegen and callsites on CatalystApp, FB4A and venice

Script: P137350694

changelog: [internal] internal refactor

Reviewed By: fkgozali

Differential Revision: D22852139

fbshipit-source-id: f85310ba858b6afd81abfd9cbe6d70b28eca7415
2020-07-31 13:34:29 -07:00