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:
using shared_ptr for vector of subscribers
Further changes in commit stack support the mutiple subscribers in event system
Reviewed By: davidaurelio
Differential Revision: D15352512
fbshipit-source-id: fac7f4268abf9ca4277734aca2f21cd711eb7d6e
Summary:
Replaced global event subscriber with a vector of subscriber functions
Further changes in commit stack support the mutiple subscribers in event system
Reviewed By: davidaurelio
Differential Revision: D15352451
fbshipit-source-id: 7ca6f0943735bf1f76a906c23e15e14ae3c5f42c
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: In D15252375 I made JSCallInvoker an abstract class and extended it in BridgeJSCallInvoker, but I forgot to add the `override` keyword for overridden methods.
Reviewed By: fkgozali
Differential Revision: D15328292
fbshipit-source-id: 3e75faf1b4a968b80643b8a97071ab2e122fd643
Summary:
In ContextContainer, only in Debug mode, we store type information alongside with data to detect typemismatch in runtime. We used type hashes before, but seems they are not so stable and can cause some false negative crashes.
This diff changes that to store mangled typenames instead of hashes, so it should be much more reliable now.
Reviewed By: JoshuaGross
Differential Revision: D15325728
fbshipit-source-id: 3a0f1116e1336af79adb51f38ce83c37aee4cad1
Summary: The existing implementation of JSCallInvoker holds a reference to Instance (aka the bridge). This diff makes JSCallInvoker an abstract base class that's extended by BridgeJSCallInvoker, which is what's returned by CatalystInstance to initialize TurboModules. This will allow us to add another class that derives from JSCallInvoker that doesn't rely on the bridge.
Reviewed By: shergin
Differential Revision: D15252375
fbshipit-source-id: 75eee2ca149235a63e2a2cd8cdd361b163d1d1ab
Summary:
Adds `LayoutPassStart` and `LayoutPassEnd` events.
The existing `NodeLayout` event in isolation is not as useful as it could be. Having events that mark start and end of a layout pass are a useful addition.
Differential Revision: D15305467
fbshipit-source-id: 14af6f65e698fb1e3112eb2ffd87a74d31df4840
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
Summary:
@public
`YGNodeGetInstanceCount` was only ever meant for tests, and caused data races in multi-threaded environments.
It was completely replaced with event-based counting for tests.
Here we remove public API around the counter, and the counter itself.
Reviewed By: SidharthGuglani
Differential Revision: D15174857
fbshipit-source-id: 228e85da565bac9e8485121e956a2e41910b11c8
Summary:
@public
Test utility on top of the new event system that maintains a counter of instantiated nodes. Meant to replace the global node counter.
Reviewed By: SidharthGuglani
Differential Revision: D15174855
fbshipit-source-id: 6998472f95a09b8da652257a26596164bdcf43d6
Summary:
@public
Publish two events, `NodeAllocation` and `NodeDeallocation`, in the same places where the global node counter is changed.
Reviewed By: SidharthGuglani
Differential Revision: D15174858
fbshipit-source-id: 6e4e9add88513b9e987189ca5035d76da2a1de55
Summary:
@public
Reduces measure cache size to a number that is enough for 95% of nodes, according to our (FB-internal) measurements.
Node size: 776b -> 584b
Reviewed By: SidharthGuglani
Differential Revision: D15183567
fbshipit-source-id: 9ae8cc78074271a015e7618b931ba0356de87a0c
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:
There are 2 issues:
* RCTTurboModuleManager may be initialized too late, so the module lookup from native via `[bridge moduleForClass:]` may end up going to the old system incorrectly
* In the case where JS is asking for a nativemodule, we may be incorrectly registering modules that are marked as RCTTurboModule - they should be ignored instead
Reviewed By: mmmulani, RSNara
Differential Revision: D15247632
fbshipit-source-id: 4e0fae33923810c74966b38276b206ac00723012
Summary: I don't recall why the mutation function return rvalue reference, but it is totally incorrect (the function cannot own the object, so returning a reference introducing a dungling pointer and will crash).
Reviewed By: mdvacca
Differential Revision: D15156312
fbshipit-source-id: 497d10de22a41906efe71cd10139e3710ae11a79
Summary:
PR https://github.com/facebook/react-native/pull/24633 introduced some inconsistency in crash messaging, this PR fix it. Asked by mhorowitz
[General] [Added] - Consistent reporting native module name on crash on native side
Pull Request resolved: https://github.com/facebook/react-native/pull/24704
Differential Revision: D15237424
Pulled By: cpojer
fbshipit-source-id: ded8db45b2a2ec9998ff33fdbecef3f12c19578f
Summary: Apparently it's not used anymore. And that a good this.
Reviewed By: JoshuaGross, mdvacca
Differential Revision: D15219258
fbshipit-source-id: e3258d851d1eec5955d86f99a0b0d8a1b0304cb4
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: After this change, all measuring operations based on `LayoutableShadowNode::getRelativeLayoutMetrics` will take into account the transformation matrices provided by shadow nodes. This will allow implementing scroll-offset-aware and custom-transform-aware measuring.
Reviewed By: JoshuaGross, mdvacca
Differential Revision: D15219259
fbshipit-source-id: 1d7cd8c0ee4406f4dd0002cd442dc0679391922b
Summary: The diff implements a function that applies given transformation to a point.
Reviewed By: JoshuaGross
Differential Revision: D15219263
fbshipit-source-id: 4cc0595b0dda38c1ede1f2885b800cbe57f54243
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: This diff implements encapsulating all time metrics in a single class for better extensibility and readability.
Reviewed By: JoshuaGross
Differential Revision: D15179835
fbshipit-source-id: 62bdf94435a0d37a87ad9bad613cc8e38043a235
Summary: iOS TurboModules work in OSS. I pulled out JSCallInvoker from `React-turbomodule-core`, as a part of D15055511. In this diff, I'm adding it back in.
Reviewed By: mdvacca
Differential Revision: D15195007
fbshipit-source-id: 64ee294a68c0a63ba400b8a829864c6619d3311a
Summary:
`CatalystInstanceImpl.cpp` now depends on `JSCallInvoker` and `JavaJSCallInvokerHolder`. Therefore, we need to correctly adjust the OSS builds to include these dependencies into the `libreactnativejni.so` file.
I made `ReactCommon/turbomodule/jscallinvoker` a static library `libjscallinvoker.a`. I then made `ReactAndroid/src/main/jni/react/jni`'s `libreactnativejni.so` depend on that static library. Also, because the Android NDK build system doesn't support header namespaces, I had to use the filesystem to simulate them. This is why all the `.cpp` and `.h` files for `JSCallInvoker` were moved to a `jsireact` folder.
Reviewed By: mdvacca
Differential Revision: D15194821
fbshipit-source-id: 0cee682e41db53d0619f56ad017d5882f6d554aa
Summary:
`TurboModuleManagerDelegate` is an abstract base class with the following API:
```
public TurboModule getModule(String name, ReactApplicationContext reactApplicationContext);
public CxxModuleWrapper getLegacyCxxModule(String name, ReactApplicationContext reactApplicationContext);
```
```
std::shared_ptr<TurboModule> getTurboModule(std::string name, jni::global_ref<JTurboModule> turboModule, std::shared_ptr<JSCallInvoker> jsInvoker) override;
std::shared_ptr<TurboModule> getTurboModule(std::string name, std::shared_ptr<JSCallInvoker> jsInvoker) override;
```
On the C++ side, when asked to provide a TurboModule with name `name`:
1. First, is this a CxxModule? If so:
1. Create the CxxModule and return
2. Otherwise:
1. Somehow get a Java instance of the TurboModule
2. If this Java object represents a CxxModule, like `FbReactLibSodiumModule`:
1. Grab the C++ part of this object, and wrap it in a `TurboCxxModule.cpp` and return.
3. Otherwise:
1. Wrap the Java object in a C++ HostObject and return.
This pseudocode demonstrates how we'd use `TurboModuleManagerDelegate` to implement `__turboModuleProxy`.
```
__turboModuleProxy(name, jsCallInvoker):
let cxxModule = TurboModuleManagerDelegate::getTurboModule(name, jsCallInvoker)
if (!cxxModule) {
return cxxModule;
}
// JNI Call that forwards to TurboModuleManagerDelegate.getLegacyCxxModule
let javaCxxModule : CxxModuleWrapper = TurboModuleManager.getLegacyCxxModule(name)
if (!javaCxxModule) {
return std::shared_ptr<react::TurboCxxModule>(javaCxxModule.getModule())
}
// JNI Call that forwards to TurboModuleManagerDelegate.getModule
let javaModule : TurboModule = TurboModuleManager.getModule(name)
if (!javaCxxModule) {
return TurboModuleManagerDelegate::getTurboModule(name, javaModule, jsCallInvoker)
}
return null
```
Reviewed By: mdvacca
Differential Revision: D15111335
fbshipit-source-id: c7b0aeda0e4565e3a2729e7f9604775782b6f893
Summary:
JSCallInvoker requires a `std::weak_ptr<Instance>` to create. In our C++, `CatalystInstance` is responsible for creating this `Instance` object. This `CatalystInstance` C++ initialization is separate from the `TurboModuleManager` C++ initialization. Therefore, in this diff, I made `CatalystInstance` responsible for creating the `JSCallInvoker`. It then exposes the `JSCallInvoker` using a hybrid class called `JSCallInvokerHolder`, which contains a `std::shared_ptr<JSCallInvoker>` member variable. Using `CatalystInstance.getJSCallInvokerHolder()` in TurboModuleManager.java, we get a handle to this hybrid container. Then, we pass it this hybrid object to `TurboModuleManager::initHybrid`, which retrieves the `std::shared_ptr<JSCallInvoker>` from the `JavaJSCallInvokerHandler`.
There were a few cyclic dependencies, so I had to break down the buck targets:
- `CatalystInstanceImpl.java` depends on `JSCallInvokerHolderImpl.java`, and `TurboModuleManager.java` depends on classes that are packaged with `CatalystInstanceImpl.java`. So, I had to put `JSCallInvokerHolderImpl.java` in its own buck target.
- `CatalystInstance.cpp` depends on `JavaJSCallInvokerHolder.cpp`, and `TurboModuleManager.cpp` depends on classes that are build with `CatalystInstance.cpp`. So, I had to put `JavaJSCallInvokerHolder.cpp` in its own buck target. To make things simpler, I also moved `JSCallInvoker.{cpp,h}` files into the same buck target as `JavaJSCallInvokerHolder.{cpp,h}`.
I think these steps should be enough to create the TurboModuleManager without needing a bridge:
1. Make `JSCallInvoker` an abstract base class.
2. On Android, create another derived class of `JSCallInvoker` that doesn't depend on Instance.
3. Create `JavaJSCallInvokerHolder` using an instance of this new class somewhere in C++.
4. Pass this instance of `JavaJSCallInvokerHolder` to Java and use it to create/instatiate `TurboModuleManager`.
Regarding steps 1 and 2, we can also make JSCallInvoker accept a lambda.
Reviewed By: mdvacca
Differential Revision: D15055511
fbshipit-source-id: 0ad72a86599819ec35d421dbee7e140959a26ab6
Summary: Diffing algorithm uses a small map for every layer of shadow tree; that's a lot of maps. Luckily, it does not need a complex feature-full map (which is not free to allocate and use), it needs a tiny map with a dozen values. Why do we need to pay for what we don't use? This diff introduces a trivial map optimized for constraints that we have here. (See more details in the code.)
Reviewed By: mdvacca
Differential Revision: D15200495
fbshipit-source-id: d859b68b9543253840b403e7430f945a0b76d87b
Summary:
This is a small micro-optimization in Diffing algorithm.
Seems we don't need to store full ShadowView objects in `insertedPairs` map, we can store only pointers to them. That can save memory and CPU cycles because we will not need to store full objects and copy shared pointers (which is somewhat expensive).
Reviewed By: mdvacca
Differential Revision: D15200498
fbshipit-source-id: 2a268c3ee80755555bff3317e10e679be1cf9830
Summary: Diffing is already pretty fast, but using move semantic should make it even faster. ShadowViews have shared pointers, so moving them can save us atomic counter bumps.
Reviewed By: mdvacca
Differential Revision: D15200496
fbshipit-source-id: 6fb0eb79e07cd6ae9b3100713497c634f306bc18
Summary: Convert FabricUIManager.measure params to floats. Currently we convert parameters to ints across the JNI boundary, and then back to floats several times in Java. This is unnecessary and actually makes measurements trickier. The new implementation uses floats across the JNI boundary and uses Float.POSITIVE_INFINITY to represent unconstrained values, which is consistent with Fabric C++ as well.
Reviewed By: shergin, mdvacca
Differential Revision: D15176108
fbshipit-source-id: cf849b3773007637f059279460163872f300a4aa
Summary: Looks like FBJNI exports a C Macro that does exactly what `throwIfJNIReportsPendingException` does. Therefore, I'm replacing `throwIfJNIReportsPendingException` with calls to `FACEBOOK_JNI_THROW_PENDING_EXCEPTION()`.
Reviewed By: mdvacca
Differential Revision: D15174820
fbshipit-source-id: 9dfb519352cbd5f37527675323cbabad05e31d4a
Summary:
`jclass` in `JNI` is just a regular local reference. Therefore, it's unsafe to keep a static reference to it. Link: http://journals.ecs.soton.ac.uk/java/tutorial/native1.1/implementing/refs.html.
This bug made it so that when you clicked on `getConstants` twice in the TurboModule playground, the app would crash.
Reviewed By: mdvacca
Differential Revision: D15174821
fbshipit-source-id: 13b2b8726473acc9b07306558044d26bed0db92d
Summary: Previously, we'd override the `TurboModule::get` method inside the `JavaTurboModule` class to return a special `jsi::Function` in the case that the property being accessed was "getConstants". We really don't need to do this because we can simply special-case the invocation of the `getConstants` method inside the `JavaTurboModule::invokeJavaMethod` method.
Reviewed By: mdvacca
Differential Revision: D15174822
fbshipit-source-id: 0ee705be841757d3870c908da911c3872b977a9f
Summary: We conducted an experiment with different measure cache sizes. This has now been deallocatedi (D15183473). Remove the necessary APIs.
Reviewed By: SidharthGuglani
Differential Revision: D15183486
fbshipit-source-id: a38fa5a3ab0321c2521265f7d1cd6b495efd76cf
Summary:
@public
`YGConfig::YGConfig(YGConfig*)` was not initializing the same fields as the default constructors.
Here, we make the default constructor delegate to the more specialized one to remove duplication.
Reviewed By: SidharthGuglani
Differential Revision: D15164599
fbshipit-source-id: 27247709091b7664386057d09ac67d481877871f
Summary:
* invokeMethod() ends up not useful because each platform has its own way of invoking the platform methods
* invalidate() is not necessary because there's already the destructor of each C++ class
Reviewed By: mdvacca
Differential Revision: D15187833
fbshipit-source-id: 9478ed1e6288da30c67179e03a7bc7da6043280b
Summary:
@public
We want to enable tooling, instrumentation, and statistics within Yoga without coupling these functionalities to our core code.
This commit introduces the foundations of a simple, global event system.
For the time being, we will only support a single subscriber. Should we require more than one, we can add support for it later.
Reviewed By: SidharthGuglani
Differential Revision: D15153678
fbshipit-source-id: 7d96f4c8def646a6a1b3908f946e7f81a6dba9c3
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: Instrumentation tests are expensive and flaky. Luckly this one does not need to be instrumentation one.
Reviewed By: mdvacca
Differential Revision: D15158985
fbshipit-source-id: 3c88e5a0d82db2cd00f5866c3f9956409cc8fc7f