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:
We are moving towards 100%-prettified files. That's the first step when we apply Clang Format for `ReactCommon`.
Changelog: [Internal]
Reviewed By: mdvacca
Differential Revision: D20110895
fbshipit-source-id: 0a0ce4997cf1c3721b0b07ef78c1a57ce87d20f9
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
Summary:
Before this change the Element<> API didn't allow to specify state objects and crashed during instantiation of non-null states.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: JoshuaGross
Differential Revision: D19816358
fbshipit-source-id: 95ba5e03ea98c0260593462146e8523c95245e2b
Summary:
Systraces were disabled a year ago in D14019272 because we suspected they can negatively affect perf. We don't think this is the case anymore.
Changelog: [Internal]
Reviewed By: mdvacca
Differential Revision: D19786284
fbshipit-source-id: 185ed45b134fdcadf131cfddfcf8faf37537a684
Summary:
Of course, compare_exchange_strong didn't actually do what I wanted.
Using a mutex is simpler and actually has the semantics we want: atomically get the current value, compare, and bail if the value is the same, or swap and continue.
Changelog: [Internal]
Reviewed By: shergin
Differential Revision: D19754451
fbshipit-source-id: 6b0aef217b235959af683ec5e31b07a0dd7bb040
Summary:
Simple hack to prevent duplicate onLayout events from being emitted to JS.
Because of the addition of State Reconciliation to the Fabric lifecycle (see previous diff), in certain circumstances entire subtrees can be relayed-out many, many times even though they aren't changing. For JS product code that responds to every onLayout and forces a ReactJS tree commit (see: some usages of VirtualizedList) this can cause an async infinite loop of commits and layouts even though the tree and the LayoutMetrics aren't actually changing. Even though nothing is changing, it can still cause serious performance regressions and even some bugs since the internals of various state machines may assume onLayout won't be called many times.
Changelog: [Internal]
Reviewed By: shergin
Differential Revision: D19715280
fbshipit-source-id: d879e24f1c7b1f710ad430b7473aa9293d093dea
Summary:
This is a quite fragile and important part of the render engine. We need to dirty Yoga node only in cases where a change affects layout. In the case of over-dirtying, we can kill performance. In the case of under-dirtying, we can produce an incorrect layout.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: sammy-SC
Differential Revision: D19596279
fbshipit-source-id: 9f2ac67c44cb35c8ba44be1025b94b7921b74e17
Summary:
This is aligned with all simular changes that we do for `*Props` types (see D19583582 and D19390813).
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: sammy-SC
Differential Revision: D19596281
fbshipit-source-id: 283b89c65504e20a461b12c2d1218325c6621dd8
Summary:
ShadowNode::Shared and SharedShadowNode represent the exact same type. Nowadays we use ShadowNode::Shared instead of SharedShadowNode.
This diff replaces usages of SharedShadowNode for ShadowNode::Shared in the fabric folder.
Changelog: [internal]
Reviewed By: shergin
Differential Revision: D19217717
fbshipit-source-id: 112331b22251aa3a3d5e183395c54f2ca0f56e47
Summary:
This is a part of migration staterted in D19390813.
There is no need to have those as `const`. The whole `*Props` object is usually `const` (and when it's not, props should not be too).
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: mdvacca
Differential Revision: D19583582
fbshipit-source-id: 9c680268f944cdf08669fce7e997b05f23a02667
Summary:
The reason for this change is that it is the primary root that we want people to be using and the naming should reflect that.
#nocancel
build-break
overriding_review_checks_triggers_an_audit_and_retroactive_review
Changelog: [Internal]
Oncall Short Name: fbobjc_sheriff
Differential Revision: D19431128
fbshipit-source-id: c7208e20ed0f5f5eb6c2849428c09a6d4af9b6f3
Summary:
Having automatic defaults/an optional arg for `convertRawProp` has caused way more problems than it is worth. Remove the default argument.
Changelog: [Internal]
Reviewed By: shergin
Differential Revision: D19151594
fbshipit-source-id: 839ec8d138b2c3c083f221a2871582454004648c
Summary:
The coefficients in the code were incorrect: the default value of the scale should be 1, not 0.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: sahrens
Differential Revision: D19101221
fbshipit-source-id: 3b4c3afc692ddb6bf32bf2344a77ec5ca34a06e4
Summary:
When we designed the Fabric's event priorities we followed the model "let's assign all priorities to all events as they should theoretically be and create a flag that disables sync execution (because we were unsure that it's stable enough". After some experiments, it's clear that this model is not feasible. We realized that we were often not sure about the exact event priority that should be assigned to a particular event. We also realized that the priorities in web work differently compare to RN. And we are not sure how we should ensure ordering among events in different queues with different priorities.
At the same time, we want to use (or experiment with) sync events for in some cases when we sure about desired behavior and/or where async events make no sense.
This diff deletes the macro that disables sync priorities and explicitly assigns async priorities to events that previously had sync ones.
The actual behavior should not change.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: sammy-SC
Differential Revision: D18950431
fbshipit-source-id: 4033ef63d4e736075b525a693cd514d7b92d5bb0
Summary:
Having those arguments optional does not really make anything easier to use; on another side that makes it hard finding problems caused by missing that parameter.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: sammy-SC
Differential Revision: D18797337
fbshipit-source-id: c119b8f6a03994072edb45e39337e33b0f8b602f
Summary:
`accessibilityTraits` was missing, this diff adds it.
Also there is a name mis match, in javascript it is called `accessibilityRole`.
Changelog: [Internal]
Reviewed By: JoshuaGross
Differential Revision: D18857668
fbshipit-source-id: 10656e8fb4e8c1d771a72c7f354b845e41cfc313
Summary:
Changelog: [Internal]
In paper implementation:
`accessibilityActivate` returns NO in case `onAccessibilityTap` is nil.
In Fabric we have no option to detect whether `onAccessibilityTap` is nil or isn't but we don't want to prevent VoiceOver from tapping an element. This could potentially trigger action associated with element twice.
Let's say you have `onPress` and `onAccessibilityTap`, it will trigger both if you trigger action through VoiceOver.
Reviewed By: shergin
Differential Revision: D18572432
fbshipit-source-id: c5ac002317c798a10045b6f05738299d0ae27456
Summary:
As soon as we have traits infra, it's pretty straight-forward to implement this kinda flag. Without the traits, it's challenging to build that in a performant and elegant way. The challenges of the dynamic_cast-involved approach are:
* How to check for that feature in YogaLayoutableShadowNode?
* Even if we use `dynamic_cast`, to which class to cast?
* We also need to do that in constructor... and dynamic_cast-like checks for `this` don't work in constructors (C++ design limitation).
* How to scale that if we have more classes like Paragraph (and we will have it for sure)?
* Performance.
* Relying on RTTI.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: sammy-SC
Differential Revision: D18525347
fbshipit-source-id: b1915f43ff3fe4364ab6345fb9d1becc591b5a35
Summary:
Quite often in the Fabric codebase, we need to iterate on a list of shadow nodes and perform some work depending on the exact type (or kind) of shadow node we have. Today, we exclusively use RTTI to test for exact type. The problem here is that RTTI is not only expensive in terms of code size (we are moving towards removing RTTI), it's expensive in terms of CPU cycles. (Don't mistake RTTI/dynamic_cast overhead with dynamic dispatch overhead!)
`dynamic_cast` has it's own advantages, of cource: it's simple and straight-forward and does not require additional configuration. On the other side, it requires knowledge about exact class relationship configuration and knowing the exact name of the class.
ShadowNodeTraits is the generalized solution for storing predefined traits right inside ShadowNode object and check/set/unset them efficiently and in a particular-class-independent manner.
This diff only implements it in general and switching storing an internal flag of ShadowNode inside the trait collection to save some space (and for illustration purposes as well).
In the coming diff, we will see how this approach allows tackling the real, non-trivial problem.
In addition to the concept, this diff implements some convenience infra, such as `ConcreteShadowNode::BaseTraits()` static method that allows designating intrinsic-to-a-class traits declaratively.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: sammy-SC
Differential Revision: D18525348
fbshipit-source-id: 083bb85e0a9dc9d6c69bf395bd338d3c18def688
Summary:
The original implementation had an incorrect order of fields in the struct wich causes bugs with border drowing.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: sammy-SC
Differential Revision: D18444733
fbshipit-source-id: e4611e6e90eee85e7cdebcee3c5bb6886417aa26
Summary:
Use padding instead of setting size of SafeAreaView, this should make it more consistent with Paper component.
changelog: [internal]
Reviewed By: shergin
Differential Revision: D18225793
fbshipit-source-id: 08dccbdae0e4f7a7847501a06e17d4c26473462a
Summary:
This change in the method signature allows removing usage of `shared_from_this()`.
After this change we will have only one usage of `shared_from_this()`.
Changelog: [Internal] Small Fabric-specific optimization.
Reviewed By: sammy-SC
Differential Revision: D17973956
fbshipit-source-id: 19818b0855565d872005062ba2992718ca89b372
Summary:
`xplat` targets add different deps based on what platform the target is being built for.
for anything using `fb_xplat`, we can put all ios supermodules in `fbobjc_labels` and all android sms in `fbandroid_labels`
There's some weirdness with python targets like `thrift_gen` in `/xplat/mobileconfig/tools/generator/gen-py/BUCK` that don't have platform-specific labels because the except_for list for `fbandroid` doesn't need the `fbsource//` prefix (see changes in `/ios/isolation/infra.mobileconfig.sm`)
Changelog: [Internal]
Reviewed By: shergin, joshleibsly
Differential Revision: D17884952
fbshipit-source-id: e245364cf515b75682990094d24f789d53b1f3f5
Summary:
If you try to use ART components with fabric, their transform is causes crash (stack trace P108110438). You can see this crash if you use RCTVideo component in fabric and tap video to reveal slider.
The cause of crash is mismatch of formats between what is expected for transform and what is being sent.
In this diff we add a check to see whether the configuration is of expected type.
Reviewed By: shergin
Differential Revision: D17181838
fbshipit-source-id: c4f3c920281a2e7f58ff0ffe1d0ec2af8249a16c
Summary: Support existing, backwards-compatible AndroidTextInput component for minimal support of TextInput on Android.
Reviewed By: shergin, mdvacca
Differential Revision: D17086758
fbshipit-source-id: 25726f22229e0d5dfe96eb36b386a5317601283d
Summary: Accessibility is essential but seems we don't have any use of AccessibleShadowNode in Fabric.
Reviewed By: sammy-SC
Differential Revision: D16139595
fbshipit-source-id: a6aec6d22c4a6050d7ee5e6b21ef4ad04d80ffce
Summary:
Previously we used `std::string` as a type behind all prop names (and name fragments). Even if `std::string` converted from `char const *` should be heavily optimized by STL and compiler, we still concatenate and copy those strings a lot. Switching to `char const *` allows avoiding tons of copying and inefficient equality checks.
Besides that, the future, more sophisticated optimization will rely on this.
Reviewed By: mdvacca
Differential Revision: D15511493
fbshipit-source-id: 9f509d18f0c737f7f77d4fea192d2ed1872e3731
Summary:
First of all, seems it's the right thing to do. Fabric C++ code is cross-platfrom and should run on *all* platforms including Windows, Linux, and Mac.
While we don't have a real *production* use cases where we need compilation for desktops, having CXX target is really handy for two reasons:
* It simplifies local test running process. Instead of going to `/fbandroid/` and executing something like `buck test fbsource//xplat/js/react-native-github/ReactCommon/fabric/core:coreAndroid` (note the suffix). We can just do `buck test fbsource//xplat/js/react-native-github/ReactCommon/fabric/core:core` everywhere and it works now out of the box. Running tests with "Apple" flavor never worked for me.
* It allows creating synthetic benchmark tests (using Google Benchmark) that can be used as a rough approximation of code micro-optimizations.
Reviewed By: JoshuaGross
Differential Revision: D15608678
fbshipit-source-id: d2449035685dbca6ab983480f5334ec4ac11cd35
Summary:
In order to remove the config pointer from nodes, we have to keep track of whether the node is using web defaults.
This information fits into one bit that we can place in padding (i.e. no extra memory needed).
This allows us to get rid of config usage withing `YGNode` with some exceptions:
- `iterChildrenAfterCloningIfNeeded` -- this function will simply receive the configuration, or the cloning callback.
- `setAndPropogateUseLegacyFlag` -- will be removed in D15316863
- in `YGNode::reset` -- will go away utomatically once we remove the config pointer
Reviewed By: SidharthGuglani
Differential Revision: D15391536
fbshipit-source-id: 0fa0d0805c6862bd741fe4a7d9b637ed534f56a4
Summary: `YogaStylableProps.yogaStyle` is designed to be consumed by Yoga only. Making it `protected` allows us to avoid confusion and misuse of this props.
Reviewed By: JoshuaGross
Differential Revision: D15296474
fbshipit-source-id: cf9e416afee99fb426d72765557b34d303a63dbe
Summary: This diff replaces usage of abort() with assert() when a prop-value is not found during parsing of prop values
Reviewed By: shergin
Differential Revision: D14563338
fbshipit-source-id: c799420e6b49df35e1d7ccdbd4bc4845067d33cc
Summary:
This diff changes the condition in `ViewShadowNode::isLayoutOnly()` removing checking for `onLayout` event listener.
We needed that before because the mechanism of emitting events was based on analyzing mutation instructures (we needed those to be generated for nodes with `onLayout`).
Recenly we changed that algorithm deeply integrating in layout infra, so we don't need this anymore.
Reviewed By: JoshuaGross, mdvacca
Differential Revision: D15273491
fbshipit-source-id: 2d43f00d1b87369d5993fe5ba70c2de36b8ce0c5
Summary: Apparently, Yoga has a "quirks mode" and we have to enable that for Fabric. Which is probably a mistake that we have to make one more time.
Reviewed By: davidaurelio
Differential Revision: D15267852
fbshipit-source-id: 88a910fafc9ff64fb19376f4b74a2f2fd5827eba
Summary: I have noticed that `backfaceVisibility` example crashes (because actual value is a string/enum, not a boolean), so I fixed it.
Reviewed By: JoshuaGross, mdvacca
Differential Revision: D15219261
fbshipit-source-id: 27f76cd10903794d597adacb9da7300a42813f8e
Summary:
`LayoutableShadowNode::getTransform` returns a transform object that represents transformations that will/should
be applied on top of regular layout metrics by mounting layer.
Reviewed By: mdvacca
Differential Revision: D15219262
fbshipit-source-id: e7aeb85b5f7e2fce3f8faf9dfcaee5dae3217d36
Summary:
Previously we computed the list of nodes that need to be notified about layout changes using a list of mutation instructions. That was fine, but that's not really compatible with some other changes that I plan to make, so I decided to change it (make it better).
Besides the better design (debatable; fewer dependencies to unrelated moving pieces), here is why I believe the new way is more performant:
* The new approach has no `dynamic_casts`, whereas the previous has tons of them (two per a mutation). If a `dynamic_cast` takes 10 ns, for 500 nodes it can take up to 5ms only for casts. (Non-scientific assumption.)
* After removing dependency to mutation instruction, we can enable flattening for views which have `onLayout` event.
Reviewed By: mdvacca
Differential Revision: D15110725
fbshipit-source-id: 31a657ccfd02441734ad1d71a833653223163289
Summary:
Different frameworks use different kinds of floats, optional floats, and floats with assigned unit names. All those approaches use different ways to represent undefined and empty values. To deal with it we need to have some helper functions.
So, this diff changes some ways that we convert some corner values (like NaN and empty value). That change is motivated by recent personal discoveries in this field that shifted my vision on that. E.g. ComponentKit does not use `CGFloatMax` value as `Infinite` value. UIKit is also (surprisingly to me) okay with using `Infitite` instead of `CGFloatMax`. And, in general, seems using really conceptually appropriate values (instead of UIKit-inspired ones) it's the right thing to do.
Reviewed By: mdvacca
Differential Revision: D15155189
fbshipit-source-id: 33e15141f1ca3efb400a7160811224335de34ba1
Summary:
We don't need to have those constants because this functionality is available in STL via `std::numeric_limits<YourParticularFloatType>::infinity()` (or `::min()` and `::max()`).
At the same time usage of `kFloatMax` was replaced with `Infinity` (which is a different value). Using `max` instead of `Infinity` was an attempt to mimic iOS/UIKit model where `Infinity` and `NaN` values usually are not being used. However, now this does not seem like a good idea. This concept is not used anywhere else (even in CK which is totally incompatible with it) and de-facto in RN we use it only in few places. So, let's use Infinity in places where it's logically appropriate.
Reviewed By: mdvacca
Differential Revision: D15155191
fbshipit-source-id: 4d24350c7540cec074a8b040d7c13f257aa812e7
Summary:
@public
Adds `YGStyle::ValueRepr` to make code depending on the actual type easier to write.
So far, we have treated `yoga::detail::CompactValue` as an implementation detail, and that’s what it’s supposed to stay.
React Native Fabric has one value conversion overload that depends on that type, though, and used `decltype(YGStyle{}.margin()[0])` until now.
That’s problematic for two reasons:
- we want to constrain the parameter of `operator[](...)` to enum types, making the `0` unsuitable
- we want to return the non-const overload of the operator to return a custom `Ref` type, which is not the type needed by Fabric.
Making the storage type explicit allows to write more forward-compatible code.
Reviewed By: SidharthGuglani
Differential Revision: D15078960
fbshipit-source-id: 932c27ef2f2cdc6ce965b79894268170f0ccdce5
Summary:
@public
In order to encapsulate property access on `YGStyle`, as a first measure we wrap all fields with accessors.
This will e.g. enable dynamic property storage and instrumentation in the future.
All accessors have a `const` version that allows direct access via `const&`. For mutation, bit fields are wrapped with a custom reference object.
This style allows for the least amount of changes in client code. Property access simply needs appended parens, eg `style.direction` becomes `style.direction`.
Reviewed By: shergin
Differential Revision: D14999096
fbshipit-source-id: fbf29f7ddab520513d4618f5e70094c4f6330b30
Summary:
UAs must adjust border radius values to fit a content box:
>>> Corner curves must not overlap: When the sum of any two adjacent border radii exceeds the size of the border box, UAs must proportionally reduce the used values of all border radii until none of them overlap.
This diff implements that.
Reviewed By: mdvacca
Differential Revision: D15028325
fbshipit-source-id: 368232ffa2fa0409d13759bbbe7fe10f8474c400
Summary:
We will use it inside `core` module, so we have to decouple it from `view`.
As part of this, I added some comments, changed `const Float &` to just `Float` and put the implementation into `.cpp` file.
Reviewed By: mdvacca
Differential Revision: D14593952
fbshipit-source-id: 80f7746f4fc5b95febc8df9f5a9c0386a6425c88
Summary: This diff replaces usage of abort() with LOG(FATAL) when a prop-value is not found during parsing of prop values
Reviewed By: fkgozali
Differential Revision: D14591210
fbshipit-source-id: 4a8484ea6bdfec5534122ded43cc24ef80c13c1d
Summary: This diff replaces usage of abort() with LOG(FATAL) when a prop-value is not found during parsing of prop values
Reviewed By: sahrens
Differential Revision: D14570713
fbshipit-source-id: 57b0f993ba264a4949baf4022d807c55cdfe03b1
Summary: Conceptually, this assert is correct, however, sometimes a new node got allocated by same address as old parent node (which does not exist already) which makes the assert fires.
Reviewed By: mdvacca
Differential Revision: D14533070
fbshipit-source-id: 3fcc71c25e7d724180dc85aaf2457227d22ddba0
Summary:
With recent changes, simple cloning a component does not mean that underlying Yoga node will be dirtied. Autodirtying is only performed if the child nodes were dirtied and/or if the YGStyles were changed.
That's not the case for Text component which does not have direct layotable children, so we have to call `dirtyLayout` explicitly.
Reviewed By: JoshuaGross
Differential Revision: D14508277
fbshipit-source-id: 2c52d7d40da963a976c7d28a13781cc1755ef591
Summary: More `assert`s and `ensureUnsealed` calls were added to YogaLayoutableShadowNode for simpler debugging and early failing.
Reviewed By: JoshuaGross
Differential Revision: D14496936
fbshipit-source-id: 898c6a0665aeac5d0b1995bd53046f58cec37007
Summary:
If the `HasNewLayout` flag is `false`, we should not copy the data from YGStyle/YGLayout to ShadowNode because the node can be already sealed and because it's unnecessary. Previously we workaround this case with a special check in `setLayoutMetrics` method, but that can be unreliable because of some side-effects related to pixel rounding and comparing floats.
The new approach is much more robust and explicit.
Reviewed By: JoshuaGross
Differential Revision: D14496939
fbshipit-source-id: deddb14d2206c5bd3f22154d0ea682e3c5888901
Summary: These default implementations are never being used. Removing them allowing to ensure that flags inside YGNode have same values as flags in YogaLayoutableShadowNode. That also saves a couple of bytes in size of ShadowNode.
Reviewed By: JoshuaGross
Differential Revision: D14496938
fbshipit-source-id: c43f9c8a2eec054f728ff54a6573668eccda55fb
Summary: That diff fixes an obvious bug that prevents internal data of LayoutableShadowNode being cloned during cloning of YogaLayoutableShadowNode.
Reviewed By: JoshuaGross
Differential Revision: D14472753
fbshipit-source-id: d07be3bf36708690dfe10de7898e2b48648aa0f4
Summary: In addition to the previous change, now we handle a situation where some node receives a new set of children and all those children have the same styles. (See the previous diff for more details.)
Reviewed By: JoshuaGross
Differential Revision: D14472754
fbshipit-source-id: 16411036e14f18e730e064e33948440b05ff51c8
Summary:
After the change, YogaLayoutableShadowNode will preserve dirty flag (being false) in cases where:
* a node was cloned with same children;
* changes in props don't affect layout.
Motivation:
In Fabric we always were aggressive about dirting yoga nodes: when we clone the node, we always dirty underlying Yoga node. I think that was the case because we don't deeply understand how the system works and we always had more severe problems to fix. Now, we faced an issue that forces us to think about that problem carefully (more about that later).
(I don't expect that will improve TTI performance, but that's possible if we do a lot of changes in the hierarchy during initial load process.)
I see two main use cases where we have to be smart about dirtied yoga nodes:
Case 1. Native local commits which do *not* modify yoga styles.E.g. in a case where ScrollView updates the internal state (which has offset info) really really frequently. (It will be implemented later.) That `contentOffset` info does not or might not affect layout, so we should not pay for this.
Case 2. Legit React commits which do *not* modify yoga styles. E.g. in a case where only the background color of some view changes, we don't need to relayout anything. Unfortunately, we do this in Fabric because of two major reasons:
* We don't make a difference between any changes in Props.
* React constructs new children of cloned node iteratively, calling `appendChild`. That makes implementing optimization really challenging because we don't know when the process ends. And when it ends we have very few pieces of information about how the state looked before.
This diff stack will handle the problems of the first kind. The main motivation is: we want to have state updates to be as lean as possible.
Reviewed By: JoshuaGross
Differential Revision: D14472752
fbshipit-source-id: 68374f60cb07de9ab65bf1f6d94c828985359fa5
Summary: Several things need to ironed out: 1) LocalState in Fabric C++, 2) setting dimensions of BottomSheet component to 0,0 for parent.
Reviewed By: shergin
Differential Revision: D14426167
fbshipit-source-id: 45a90a7971c87672872108a9e360926b4a6095f0
Summary: The hope is that it will remove many unnececery allocations improving overal perfromance.
Reviewed By: mdvacca
Differential Revision: D14249198
fbshipit-source-id: f0442b3919ccead0582a3190dea0e33d517d85f6
Summary: It can save us a couple of ms, hopefully.
Reviewed By: mdvacca
Differential Revision: D14249196
fbshipit-source-id: b5911bcd8b49be66de7b9d2da660df38ef7cc8cd
Summary: That should reduce the size of `ShadowNode`, make an instantiation of shadowNode a bit faster, and make `clone` operation a bit faster because simple dynamic dispatch is faster than std::function invocation. It also should help a bit with code size.
Reviewed By: mdvacca
Differential Revision: D14249200
fbshipit-source-id: c1332b139d27becebf15cd894475507b5fd0eb9f
Summary: Add assorted missing includes in `xplat` that would be exposed by future changes.
Reviewed By: ispeters, nlutsenko
Differential Revision: D14213660
fbshipit-source-id: 329f133784015fe20ee99feaec8ef05e117fe3a6
Summary: That's bummer that we have to do it, but it's actually reasonable. Files in `core` and `events` depend on each other creating circular dependencies and other similar hard problem.
Reviewed By: mdvacca
Differential Revision: D14195022
fbshipit-source-id: 96a44ae28631cc9ccd7d7de72a94526f9e0dd12a
Summary:
The ConcreteViewShadowNode was changed to be independend of actual amount of template arguments of ConcreteShadowNode.
We will use it soon.
Reviewed By: JoshuaGross
Differential Revision: D14187761
fbshipit-source-id: b4c8051e2ae3803932713b0c255492466e80d3bd
Summary:
* "rotate" is often used as shorthand for "rotateZ"
** Paper handles this here: diffusion/FBS/browse/master/xplat/js/react-native-github/React/Views/RCTConvert%2BTransform.m$89
* Sometimes react sends a string with units, e.g. "45deg", so we need to convert that to a Float.
** Paper handles this here: diffusion/FBS/browse/master/xplat/js/react-native-github/React/Views/RCTConvert%2BTransform.m$14-27
Reviewed By: JoshuaGross, mdvacca
Differential Revision: D14154173
fbshipit-source-id: 53d7405f26c78bb470d46879309c9697d9985c1c
Summary:
@public
Encapsulates node cloning within `YGConfig`.
This is necessary for allowing for context-aware cloning functions, which will ultimately allow for removal of weak global JNI references.
Reviewed By: shergin
Differential Revision: D14132608
fbshipit-source-id: 0dec114c8e172b1e34a4b7fd146c43f13c151ade
Summary: Use the new copyright header format used elsewhere in the React Native repository.
Reviewed By: shergin
Differential Revision: D14091706
fbshipit-source-id: b27b8e6bcdf2f3d9402886dbc6b68c305150b7d5
Summary: Now in BUCK file only, not in code.
Reviewed By: JoshuaGross
Differential Revision: D14019271
fbshipit-source-id: e1396be7156a374a1379a147ddecb83b51686121
Summary:
It's better to comment `DWITH_FBSYSTRACE` out in BUCK files instead of removing them from the code.
I'll publish the BUCK changes as separate diff for simpler backout in the future.
Reviewed By: mdvacca
Differential Revision: D14019272
fbshipit-source-id: 8b322b5c115efe33c15929e008b97a05220813df
Summary: All our C++ Fabric tests are cross-platform, so it makes sense to run them for all platforms (especially because platform may behaive differently).
Reviewed By: JoshuaGross, mdvacca
Differential Revision: D13984574
fbshipit-source-id: e384c03c7f9839be38a1910e04ba2f7725abc378
Summary:
Our long-term plan is to completely illuminate `jsi::Value`-to-`folly::dynamic` serialization step in prop parsing process improving performance and memory pressure. At the same time, we don't want to introduce a hard dependency in application code to JSI because it exposes direct access to VM and prevents parsing some data that come *NOT* from JSVM.
RawValue is an extremely light-weight (hopefully fully optimized-out) abstraction that provides limited JSON-like and C++-idiomatic interface.
The current particular implementation is still using `folly::dynamic` inside, but I have fully JSI-powered one which will replace the current one right after we figure out how to deal with folly::dynamic-specific callsites. Or we can implement RawValue in a hybrid manner if a code-size implication of that will be minimal.
Reviewed By: JoshuaGross, mdvacca
Differential Revision: D13962466
fbshipit-source-id: e848522fd242f21e9e771773f2103f1c1d9d7f21
Summary: This is a temporary change to measure production data
Reviewed By: fkgozali
Differential Revision: D13906807
fbshipit-source-id: 2a2f71aa379c4aca63c7bb4a9644704f713cb088
Summary:
@public
Removes all `YG...Count` macros for enums and replaces them with `facebook::yoga::enums::count<YG...>()`.
This removes the need to manually maintain enum counts.
Same as D13597449, working around a defect in clang < 3.9
Reviewed By: amir-shalem
Differential Revision: D13634622
fbshipit-source-id: 344dc70e167b0caf746fe396cedd200f54e52219
Summary:
@public
Removes all `YG...Count` macros for enums and replaces them with `facebook::yoga::enums::count<YG...>()`.
This removes the need to manually maintain enum counts.
Reviewed By: shergin
Differential Revision: D13597449
fbshipit-source-id: edcee225ada4058e94f3a727246763e3cc45873d
Summary:
@public
The storage format of `YGValue` in `YGStyle` is an implementation detail that is going to change soon. It is only guaranteed to be assignable from, and castable to `YGValue`.
Here, we remove tight coupling from the actual implementation in React Native.
Reviewed By: shergin
Differential Revision: D13465113
fbshipit-source-id: 41dfcb90c2a1cd825a6732854bf84d4c3318d835
Summary:
@public
When switching to `CompactValue`, casting edges or dimensions to `std::array<YGValue, ...>` will do actual work.
In order to avoid that from happening implicitely, we remove the casting operator.
Reviewed By: SidharthGuglani
Differential Revision: D13464292
fbshipit-source-id: 217065b001a63cfa8adde715063682c583007a4d
Summary:
@public
Replace `YGFloatOptional::getValue()` with `YGFloatOptional::unwrap()`.
`YGFloatOptional::getValue()` has the unfortunate property of calling `std::exit` if the wrapped value is undefined.
Here, we eliminate the method, and just call `.unwrap()` everywhere.
Reviewed By: shergin
Differential Revision: D13439608
fbshipit-source-id: 5ae82b170537d0a10c301412567a7a66fd50bab4
Summary:
@public
`YGFloatOptional::getValue()` has the unfortunate property of calling `std::exit` if the wrapped value is undefined.
That forces `x.isUndefined() ? fallback : x.getValue()` as access pattern.
Here, we replace that by introducing `YGFloatOptional::orElse(float)` which encapsulates that pattern. Other additions are `orElseGet([] { … })` and some extra operators.
Reviewed By: SidharthGuglani
Differential Revision: D13209152
fbshipit-source-id: 4e5deceaaaaf8eaed44846a8c152cc8b235e815c