Summary:
Changelog: [Internal]
Using `empty()` vs `size() == 0` or `size() > 0`.
It is a more semantic way to check whether container is empty or not.
Reviewed By: JoshuaGross
Differential Revision: D21573183
fbshipit-source-id: b83283f687432a037941852114717a0f014e28db
Summary:
It's not allowed to return nullptr from the callback. The assert ensures it which is helpful during development.
Probably, we should consider using `gsl::not_null<>` here.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: sammy-SC
Differential Revision: D21149891
fbshipit-source-id: a5f77b35029f22b499491721036405682f812a38
Summary:
The diff introduces a new field in `ShadowNode` which defines in which order ShadowViews created from the node and its siblings will appear ShadowView tree. The feature will be used to overcome some platform limitations (e.g. on Android) on the mounting layer (it will be able to move some nodes of some time to the end (or beginning) of the list) and build features like zIndex ordering in C++ core.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: mdvacca
Differential Revision: D20396718
fbshipit-source-id: 16aef7c2b5511c874341ab7554e5585b2cdc356f
Summary:
Cloning subtrees is not something specific to a RootNode, so it makes sense to have it in ShadowNode. Soon we will use that to clone subtrees inside Paragraph component to implement Inline Views.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: mdvacca
Differential Revision: D20090666
fbshipit-source-id: 0a64ef9bda438cd55d5fd21d3ad83b36221fa89e
Summary:
Changelog: [Internal]
There shouldn't be any logical changes to the code.
Reviewed By: JoshuaGross
Differential Revision: D19814500
fbshipit-source-id: 2be492eebb284c7e241662d9d78117badcb2eee4
Summary:
# Problem
We calculate `stateRevision_` in constructor from children, but children change after shadowNode is initialised and before it is sealed. So the `stateRevision_` we calculate in constructor can be incorrect.
# Solution
Recalculate `stateRevision_` whenever children change. This can happen in two methods `ShadowNode::replaceChild` and `ShadowNode::appendChild`. This diff implements this solution.
Changelog: [Internal]
Reviewed By: JoshuaGross
Differential Revision: D19813840
fbshipit-source-id: 8fc3b6601e4618f4ee5b322eebc230e0bbb92e3a
Summary:
This change removes the concept of `StateTarget`, replacing its role with `ShadowNodeFamily`.
When `StateTarget` was built, we didn't have a concept of `Family`, and when we added it we introduced a retain-cycle: ShadowNode -> Family -> StateTarget -> ShadowNode. This diff fixes that.
This change does not change conceptually how the state behaves, it just adjusts internal machinery.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: sammy-SC
Differential Revision: D19799013
fbshipit-source-id: c1360bfbf6b8ac34e2a856a40047eafeb50ed070
Summary:
This implements proposal #2 in our State architecture doc: https://fb.quip.com/bm2EAVwL7jQ5
Problem description: see the text in the comment of TreeStateReconciliation.h
Solution: see also comments in TreeStateReconciliation.h.
Changelog: [internal]
Reviewed By: mdvacca
Differential Revision: D19617329
fbshipit-source-id: 845fb5fe27f2591be433b6d77799707b3516fb1a
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:
Changelog: [internal]
1. Moves `ShadowNode::getAncestors` to `ShadowNodeFamily`.
2. Exposes shadowNode's family through `ShadowNode::getFamily()`.
# Why?
This is a first step in order to merge `StateCoordinator` into `ShadowNodeFamily` and use it as target for state updates.
Reviewed By: shergin
Differential Revision: D19465188
fbshipit-source-id: b5a3625aa21c040301259de02beedbf97e11f20e
Summary:
LocalData isn't used by any components. We've moved towards State.
Changelog: [internal]
Reviewed By: mdvacca
Differential Revision: D19250732
fbshipit-source-id: dd23a723c5392632165798f6365ea107b37b54cd
Summary:
LocalData isn't used by any components. We've moved towards State.
Changelog: [internal]
Reviewed By: mdvacca
Differential Revision: D19250603
fbshipit-source-id: f95da375117dcb8f6540a6c75d3a80bba630672c
Summary:
As part of the plan is splitting ShadowNodeFragment into two parts. ShadowNodeFamilyFragment is already in place. This diff removes use of `ShadowNodeFragment::eventEmitter` and goes over all call sites to change it to `ShadowNodeFamilyFragment::surfaceId`.
Changelog: [Internal]
Reviewed By: shergin
Differential Revision: D19146697
fbshipit-source-id: 22cae5404b0f3098feb86c0437a4aa256d5b773e
Summary:
As part of the plan is splitting `ShadowNodeFragment` into two parts. `ShadowNodeFamilyFragment` is already in place. This diff removes use of `ShadowNodeFragment::surfaceId` and goes over all call sites to change it to `ShadowNodeFamilyFragment::surfaceId`.
Changelog: [Internal]
Reviewed By: shergin
Differential Revision: D19115785
fbshipit-source-id: 5972332c3360b88ca935581ed36070f26e678b22
Summary:
As part of the plan is splitting `ShadowNodeFragment` into two parts. `ShadowNodeFamilyFragment` is already in place. This diff removes use of `ShadowNodeFragment::tag` and goes over all call sites to change it to `ShadowNodeFamilyFragment::tag`.
Changelog: [Internal]
Reviewed By: shergin
Differential Revision: D19115781
fbshipit-source-id: 6ab3464a063c220d0924bf5a69b75449ca178650
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:
Before this change, all methods `ShadowNode::getComponentHandle()` and `ShadowNode::getComponentHandle()` returned the values directly from a `ComponentDescriptor` (via `ShadowNodeFamily`). Now, we store/cache those values in ShadowNodeFamily object (and ShadowNode's methods use that).
We need that to ensure that calling those methods doesn't access the `ComponentDescriptor` object because it's difficult to guarantee that this object overlives all `ShadowNode`s. This is especially important when we build `ShadowView`s from `ShadowNode`s: this might happen way after the code is already deallocated and the only living objects are MountingTransactionCoordinator and essentially two pointers to root nodes of before and after trees (that still needs to be mounted).
This diff introduces no actual changes in the ownership model.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: mdvacca
Differential Revision: D18290024
fbshipit-source-id: 4135a277515a84b053fe0d0dde48fba59bf2aae3
Summary:
`StateTarget` no longer uses `shared_from_this`, this allows us to remove need for `enable_shared_from_this`
I decided to put `state->commit` call inside `ShadowTree.cpp` because I needed to have access to `shared_ptr` of shadow node from outside of the class itself.
`state->commit` was originally designed to be only called by `ShadowNode` but this does not seem to be the case anymore since it is called from `UIManager` as well.
changelog: [internal]
Reviewed By: shergin
Differential Revision: D18032532
fbshipit-source-id: 75c874fd04f86adc07bfddbef3a0384e17c2067b
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:
We use this piece of data only for debug purposes, so there is no need to pay for that in prod.
Changelog: [Internal] - Small optimization in `ShadowNode` (Fabric)
Reviewed By: JoshuaGross
Differential Revision: D17961209
fbshipit-source-id: 2a0d609ac4d3c4815b26789551a4c51bcf91dea4
Summary:
# LegacyViewManagerInterop is born
LegacyViewManagerInterop is a component that should make it possible for legacy components to work in Fabric, new renderer.
This is just a first stage that prints keys of props to screen together with component name.
Reviewed By: shergin
Differential Revision: D17552827
fbshipit-source-id: c3e062f413727729e6a9b683c60f59f0292cc63b
Summary:
We don't need to have those methods virtual anymore.
Nowadays we have a pointer to a `ComponentDescriptor` in `ShadowNode`, it's simpler to get that value from there.
That's also more code-size friendly because we now can remove those methods from a template.
Reviewed By: sammy-SC
Differential Revision: D17142173
fbshipit-source-id: 9f54fbe6c1ebad3ed49843ed75a01ca5ee48c34f
Summary: That was always part of design, that's okay to get a newer state from any other state. We will need it in the future diffs.
Reviewed By: sammy-SC
Differential Revision: D17053429
fbshipit-source-id: 2174e7d6e3a1ed231f7f6e238d216d0b09ec8797
Summary: In some cases, we cannot retrieve the "committed" state because no one state was mounted yet. The whole concept of "confirmed" or "legit at the moment" is kinda overstatement. The actual meaning of this is "the last vision of the state to which we advanced so far"; it does not have any relation to the actual "commit" phase or "mounting" process.
Reviewed By: sammy-SC
Differential Revision: D16002127
fbshipit-source-id: 95465e632525f873ae67f6db320a89562b62ba29
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:
Trivial.
We are replacing rootTag with surfaceId according to the plan describing here: https://fb.workplace.com/groups/rn.fabric/permalink/1374002366064519/
Reviewed By: JoshuaGross, mdvacca
Differential Revision: D15039134
fbshipit-source-id: ec8c3044f9f3f23939488bc01c66e9b653e651dd
Summary:
The algorithm is quite simply:
1. Get family objects of the two nodes (inner and outer).
2. Traverse the list of family objects starting from the inner one and form a reversed list of them.
3. tarting from the inner node, traverse the tree layer-by-layer choosing a next element of the path by comparing the family object of each node on the level and an object from the list.
Reviewed By: JoshuaGross
Differential Revision: D14416950
fbshipit-source-id: 23c659a9e01690f90174193650a2b0ef09eadb4d
Summary:
One of the core feature of ShadowNodeFamily is having a pointer to a parent family. This diff implements it.
I don't think there is a hard retain cycle there, but for more lean memory usage we use weak_ptr here.
Reviewed By: JoshuaGross
Differential Revision: D14416948
fbshipit-source-id: 05fd2c4833146f007228363b1d958776b4a2a9cf
Summary:
ShadowNodeFamily is a new concept that allows us to implement an efficient way to solve the problem of finding a path to some ancestor node (practically reimplement ShadowNode::constructAncestorPath() in some efficient way).
This diff is the first one in the series. It introduces a new class and moves some data into it.
Reviewed By: JoshuaGross
Differential Revision: D14416947
fbshipit-source-id: c93865a8929a2128498e34d3589487696aac6283
Summary: In React, things like changing `tag`, `eventTarget` or reparenting are impossible by design. Which seems like a strange limitation actually allows us to do tremendous performance optimizations (stay tuned!).
Reviewed By: JoshuaGross
Differential Revision: D14402638
fbshipit-source-id: 3b7b7edaff0d55a3ca94e2ac4c753d630d07101d
Summary:
Nowadays, every ShadowNode has a reference to a ComponentDescriptor, so now there is no need to do registry lookup for that.
That should save us 0.5-1.0 ms in my non-scientific measurements.
Reviewed By: mdvacca
Differential Revision: D14348369
fbshipit-source-id: 57f6a6f2f8bf0b7e58d89a414fec20b2db8876f7
Summary:
This pull request removes the use of the GCC extension null coalescing operators (`?:`) and replaces them with ternary operators. This improves the portability of `ShadowNode.cpp` (and enables MSVC to build it)
[General] [Fixed] - Fabric: Removed null coalescing operators in `ShadowNode`
Pull Request resolved: https://github.com/facebook/react-native/pull/23438
Differential Revision: D14304958
Pulled By: shergin
fbshipit-source-id: 7d8e6778a72dabf09b1d99bc091a7578598b79c3
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:
In React Native there are several use cases where React State is not the only input that affects the component tree. E.g., in case of a <Modal> component, the screen size directly affects the layout of components inside modal; in the case of uncontrolled <TextInput> component, the text inside the input affects the layout of the surrounding components. `State` is a special (legit!) workaround for all those similar cases. Native part of React Native maintains a special shared object between all nodes of the same family and use that during cloning and commits.
See coming commits to know how to use that.
In the near future State will fully replace LocalData concept but for simplicity they both exist for now.
Reviewed By: mdvacca
Differential Revision: D14217184
fbshipit-source-id: 6e018c5b68208d662462013bce0f4e2733d2f673
Summary: This diff implements a new algorithm that effectively marks `EventEmitter`s enabled or disabled. The previous implementation relied on a list of mutation instructions whereas the new one analyzes the shadow trees. The mutations-based approach didn't work well because mutations describe `ShadowView`s whereas some `ShadowNode`s are simply not views (like VirtualText), but we have to enable/disable them anyway.
Reviewed By: sahrens
Differential Revision: D13642594
fbshipit-source-id: 12169e11d5685e50bcd0d8c410498c594df744b4
Summary:
We have to have a way to backtrack a pointer to a parent node and this is generalized version of that.
This is the first naive implementations of the algorithm. We will invest in optimizing this later.
Reviewed By: mdvacca
Differential Revision: D12920856
fbshipit-source-id: 9facb4e16a0b5608feb6747df3804952025ef093
Summary: We are moving to more stable APIs removing all mentiones of the effort name from the codebase.
Reviewed By: mdvacca
Differential Revision: D12912894
fbshipit-source-id: 4a0c6b9e7454b8b14e62d419e9e9311dc0c56e7a
Summary: This is the second and the final part of adopting clang-format.
Reviewed By: mdvacca
Differential Revision: D10229624
fbshipit-source-id: d97670b716800ea2488b84bd0aacaf54d8bd2e31
Summary: That should save us some app size kilobytes.
Reviewed By: mdvacca
Differential Revision: D10081499
fbshipit-source-id: 2b950768c609b412f9be332c22b6b1e96657e5ea
Summary: This change drops the year from the copyright headers and the LICENSE file.
Reviewed By: yungsters
Differential Revision: D9727774
fbshipit-source-id: df4fc1e4390733fe774b1a160dd41b4a3d83302a
Summary:
I was watching a classic magnificent talk about modern C++ by Herb Sutter and I was totally sold on double down on using `auto` in our codebase. Surprisingly, 95% of the code base already follows Herb's guidence; I just changed the last 5% to make it consistent.
All those changes must work *exactly* like it was before.
The talk: https://youtu.be/xnqTKD8uD64?t=28m25s
Reviewed By: mdvacca
Differential Revision: D9753301
fbshipit-source-id: 9629aa485a5d6e51806cc96306c297284d4f90b8
Summary:
@public
We don't need this anymore.
The same functionality is now implemented as `ShadowView::operator==` in much more reasonable way.
Reviewed By: sahrens
Differential Revision: D9649821
fbshipit-source-id: 8cd5f3cb4f583fd10d2d1e060aba914541341b5b
Summary:
@public
Now it accepts `const ShadowNode &` instead of `std::shared_ptr<const ShadowNode>` which is more reasonable (and more performant) becasue the function must not retain ownershipt.
Reviewed By: mdvacca
Differential Revision: D9073921
fbshipit-source-id: c24c475615e0f81b3e004e118dea7565d8e757b4
Summary:
@public
To avoid unnecessary copying of `shared_ptr`s inside ShadowNodeFragment, now we store them as `const &` references.
Reviewed By: mdvacca
Differential Revision: D8988388
fbshipit-source-id: 0b3582e57ce7577b8fa819392bf33f34e1a60b59