Summary: `Target` inside the Stage can be empty; in this case, we should not try to extract `ShadowNode` from it.
Reviewed By: JoshuaGross, mdvacca
Differential Revision: D15982479
fbshipit-source-id: 83a4bebadc88b59d7fe77acbdf07e8ce9f2f6be1
Summary:
The previous version of a set of default values of `ShadowView`'s fields has a bug:
```
ComponentName componentName = "";
```
Initalizing `char const *` with a string literal in .h file makes the default constructor of the object produces different values across binary units (because a pointer to empty string can be defined differently). Now it's just a null pointer.
Reviewed By: sammy-SC
Differential Revision: D15911452
fbshipit-source-id: 16bcfb5f78ea802c0833135c486e3fbb8b7acaa6
Summary: I am about to change the definition of ShadowView a bit, so I think we need to ensure that we don't regress move semantic.
Reviewed By: JoshuaGross, sammy-SC
Differential Revision: D15911453
fbshipit-source-id: ce2cd4cb2375ecb76295948a1e9b5d2e7fb80f38
Summary: Returning a shared pointer by const reference in this context is not correct/safe because the object (the ShadowNode) doesn't own the object, so the caller cannot reason about the lifetime (esp. in a multithreaded environment).
Reviewed By: mdvacca
Differential Revision: D15958737
fbshipit-source-id: 8f03e6530d07d63ece5f955055c5c67c204b8223
Summary:
It's unclear why, but the introspection infra is enabled somehow in prod.
It must be some kind of misconfiguration somewhere. Until we figure it now, we have to disable it completly.
Reviewed By: mdvacca
Differential Revision: D15908765
fbshipit-source-id: 2b17c61938731d43eaef51b070a4ec1ae9e5e1df
Summary:
ComponentName is used by many core component of React Native, such as ComponentDescriptor, ShadowNode, ShadowView and so on. In all those cases this value represents the actual name of the component which came from `concreteComponentName` template parameter of ConcreteShadowNode. In all of those cases, it's raw `char const *` type. So, we don't need to use owning representation of the string (std::string) in all those places.
The only exception from this is a part where we receive the name of the component from JS side. In this case, the source string comes from JS and has to be analyzed as a character sequence to find corresponding ComponentDescriptor.
In my experiments, 20% of the time during diffing is spent on copying (this) `std::string`.
Reviewed By: mdvacca
Differential Revision: D15844407
fbshipit-source-id: a2e71505e22d09107e001bdf661d4a826bcf2dea
Summary: Seems RCTImageLoader is not thread-safe, so we need to compensate for this for now. Classic RN mostly accesses the loader from the main thread (non-concurrently), so it mostly works for Paper.
Reviewed By: mdvacca
Differential Revision: D15867574
fbshipit-source-id: 4aad5570b57a136aa0bbe31d65f1afe2ae6e380e
Summary:
This diff reimplements the prop parsing infrastructure in a part where it interacts with RawProps value.
Local synthetic tests show that the new way is 3x faster but the actual production result is quite unpredictable. MobileLab tests show some improvements about 10-20 ms on iPhone 6.
In short, the new way is faster because it inverts the lookup order and heavily relies on actual data types (and their properties) that we use. The old approach required about 130 hash-map lookups (where the key is `std::string`) to parse a single *Props object.
The new approach prepares concrete-props-specific tables with indexes of coming values ahead of time, iterates over raw data and puts it into those tables, and then performs a lookup in a very efficient manner.
Reviewed By: JoshuaGross
Differential Revision: D15752968
fbshipit-source-id: 847106e652eb7fc7ef7b99884a6f819ea3b9fd06
Summary: Even though it makes no sense to construct RootProps from RawProps, we need to support that (even if it's no-op) to be able to call this once from generic `ConcreteComponentDescriptor`. We will need it in the coming diff.
Reviewed By: mdvacca
Differential Revision: D15752970
fbshipit-source-id: b75a4023c5d0425a8dbe0f104a36a0f265eb6084
Summary:
In theory, those annotations can help the compiler to emit more optimized code and/or code that suggest CPU the proper way to utilize the instruction pipeline after the coming branch.
TBH, it's not clear how exactly beneficial those annotations are (esp. on target architectures) but they certainly don't hurt (in all cases here the favorite code branch is obvious).
Reviewed By: mdvacca
Differential Revision: D15752969
fbshipit-source-id: 8adf25a48107ffde828f735fb1386b30dbe63ede
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: This is a small perf tweak that alone does not give much improvement but the coming diffs will rely on the possibility to construct empty RawProps object.
Reviewed By: mdvacca
Differential Revision: D15511494
fbshipit-source-id: 39dec9336e6b5cf6ad33b1f3a06ca1c096ece628
Summary:
Address Sanitizer told me that I have UB in `RCTUIFontWeightFromFloat` and it was right. After a short investigation, I find out that the original assumption that `UIFontWeight` values are practically numbers from 100 to 900 was incorrect. In my simulator, it's something like from `-1` to `+1` (irregularly!). So, the whole subsystem worked only by accident.
This diff fixes that; now we never assume which actual values `UIFontWeight` constants have.
I will publish code style fixes as a separate diff (otherwise it will be really hard to review).
Reviewed By: JoshuaGross
Differential Revision: D15756620
fbshipit-source-id: d7f888e85815d863487c6b68a960e39fd473e095
Summary: This is a temporary backout of D14817454, to verify if this is related T45503571
Reviewed By: JoshuaGross
Differential Revision: D15780018
fbshipit-source-id: 455034ce7b7096101db93a8604b77e1233db1137
Summary:
... and slighly new behaviour for one of them.
The method does nothing if given `key` already exists in the container.
This diff finishes the transition of ContextContainer from an internal bag of things with unclear yet ownership into a legit dedicated dependency injection container for the product code.
The original names of methods imply that the container can have only one object of a given type which is no longer true. The new API is much more generic and idiomatic to C++, it mimics `std:map` API which is intuitive to anyone who familiar with C++ containers.
Besides the naming, `insert` method changed the semantic a bit; now it does nothing in case of inserting an object with a key that already exists. That might seem counterintuitive for "normal" people, but C++ has some wired reasons for that and, hopefully, it's expected behavior in the C++ community.
Fun fact: We need this to fix hot-reload.
Reviewed By: sahrens
Differential Revision: D15681736
fbshipit-source-id: 194f342528446a911eaf072ba3a94a5d8af3cb52
Summary:
And, btw, the tests show that performance of that is not so great:
```
Running /Users/shergin/fbsource/fbobjc/buck-out/cells/fbsource/gen/xplat/js/react-native-github/ReactCommon/fabric/core/benchmarks
Run on (12 X 2900 MHz CPU s)
CPU Caches:
L1 Data 32K (x6)
L1 Instruction 32K (x6)
L2 Unified 262K (x6)
L3 Unified 12582K (x1)
--------------------------------------------------------------------------------------------
Benchmark Time CPU Iterations
--------------------------------------------------------------------------------------------
propParsingUsingComponentDescriptor 79630 ns 77991 ns 8864
propParsingUsingComponentDescriptorWithNoSourceProps 70200 ns 69099 ns 8362
```
Which means 70ms per 1000 prop parsing processes.
Reviewed By: JoshuaGross, mdvacca
Differential Revision: D15608677
fbshipit-source-id: ed4feca489e1243adc73de4741c287256c3aaec3
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: Right now we render a surface by calling `AppRegistry.runApplication`, but the way we do this relies on the batched bridge. For Venice (bridgeless RN) I created a new module for registering a surface called SurfaceRegistry, which uses a global variable instead of registering itself as a callable module on the bridge. If that global variable exists, we can use that to start the surface instead of calling AppRegistry.
Reviewed By: sahrens
Differential Revision: D15502241
fbshipit-source-id: 0b8d4677f1df41f46d84444567a30e40e21fed3d
Summary: This diff creates the base classes for MapBuffer and its tests
Reviewed By: shergin
Differential Revision: D15550730
fbshipit-source-id: a5a47edebd7c3e1b8b2c3ad2006aee0f8bdb7866
Summary:
While ViewConfig infra isn't perfect we need to check that for correcness.
See the task for more details.
Reviewed By: JoshuaGross
Differential Revision: D15578675
fbshipit-source-id: c99c2be9c215e6b9d7ee8e6e50d85e822c1f007e
Summary: Create structure of C++ side of mapbuffer project
Reviewed By: shergin
Differential Revision: D15529650
fbshipit-source-id: b563d3fbcfddcf46802ccb202e372233baad123d
Summary:
We currently have two different codepaths for actually rendering a surface with Fabric on iOS and Android: on iOS we use Fabric's `UIManagerBinding.startSurface` to call `AppRegistry.runApplication`, but on Android we don't; instead we use the same codepath as paper, calling `ReactRootView.runApplication`.
This diff does a few different things:
1. Unify iOS and Android by removing the `#ifndef` for Android so that we call `startSurface` for both
2. Pass through the JS module name on Android so that this actually works (it currently passes in an empty string)
3. Remove the call to `ReactRootView.runApplication` for Fabric so that we don't end up doing this twice
4. Copy over some logic that we need from `ReactRootView.runApplication` (make sure that root layout specs get updated, and that content appeared gets logged)
Reviewed By: mdvacca
Differential Revision: D15501666
fbshipit-source-id: 5c96c8cf036261cb99729b1dbdff0f7c09a32d76
Summary:
We are not sure yet how exactly this should work semantically (e.g. should unbatched events flash previously dispatched batched or not).
So, let's disable that until we have all answers.
Reviewed By: mdvacca
Differential Revision: D15498191
fbshipit-source-id: 77f07c5e86bfbfd212505df8cc6530e39531b5ef
Summary:
Right now calling FabricUIManager.addRootView() doesn't actually start running the application on Android. This diff:
1. Removes the #ifndef so that we actually call UIManagerBinding.startSurface() on Android
2. Passes through the JS module name from addRootView so we can render the surface (falls back to an empty string if not provided, which is the current behavior)
3. Adds an option for starting the surface using `RN$SurfaceRegistry` instead of `AppRegistry`, if that global property has been defined in JS. This is used for Venice (bridgeless RN)
Reviewed By: shergin
Differential Revision: D15366200
fbshipit-source-id: 4a506a589108905d4852b9723aac6fb0fad2d86e
Summary:
Set `sizeMultiplier` to `1.0` if default value is `NAN`, otherwise, text cannot show properly.
## Changelog
[iOS] [Fixed] - Add NAN check for text font sizeMultiplier
Pull Request resolved: https://github.com/facebook/react-native/pull/24966
Differential Revision: D15466559
Pulled By: shergin
fbshipit-source-id: 6f8b47eb8e521cb120d7f351cba02dbf1c5411fd
Summary:
This diff restores the original role of StateData as a dummy class that has only one purpose - designate that there is no state associated with the node.
I believe having an abstract StateData class for all data types is not necessary and actually slightly harmful. And here the reasons:
* Having virtual dispatch enabled for classes introduces some overhead, and it should be used only if it is absolutely necessary. In this case, we don't need to have virtual dispatch enabled for Data classes because it's already enabled for State classes; therefore all virtual resolution is done there and that's sufficient. No need to pay for what we don't need.
* Continuing the previous point, yes, we expect some API being exposed for Data classes (such as `getDynamic`), but introducing a base abstract class for that is *not* an idiomatic C++ solution; in C++ it's by design that most of the template contracts are actually duck-typed. This is a well-known design issue/concern that will be addressed with an effort called "Concepts" in C++20. Anyway, we should not use abstract classes as *only* indication of conformance to some interface.
* StateData does not introduce any convenience. As it is clear from several subclass implementations, we don't really use base methods from it.
* The previous issue actually happens especially because of the interface of StateData class. Consider constructor that accepts `folly::dynamic` and does nothing, it actually useless because it's impossible to use it unless it's called inside superclass's constructor. That's the case because C++ does not support virtual dispatch for constructors (for good).
* Avoiding subclassing StateData counter-intuitively enforces the desired conformance to imaginary interface: it does not compile otherwise.
Reviewed By: JoshuaGross
Differential Revision: D15342338
fbshipit-source-id: 1f04f7fc5247499e7cfc09cd4b3cccffdc0b6b06
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:
Updates the paragraph component to use State instead of Local Data, part of the path to a Fabric TextInput 💯
## Changelog
[General] [Changed] - Fabric: Use State instead of Local Data for Paragraph
Pull Request resolved: https://github.com/facebook/react-native/pull/24873
Differential Revision: D15410979
Pulled By: shergin
fbshipit-source-id: 3c9517d2495a64c4dbd213b6efb5ff55287900e3
Summary:
Straightforward.
Rick, I rename some stuff, I hope you are cool with that.
Reviewed By: mdvacca
Differential Revision: D15403306
fbshipit-source-id: 1dbd34060052a9bd39ed4211010f14b76fffcde6
Summary: This is implementation of standard PullToRefresh component that uses standard iOS component and modern integration approach.
Reviewed By: mdvacca
Differential Revision: D15403308
fbshipit-source-id: 5c877f7c18af9f5ac40e15a4ba44118614ba80bc
Summary:
This is the final piece of change that makes measuring (`LayoutableShadowNode::getRelativeLayoutMetrics()`) take ScrollView content offset into account (on iOS).
It works pretty simply: at the end of scrolling (or zooming) action ScrollView updates the state which later can be used for computing `transform` which measuring uses to adjust values in LaoutMetrics.
Reviewed By: mdvacca
Differential Revision: D15323688
fbshipit-source-id: fdf86c6cd9bdfd56caddd4b39bdd1185760b9f94
Summary: Seems we need this now to enable future improvements in ScrollView such as correct measure, pull-to-refresh and so on.
Reviewed By: mdvacca
Differential Revision: D15323687
fbshipit-source-id: fae37431ccbbf2faec9c84752396153689b873ef
Summary: A couple of new methods in ConcreteShadowNode allows us to deal with State in more LocalData-like manner.
Reviewed By: mdvacca
Differential Revision: D15323686
fbshipit-source-id: ede4aa1f1d0ad6f876bd963e57a00a0ad470c1c0
Summary:
The `measure` API receives LocalData and Props, it should also receive State.
This will also be used in future diffs.
Reviewed By: mdvacca
Differential Revision: D15325182
fbshipit-source-id: 6cb46dd603ce7d46673def16f0ddb517e2cf0c4f
Summary:
Previously the pointScaleFactor field was not being compared properly in LayoutMetrics equality method.
This diff fixes that
Reviewed By: shergin
Differential Revision: D15303555
fbshipit-source-id: 8863e9e1fbad15b43400afc32b97bf6d252cbe55
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:
ImageLoader is an actual external dependency, not a ImageManager.
That change allows to remove dependency on ImageManager from SurfacePresenter and make some other code simpler.
Reviewed By: mdvacca
Differential Revision: D15242047
fbshipit-source-id: 8622d15b8fdb5c3a7e25091adf7be1108f87ecd5
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