Summary:
Replaces `fbjs/warning` call sites in React Native with `console.warn`. A few warnings will now log as warnings without the "Warning:" prefix.
Changelog:
[General][Changed] - Some warnings changed to use `console.warn` without the "Warning:" prefix.
Reviewed By: TheSavior, cpojer
Differential Revision: D22445946
fbshipit-source-id: 96b01e1bdee52b89ff3b808bc9d6cd494f6787f5
Summary:
This implements the full NativeModuleResolvedType for each NativeModule spec, producing .java spec files in the output directory. The output files are now compiled during build time for :ReactAndroid and :packages:rn-tester:android:app.
Changelog: [Internal]
Reviewed By: mdvacca
Differential Revision: D23312858
fbshipit-source-id: c521b9d6602677fd275891cf44329740c6bd7387
Summary:
For each resolved type, define how to process its own type and whether it should produce generated code/file, minus the NativeModuleResolvedType (will be in the next commit).
Changelog: [Internal]
Reviewed By: mdvacca
Differential Revision: D23307961
fbshipit-source-id: 87af09867aace7a5ff060a33a00b141048630eda
Summary:
This is the base setup for ResolvedType. Each Type needs to be resolved to its final representation, which knows what Java type it needs, and what standalone Java code (e.g. class) it needs to produce. Individual resolved types are not yet implemented, this commit provides the flow to pass the parsed structure (from schema) to the resolution logic.
Changelog: [Internal]
Reviewed By: mdvacca
Differential Revision: D23288208
fbshipit-source-id: 18535d5fae8ca15f6d9374bdba38f57dfd4300e8
Summary:
Instead of recreating the schema structure, the generator only needs to collect the list of types that it needs to generate for. So instead, let's just add each parsed type into a map using TypeId as the key. This means every inner types in the schema needs its own unique TypeId. This was a change from the previous commit where we didn't assign unique names to the types. Here's the reasoning:
* In Java, any generated class needs to be in its own file.
* If a NativeModule spec defines a few aliases, and or inner types (function args, return type shape, etc) that needs representation with a dedicated class, we need to track them as well for code generation.
* This means, the schema format is no longer relevant for the code generation step, so let's produce a structure that's more efficient for code generation
Changelog: [Internal]
Reviewed By: mdvacca
Differential Revision: D23287818
fbshipit-source-id: 7caf4e95aeafe5c8ba336af290179b85bf87ad6d
Summary:
Changelog: [Internal]
This was set to screensize in D13104172 (https://github.com/facebook/react-native/commit/346c9d5f2c0fd99d6f05828d594d05bfaeed902f) to work around issues at that time.
The issues might not be around anymore.
Reviewed By: PeteTheHeat
Differential Revision: D23298723
fbshipit-source-id: 4f33a2cc65ae4fe5ba20b0b2b270b135878c339f
Summary:
I'm removing an ill-informed "optimization" that resulted in some StateUpdates being dropped. For some components (including TextInput) we rely on State updates to request a layout from the ShadowNode layer.
In the past we were performing an optimization that didn't update the View layer if the data contained in the State container is identical, but in the case of TextInput and other components, we simply pass an opaque
object with no meaningful data to trigger the layouts. In those cases, it could cause a permanent rift between the View layer's StateWrapper and the most recent state object from the C++ perspective.
In the case of TextInput this didn't cause tangible bugs because you can always update state using an out-of-date State object, but it's better this way anyway.
The other issue is that for some components, we want to know when there's a State update from the Cxx layer. This optimization broke certain logic in those components.
Changelog: [Internal]
Reviewed By: mdvacca
Differential Revision: D23306222
fbshipit-source-id: 8ef83149b814de50776674b5fd22406be1db14ba
Summary:
This crash was introduced in D22962320 (https://github.com/facebook/react-native/commit/ffdfbbec08b1afb1970d2cfe75a78a203d4a79a4), which landed 8/17 and went into 8/23 cut. I plan to pick this diff into that release.
I can't repro this, but there must be a scenario (in bridged mode), where we try to flush event queue while bridge is tearing down. I plan to consider this scenario going forward.
Changelog: [Internal]
Reviewed By: JoshuaGross
Differential Revision: D23306445
fbshipit-source-id: 285d4b94a17423c3b08d83e7041c4ee04b7e6d0c
Summary:
This diff ties the stack together. It completes the long chain of RCTSurfacePresenter ownership:
`FBReactModule` -> `RCTNativeAnimatedTurboModule` (this diff and D23272746)
`RCTNativeAnimatedTurboModule` -> `RCTNativeAnimatedNodesManager` (this diff)
`RCTNativeAnimatedNodesManager` -> `RCTPropsAnimatedNode` (D23272735)
It completes animations working without the bridge.
Changelog: [Internal]
Differential Revision: D23272755
fbshipit-source-id: 137f7ff89993a2cb644bd67869eb685afcec4068
Summary:
`RCTPropsAnimatedNode` uses the bridge to access it's current surface presenter to perform animations.
In bridgeless mode, the surface presenter is not owned by the bridge. Instead, pass the surface presenter through the ownership chain:
`RCTNativeAnimated*Module` -> `RCTNativeAnimatedNodesManager` -> `RCTPropsAnimatedNode`
`RCTSurfacePresenter` should not be strongly held by any of these animation internals. If it gets destroyed at a higher level, animations should not be completed.
Changelog: [Internal]
Differential Revision: D23272735
fbshipit-source-id: ce08ee3b59ac2ba70e31cebb7ba8e9f3a644c848
Summary:
The animated native module relies on `setBridge` to perform generic setup which doesn't rely on the bridge at all. This diff refactors that setup code to an `init` function.
Changelog: [Internal]
Differential Revision: D23272427
fbshipit-source-id: 0c9c5522c9044283f4db25360010465ff42aba25
Summary:
Extracts `ScrollViewContext` so that other components can use it without requiring `ScrollView` as a dependency.
Changelog:
[Internal]
Reviewed By: kacieb
Differential Revision: D22670035
fbshipit-source-id: 7f902697ad2a60cd1869438e9a2b77e479a18065
Summary:
# What is this?
For a very long time, we've discussed the possibility of detecting Node Reparenting in the Fabric Differ. Practically, from the developer perspective, ReactJS and React Native do not allow reparenting: nodes cannot be reparented, only deleted and then recreated with entirely new tags.
However, Fabric introduced the idea of View Flattening where views deemed unnecessary would be removed from the View hierarchy entirely. This is great and improves memory usage, except for one issue: if a View becomes unflattened, or becomes flattened, the entire tree underneath it must be rebuilt.
In a past diff we introduced a mechanism to detect sibling reordering cleverly, and produce a minimal instruction set. This diff is very similar: we know the invariants around flattening and unflattening of views and we take advantage of them to produce an optimal set of instructions efficiently.
# What's different from previous attempts?
No global maps! Those are slow!
This seems to work and (hopefully) might even improve performance, since way less work is being done on the UI thread in cases when views are (un)flattened.
This *only* does extra work when flattening/unflattening happens, which gives product engineers a little more control over perf.
# So, how's it work?
This algorithm is intuitively simple (I think) but tricky to pull off, because there are lots of edge-cases.
In short: In the past, that information was hidden from the Differ: the differ didn't know if views were being reparented, it would see them
as entirely new views or as views being deleted if a View was flattened or unflattened. We very subtly change the information given to the differ:
all nodes are visible to the differ, but marked as Flattened or Unflattened. Thus, when the differ compares two nodes in the "old" and "new" tree,
it can tell not just if there are updates to the node but if it has been unflattened or flattened as well.
For example, take this tree, where * indicates that a View is flattened:
```
A
+
+----+---+
B* X
+ +
| |
+---+--+ +
E F Y
```
When the Differ asks for the children of A, in the past it would get a list `[E, F, X]`. That is, B* and X are both its children, but since B is flattened, it is omitted entirely from the list and
its children are substituted.
Now, when the Differ asks for the children of A, we give it this list instead: `[B*, E, F, X]`. That is: we give it a list which includes B, but B is marked as flattened.
Another wrinkle: A node `X` could have its children flattened, but still be a concrete view: so flattening/unflattening is a different operation from making a view "concrete" or "unconcrete", which can change independently of flattening.
There is one additional wrinkle: because of zIndex/stacking order, the children of `B` might not actually appear after `B` in the list. Depending on zIndex, a tree that looks like this:
```
A
+
+------+------+
B* C*
+ +
| |
+--+--+ +--+--+
D E F G
```
Could actually be linearized as: `[D G B* F C* E]` (as an extreme example; but basically all permutations as possible).
This is the reason, and the *only* reason that the inner Flattener/Unflattener
## The cases we need to handle
There are 7 cases/edge-cases of flattening and unflattening that we need to handle. Practically, all cases of reordering + flattening/unflattening, and taking recursive cases into account:
1. View A and A' (A in the old tree, A' in the new tree) are matched in the differ, and A* has been flattened or unflattened. These two cases are the easiest to handle.
2. View A' has been reordered with its siblings, and has been flattened or unflattened. These cases are slightly trickier to handle.
3. While flattening or unflattening, we encounter a child that has also been unflattened or flattened. So we need to handle four cases here in total: Flatten-Flatten, Flatten-Unflatten, Unflatten-Flatten, and Unflatten-Unflatten.
Other things to think about, also covered above:
1. Ordering. Views can be reordered and flattened/unflattened at the same time.
2. zIndex ordering: children in a certain order from the ShadowNode perspective may be stacked differently from a View perspective. We use the zIndex ordering for everything in the differ, and this prevents us from performing certain optimizations (see above: we cannot assume that children come after their parent in a list; they may come before, may be interwoven with children from other parents, etc).
# Perf Implications?
Practically, there should be very little negative overhead. There is some overhead in actually performing a flattening/unflattening operation, but... not much more than before. We don't use global maps, so the cost of flattening/unflattening is basically `O(number of nodes reparented)` - note that that's direct nodes reparented, *not* descendants.
tl;dr the perf hit should be similar to reordering, which is non-zero, but close to zero, and zero-cost for any diff operations on parts of the tree that don't involve flattening/unflattening. AFAICT this is very close to an ideal solution for that reason (but I wish it was simpler overall).
# In Summary?
I hope this works out and I think it could improve a number of things downstream: perf, LayoutAnimations, Bindings, certain crashes because of platform assumptions about mutations, etc.
Is it worth it? This new implementation is substantially harder to reason about, harder to read, and harder to understand. This is an important consideration. All I can say there is that I trust the test suite I've been using, but
the decreased readability is a big negative. Hopefully we can improve this in the future.
The rest is fiddly implementation details that I sincerely hope can be improved and simplified in the future.
# Followups?
The part that makes this algorithm the most expensive is that because of zIndex ordering, we cannot assume that children are linearized after their parents and so we rely more heavily on maps for the flattening/unflattening. Our TinyMap implementation should make these `find` operations fast enough unless trees' children are constantly being reordered, but it's still worth thinking of ways to make this even faster.
Changelog: [Internal]
Reviewed By: shergin, mdvacca
Differential Revision: D23259341
fbshipit-source-id: 35d9b90caf262d601a31996ea2cb37e329c61ffc
Summary:
1. When testing major changes to the differ, it can be useful to have more verbose logging.
2. On Android, since asserts don't fire yet, I log which asserts are failing.
Should have no impact on any builds unless you manually set the macro here, and it will have no impact on production builds regardless.
Changelog: [Internal]
Reviewed By: shergin
Differential Revision: D23257859
fbshipit-source-id: 94a8e74ece8023064de0f2203db6074975f8f1f0
Summary:
Simplify the TextInput measurement mechanism.
Now, data only flows from JS->C++->Java and from Java->JS. C++ passes along AttributedStrings from JS if JS updates, and otherwise Java maintains the only source of truth.
Previously we tried to keep all three in sync. This was complicated, slow, and even lead to some crashes.
This feels a bit hacky but I believe it's the simplest way to achieve this short-term. Ideally, we would use something like `AttributedStringBox` and pass that to State from Java,
but currently everything passed through the State system from Java must be serializable as `folly::dynamic`. So, instead, we just cache one Spannable per TextInput component and
use ReactTag as the cache identifier for lookup.
An interesting side-effect is that `measure` could race with TextInput updates, but the race condition favors measuring the latest text, not outdated values.
Followups:
- Can we do this without copying the EditText Spannable on every keystroke? Maybe this approach is too aggressive, but I don't want a background thread measuring a Spannable as it's being mutated.
- Do we need to support measuring Attachments?
- How can we clean up this API? It should work for now, but feels a little hacky.
Changelog: [Internal]
Reviewed By: mdvacca
Differential Revision: D23290230
fbshipit-source-id: 832d2f397d30dfb17b77958af970d9c52a37e88b
Summary:
Changelog: [Internal]
# Problem
In D22274782 (https://github.com/facebook/react-native/commit/fb2b49d2982399f26b93ac02b2197c0b3813a4a9) I removed integration between Paper and Fabric. However this integration was still used by `RCTLegacyViewManagerInteropComponentView` for view commands dispatch.
Fix is to use `[RCTUIManager viewForReactTag:viewTag]` instead of viewRegistry.
Reviewed By: shergin
Differential Revision: D23291567
fbshipit-source-id: 35c50716fd8b86ae25b1534e4d8aa688c8e6e129
Summary:
Changelog: [internal]
# What is Teller?
Teller is a bank's employee who deals with the customer on behalf of the bank. In Fabric's scenario it is a class that on behalf of the view deals with State.
# Why do we need it?
Dealing with `ConcreteState` can be complicated and patterns are often repeated among different component views. `ConcreteStateTeller` aims to resolve these issues. Examples:
- You can call teller's methods without checking for nullptr (we have had crashes because of this before).
- Methods are save to be called on any thread.
- Mechanism to retry state update if it fails is built in.
It is designed to be used from ComponentView so views don't have to talk directly to `ConcreteState`.
Reviewed By: JoshuaGross, shergin
Differential Revision: D23216865
fbshipit-source-id: 90a50702e036eac084f89743ebab687a67182dc0
Summary:
On windows it is required to explicitly specify what symbols need to be exported from a DLL to make them accessible (using `__declspec(dllexport)`). I have added and expanded on existing macros to do this and added exports that were previously missing.
Changelog:
[Internal][Changed] - Allow Hermes to be compiled to a single DLL on windows
Reviewed By: mhorowitz
Differential Revision: D23084343
fbshipit-source-id: 832cb17b9e637e4c04dad479aae6c1fc190f968e
Summary:
Changelog: [Internal]
If `ConcreteShadowNode::setStateData` is called and the node is cloned before it is mounted, the cloned node will have old state before `setStateData` was called.
To solve this, simply call `setMostRecentState` on the family inside `ConcreteShadowNode::setStateData`.
Reviewed By: JoshuaGross
Differential Revision: D23283560
fbshipit-source-id: f9822fb69e4234f776d512fc02fe13ea7de64897
Summary:
This is the JS side of D23010844 (https://github.com/facebook/react-native/commit/73242b45a9f7f9ecce8f5124ac3d1665f575be74).
In the past I tried a few heuristics to guess when a batch of Animated Operations were ready, and none of these were super reliable. But it turns out we can safely allow JS to manage that explicitly.
Non-Fabric still uses the old behavior which seems fine.
Changelog: [Internal]
Reviewed By: mdvacca
Differential Revision: D23010937
fbshipit-source-id: 4a513672c166ceaa8b6daa387e46a2a95b60ce53
Summary:
In MountingManager.java in Fabric, if we drop a view with any attached views, we also drop all children. If verbose logging is turned on, log all instances of that happening.
This has no impact unless you switch the flag on manually in debug mode.
Changelog: [Internal]
Differential Revision: D23257749
fbshipit-source-id: fce4476aa47cc1b7137cd9fd2fd0241af1593288
Summary:
Instead of invoking JavaGenerator when the task is registered, do it when the task actually executes. This way, it will wait until the other task it depends on to finish executing.
Changelog: [Internal]
Reviewed By: mdvacca
Differential Revision: D23276359
fbshipit-source-id: 6aea98d97121f2dcfd83b299e38debc767f08240
Summary:
This diff moves AndroidSwitch C++ files to make them compatible with RN OSS Build
Changelog: [Internal] internal
Reviewed By: PeteTheHeat
Differential Revision: D23227861
fbshipit-source-id: 8f23c2eb266a47cb9af82f4159f64b987c14141b