Summary:
Each ComponentDescriptor becomes capable of doing its own interpolation over props for animation purposes.
This new custom interpolator is called by default by the ConcreteComponentDescriptor, but `ComponentDescriptor::interpolateProps` is a virtual function and each ComponentDescriptor can provide custom interpolation if necessary.
For now, only View does any actual interpolation, to support LayoutAnimations.
Changelog: [Internal]
Reviewed By: mdvacca
Differential Revision: D20965310
fbshipit-source-id: e1c1588107848e94c155efecb0da1cc1619ae544
Summary:
Move and create an empty rule that redirects as well, to handle //arvr rules
Need to do this way, since ovrsource sync rules are in different repo.
allow_many_files
allow-large-files
Steps:
- [X] Move glog from xplat/third-party to /third-party
- [ ] Update references in ovrsource to translate to //third-party instead of //xplat/third-party
- [ ] Get rid of temporary rule
- [ ] Update fbsource/third-party/glog to 0.3.5 (what we have in ovrsource)
Changelog: [Internal] Update reference for glog from xplat/third-party to /third-party.
Reviewed By: yfeldblum
Differential Revision: D21363584
fbshipit-source-id: c1ffe2dd615077170b03d98dcfb77121537793c9
Summary:
I spent the last several days thinking about state reconciliation issues, some crashes (T65586949) that suspiciously happen somewhere inside, and a bunch of issues that might be connected to that (possibly, some of T65516263 sub-task).
I cannot see some obvious problems in the current state reconciliation algorithm that might cause the crash (because of some use-after-free or other pure C++ issues), but I suspect some of the problems we experience might be caused by some details of how we reconcile states.
In the current approach, we rank all states based on the "hierarchical" history of their creation (state version is being calculated based on the version of the base tree). That's usually fine but in some cases when trees are being constructed concurrently, a logical version of a based tree does not correspond to the local version of a committed tree. In other words, the linear history of commits does not always correspond to the "hierarchical" history of trees generation that was done by different parties (e.g. React vs native state update pipeline).
In this diff, I tried to change the approach to change the algorithm to follow this logic: If some state is `obsolete` (already been committed and then replaced with newer one), we replace that with the most recent one. This change does not introduce the `obsolete` flag; is already used by State infra to avoid cloning nodes with an outdated state.
Interestingly, it fixes the issue with an empty BottomSheet on Android (T66177144). See the attached video. The hope is that it's also will
This change theoretically might affect all things that use State, so it hard to predict what can break and how. So, if we don't see obvious problems here, I would set up a GK/QE and run the experiment in prod.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: JoshuaGross
Differential Revision: D21295137
fbshipit-source-id: e5613218d3e11a56623cab9bbf2540495b2b24e8
Summary:
It's not allowed to return nullptr from the callback. The assert ensures it which is helpful during development.
Probably, we should consider using `gsl::not_null<>` here.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: sammy-SC
Differential Revision: D21149891
fbshipit-source-id: a5f77b35029f22b499491721036405682f812a38
Summary:
`ShadowNodeFamilyFragment::Value` is a value couter-part type for `ShadowNodeFamilyFragment`.
We need that to be able safely copy data stored inside a `ShadowNodeFamilyFragment` object.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: kacieb
Differential Revision: D21169580
fbshipit-source-id: 1a485e1b2ae47bc7da9476a60466934ac9d61366
Summary:
We need it to be able pass an `EventEmitter` object to constructed concrete State objects.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: JoshuaGross
Differential Revision: D21169581
fbshipit-source-id: 3eef0310de7e2f061108aa85c1a39678a43fe85e
Summary:
The diff changes how the `empty raw props` optimization works in `ComponentDescriptor::cloneProps()`. Now it only fires only when the base `props` object is null, which is practically all production cases we have (and care about). (I tried, in a normal run there were no cases where the empty raw props were passed with non-null props.) From the other side, the old behavior that may return the same props objects previously several times created bugs and practically unexpected results and practically disallowed to clone props objects easily.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: JoshuaGross
Differential Revision: D21110608
fbshipit-source-id: 884807cd8e9c5c3e6cc1c9e4c1f0227259cc21fb
Summary:
We need to break up the `uimanager` module in order to solve circular dependencies problem (which future diff would have otherwise).
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: JoshuaGross
Differential Revision: D20885163
fbshipit-source-id: 08eb1ba1d408fc0948e8d0da62380786a40973af
Summary:
This is a debug-only feature that simply should be an assert. When it triggers in debugger and bubbles to some random exception catch block which makes it impossible to understand was exactly it happens. Making it an assert will stop debugger exactly where it happens.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: mdvacca
Differential Revision: D21028571
fbshipit-source-id: 3df4ec0da922026bb9df61081cb71113577e06e9
Summary:
We don't use it as vitrual anymore (setLayoutMetrics is a non-virtual method already), so it does not need to be marker virtual.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: mdvacca
Differential Revision: D21028572
fbshipit-source-id: 99f86fdd4cf2f5972034d9058d7b82bdc8680187
Summary:
Changelog: [Internal]
Current implementation of `measure` doesn't take transform into account..
So if you had a view which has width and height 100 and had `Scale(0.5, 0.5, 1)` (this will shrink view by half). Calling `getRelativeLayoutMetrics` would report its size being `{100, 100}`.
This applies if view's parent has transformation as well, because transformation is applied to all subviews of the view as well.
Reviewed By: mdvacca
Differential Revision: D20621590
fbshipit-source-id: 2cf902a0494291c821ecada56f810c5e6620db5a
Summary:
`LayoutInspectingPolicy` has two flags, `includeTransform` and `includeScrollViewContentOffset`.
`includeScrollViewContentOffset` seems to be redundant for two reasons.
# 1st
From looking at callers, they have always the same value.
I looked at all call sites, and they are either always both set to true or both set to false.
# 2nd
The way we include scroll view content offset, is through transformation, so setting `includeTransform` to true and `includeScrollViewContentOffset` to false will include content offset anyway. In order to make both flags work, we would need to introduce further changes to `getRelativeLayoutMetrics`. But since the flag isn't used anyway, I think it is better to get rid of it for now. If we need it in the future, we could re-introduce it.
Reviewed By: shergin
Differential Revision: D20622256
fbshipit-source-id: fb6156c66b752319ea928239fa723ff90688b0a0
Summary:
`fbsource//xplat` and `//xplat` are equivalent for FB BUCK targets. Removing extra prefix for consistency.
Changelog: [Internal]
Reviewed By: scottrice
Differential Revision: D20495655
fbshipit-source-id: a57b72f694c533e2e16dffe74eccb8fdec1f55f5
Summary:
This is pure syntactic change. Often we don't have a shared pointer to ShadowNodeFamily and only have just a reference. At the same time, `ComponentDescriptor::createState` does not have to accept a shared pointer. So, it's better to accept just a reference.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: sammy-SC
Differential Revision: D20578787
fbshipit-source-id: 905277001e096d41e75007575b59ea2ea15fbf4b
Summary:
This behavior matches the behavior of `dynamic_cast` (on which some callsites rely on).
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: sammy-SC
Differential Revision: D20456792
fbshipit-source-id: 9604da0f9f78cc7357e60ed11012756e753e4b45
Summary:
The diff introduces a new field in `ShadowNode` which defines in which order ShadowViews created from the node and its siblings will appear ShadowView tree. The feature will be used to overcome some platform limitations (e.g. on Android) on the mounting layer (it will be able to move some nodes of some time to the end (or beginning) of the list) and build features like zIndex ordering in C++ core.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: mdvacca
Differential Revision: D20396718
fbshipit-source-id: 16aef7c2b5511c874341ab7554e5585b2cdc356f
Summary:
Before this change, fields of EmptyLayoutMetrics have some "invalid" values to allow us to compare equal them individually and get `false`. Turned out that having invalid values there might break some serialization layers, which is no good.
This change fixes that and adds explicit check for EmptyLayoutMetrics before running a comparison of individual fields.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: mdvacca
Differential Revision: D20324881
fbshipit-source-id: ab8e2a402f6bdfb393fc9b6789decb526fa94dfa
Summary:
The new name is get_preprocessor_flags_for_build_mode.
Changelog: [Internal]
Reviewed By: d16r
Differential Revision: D20351718
fbshipit-source-id: 67628ce81e7244f0f72af2d00d92842a649ff619
Summary:
This diff introduces a new method of `LayoutableShadowNode` called `measure`. The purpose of the method is to measure the node from an "outside" perspective (including paddings and so on). The existing method with the same name (but with slightly different signature) will be renamed to `measureContent` in future diffs.
Hense we will have two `measure*` methods:
* `measureContent` measures nested content of the node;
* `measure` measures the node (outside).
This diff also introduces a default implementation of a new measure that uses `layoutTree` under the hood.
Measures the node with given layoutConstraints and layoutContext.
The size of nested content and the padding should be included, the margin should *not* be included.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: JoshuaGross, sammy-SC
Differential Revision: D20268047
fbshipit-source-id: 29c28cf16c5afe24f1bfb6e76c42816d4583a8fa
Summary:
Removing `virtual` qualifier for `LayoutableShadowNode::setLayoutMetrics()`. Original design implied that some subclass might override that method to provide additional functionality but we never used that and seems not it does not much the overall design: we store `layoutMetrics` *inside* `LayoutableShadowNode`.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: sammy-SC
Differential Revision: D20268042
fbshipit-source-id: 2aa9b3da316b97f26493fb04d19ca8290bd5d2a6
Summary: Now, following the previous diff, we remove `LayoutableShadowNode::isLayoutOnly()` and change the view flattening algorithm to rely on two new traits. See the previous diff to learn more about how it works.
Reviewed By: sammy-SC
Differential Revision: D20212252
fbshipit-source-id: 87a07e8bb17b2e66e5703f107dc35ca7a8e49634
Summary:
This diff introduces two new `ShadowNodeTrait`s that we will use in the future in the new (slightly tweaked) view-flattening algorithm. (Note: this diff does not enable the new flattening, it's just preparation.)
The idea is that we split the notion of `isLayoutOnlyView` into two traits:
* `FormsView`: `ShadowNode`s with this trait must be represented as `ShadowView`s. Normal "visible" ShadowNodes will have this trait, but "layout only views" in old nomenclature will not.
* `FormsStackingContext`: `ShadowNode`s with this thread not only must be represented as `ShadowView`s but also have to form a "stacking context" which means that their children must be mounted as `ShadowView`'s children.
Our implementation does not exactly follow W3C spec in terms of sets of props that create the stacking context (because of historical reasons and mobile specifics) but ideologically it's the same. We start from the very conservative implementation where only views with background-color and borders do not form stacking context and then we probably extend that to more props.
Most importantly for us now, we will enforce the absence of ``FormsStackingContext` for `ParagraphShadowNode` and the presence of `FormsView` for `TextShadowNode` on Android where it's essential for mounting layer.
Read more about stacking context here: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: sammy-SC
Differential Revision: D20212253
fbshipit-source-id: 0fbaee214ce2c5886cb0232843a2a3c7bb20655d
Summary:
Changelog: [Internal]
Use LayoutContext to pass `fontSizeMultiplier` down to ParagrapShadowNode.
Reviewed By: shergin
Differential Revision: D20184596
fbshipit-source-id: 3965a127069a21328ed19cb3f9732f0a2d1c4d58
Summary:
In order to build dynamic text sizing, `LayoutableShadowNode::measure` needs to accept `LayoutContext`
Changelog: [Internal]
Reviewed By: shergin
Differential Revision: D20184598
fbshipit-source-id: 8928b59d51948caf3654f40049212a89a91dceb6
Summary:
Cloning subtrees is not something specific to a RootNode, so it makes sense to have it in ShadowNode. Soon we will use that to clone subtrees inside Paragraph component to implement Inline Views.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: mdvacca
Differential Revision: D20090666
fbshipit-source-id: 0a64ef9bda438cd55d5fd21d3ad83b36221fa89e
Summary:
All logic that is performed on the root node only was moved from `layout` to a separate methods `layoutTree`. That makes the code simpler and allows reusing `layoutTree` in InlineViews feature.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: mdvacca
Differential Revision: D20052025
fbshipit-source-id: 3070a1cca4e322c6d077ede751ea80359c96a600
Summary:
Here we refine the `ShadowNode::BaseTraits` static method. Before this change, ConcreteViewShadowNode<> enforces Layoutable and YogaLayoutable traits. This change moves that responsibility to LayoutableShadowNode and YogaLayoutableShadowNode which makes overall logic more coherent.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: sammy-SC
Differential Revision: D20052027
fbshipit-source-id: fd25264204b0232b1dbbff6f9dfefd9fbcb146c4
Summary:
The fact that `LayoutableShadowNode` now inherits `ShadowNode` allows us to de-virtualize `getLayoutableChildNodes` and move that to `LayoutableShadowNode`. Less code, less virtual dispatch, less complexity.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: sammy-SC
Differential Revision: D20052032
fbshipit-source-id: 580e86b5a746028e470788e00027f247bf77126c
Summary:
D19963353 mentioned the infrastructure that re-routes methods calls related to adding and cloning children between YogaLayoutableShadowNode and ShadowNode. `cloneAndReplaceChild` is exactly this. It was implemented as a virtual method that is called from `ConcreteViewShadowNode`. The whole process requires building a list of children of some class and passing that as a list of pointers. Now we don't need it all that because we can call directly and statically. That change will allow us to simplify that infra even more in the future diffs.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: sammy-SC
Differential Revision: D20052022
fbshipit-source-id: ddf341c112edd8a2f79eaf74465a9a360a168541
Summary:
`traitCast` is a special form of static_cast that checks additional requirements (similar to `dynamic_cast`) before performing the cast. We will use that in many places in the coming diffs.
Restructuring the class hierarchy in the previous diff finally allows us to do static casts among ShadowNode and LayoutableShadowNode and other classes (previously it wasn't allowed because of lack of common base class).
Why we don't want to use `dynamic_cast`:
* It's expensive (and we need to do the cast on the hottest fragments of the framework). (See: (1) http://www.stroustrup.com/fast_dynamic_casting.pdf and (2) https://www.youtube.com/watch?v=ARYP83yNAWk Herb Sutter & proposal of `down_cast`).
* It's code-size inefficient, whereas `static_cast` has zero runtime and code-size overhead.
* Removing `dynamic_cast` will allow us finally to opt-out `RTTI` (additional code size and perm wins).
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: sammy-SC
Differential Revision: D20052024
fbshipit-source-id: d293c1cf80deb7817d333d5306d6b32bf3abdb27
Summary:
This is a very crucial change, everything else in this stack depends on it.
Here is the set of constraints that we have for ShadowNode-based class hierarchy:
* `ShadowNode` is a base class that defines basic operations on the nodes. It does not have virtual methods by design (virtual dispatch hurts performance; we want to limit and centralize that in `ComponentDescriptor`s).
* `ConcreteShadowNode<>` template *statically* wires particular `ShadowNode` and particular `Props` establishing a type-safe relationship between them ensured on compile time.
* Not all `ShadowNode`s are "layoutable", not all "layoutable" `ShadowNode`s use Yoga to do layout.
* Layotability (and YogaLayotability) feature is implemented as two classes `LayoutableShadowNode` and `YogaLayoutableShadowNode`. These classes essentially need to know something about the ShadowNode nature of the object (get the list of children or replace some children).
Before the change, `LayoutableShadowNode` and `YogaLayoutableShadowNode`classes did not inherit `ShadowNode` because we don't want to use *virtual inheritance* for `ShadowNode`: `ConcreteShadowNode<>` already inherits `ShadowNode`, so if we make `LayoutableShadowNode` inherits `ShadowNode`, we will have to somehow flatten this inheritance hierarchy (and the virtual inheritance is an answer to that). (Yes, C++ supports multiple inheritance and virtual inheritance.)
Before this change, we solved this dilemma this way: We have a subclass-template `ConcreteViewShadowNode<>` that inherits `ConcreteShadowNode<>` and `YogaLayoutableShadowNode`. Then, we had a bunch of methods that implement the rerouting of some functionality from `YogaLayoutableShadowNode` to `ShadowNode` and vise-versa. (See the diagram "Before".)
That worked fine, except the caveats:
* That wiring is nasty, complex, hard to reason about and overall limiting.
* There is no way to statically cast `LayoutableShadowNode` to `ShadowNode` (because there is no common base class). That forces us to use dynamic_cast on some perf critical paths (including layout, diffing and so on).
* Adding features that rely on interop between `LayoutableShadowNode` and `ShadowNode` is a nightmare.
It should be a better way to deal with this dilemma, and this diff implements a different approach: We can have a base class of `ConcreteShadowNode<>` as a template parameter. With this approach, we can make `LayoutableShadowNode` inherit `ShadowNode` and when we need to instantiate a `ConcreteShadowNode<>` that needs to be layoutable, we can just specify `YogaLayoutableShadowNode` as a base class. (See the diagram "After".)
This simple change will allow us to simplify a lot of things. The rest of the stack is about getting rid of unnecessary moving parts. Which will finally allow us to build "Inline Views" feature.
```
╭──────────────────────╮
│ ◎ ○ ○ ░░░░░░░░░░░░░░░│
├──────────────────────┤
│ │
│ │
│ Before │
│ │ ┌────────────────────────────┐ ┌────────────────────────────┐
│ │ │ │ │ │
│ │ │ ShadowNode │ │ LayoutableShadowNode │
└──────────────────────┘ │ │ │ │
└────────────────────────────┘ └────────────────────────────┘
▲ ▲
│ │
╔════════════════════════════╗ ┌────────────────────────────┐
║ ║ │ │
┌────────�║ ConcreteShadowNode<> ║ │ YogaLayoutableShadowNode │
│ ║ ║ │ │
│ ╚════════════════════════════╝ └────────────────────────────┘
│ ▲ ▲
│ │ │
│ │ │
│ │ │
│ │ ╔════════════════════════════╗ │
│ │ ║ ║ │
│ └─────║ ConcreteViewShadowNode<> ║─┘
│ ║ ║
│ ╚════════════════════════════╝
│ ▲
│ │
│ ┌──────────────┴───────────────┐
│ │ │
│ │ │
│ │ │
┌────────────────────────────┐ ┌────────────────────────────┐ ┌────────────────────────────┐
│ │ │ │ │ │
│ TextShadowNode │ │ ViewShadowNode │ │ ParagraphShadowNode │
│ │ │ │ │ │
└────────────────────────────┘ └────────────────────────────┘ └────────────────────────────┘
╭──────────────────────╮
│ ◎ ○ ○ ░░░░░░░░░░░░░░░│
├──────────────────────┤
│ │ ┌────────────────────────────┐
│ │ │ │
│ After │ │ ShadowNode │
│ │ │ │
│ │ └────────────────────────────┘
│ │ ▲
└──────────────────────┘ ┌────────────────────────────────────┤
│ │
│ ╔════════════════════════════╗
┌────────────────────────────┐ ║ ConcreteShadowNode ║
│ │ ║ <Base: ShadowNode> ║
│ LayoutableShadowNode │ ║ ║
│ │ ╚════════════════════════════╝
└────────────────────────────┘ ▲
▲ │
│ ┌────────────────────────────┐
┌────────────────────────────┐ │ │
│ │ │ TextShadowNode │
│ YogaLayoutableShadowNode │ │ │
│ │ └────────────────────────────┘
└────────────────────────────┘
▲
│
╔════════════════════════════╗
║ ConcreteShadowNode ║
║ <Base: ║
║ YogaLayoutableShadowNode> ║
╚════════════════════════════╝
▲
│
╔════════════════════════════╗
║ ║
║ ConcreteViewShadowNode<> ║
║ ║
╚════════════════════════════╝
▲
├─────────────────────────────────────┐
│ │
┌────────────────────────────┐ ┌────────────────────────────┐
│ │ │ │
│ ParagraphShadowNode │ │ ViewShadowNode │
│ │ │ │
└────────────────────────────┘ └────────────────────────────┘
```
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: sammy-SC
Differential Revision: D19963353
fbshipit-source-id: b65c8a5064bdb54ab64f08a8e546aa9e2b5a486b
Summary:
Changelog: [Internal]
As agreed in https://fb.quip.com/Oh2mAaTAbBj6, `findNodeAtPoint` now calls callback with `shadowNode` instead of `instanceHandle`.
Reviewed By: shergin
Differential Revision: D20097269
fbshipit-source-id: bd2a1bcd26ab2510f16c3e73f628be4b1f7dacfc
Summary:
Changelog: [Internal]
# Problem
Calling `UIManager::updateState` does not increment state revision because it calls `ConcreteComponentDescriptor::createState` which creates new state with state revision 1.
# How did this propagate?
This error propagated itself in TextInput when trying to input a value, you would be only allowed to type in 1 character.
Reviewed By: JoshuaGross
Differential Revision: D20072844
fbshipit-source-id: 37b8173307e1d91d6e9c41b5ff2e185dde31cc38
Summary:
Having the overridden function that returns a different type is apparently not a good idea (and might cause bugs and unexpected behavior), so it was renamed. The function also got a new return type (`const &` instead of `std::shared_ptr`) for simplicity, better performance, and smaller code size.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: JoshuaGross
Differential Revision: D19837694
fbshipit-source-id: b7a96424bd040409371724907b3fb3931cd8a2e8