Skip to content
This repository was archived by the owner on Mar 7, 2025. It is now read-only.

Commit b87c5bd

Browse files
tomekzawfluiddot
authored andcommitted
Add support for React Native 0.71 (software-mansion#3745)
## Description Closes software-mansion#3871. ### TODO - [x] Update Example app template to 0.71.0-rc.5 - [x] Update FabricExample app template to 0.71.0-rc.5 - [x] Consume shared libraries and headers from prefabs (partially done) - [x] Use `implementation "com.facebook.react:react-native` (without plus) for RN 0.71+ - [x] Use `implementation "com.facebook.react:react-native:+" // From node_modules` for older RN versions (leave as it it now) - [x] Make it work with Hermes - [x] Make it works with JSC - [x] Properly detect Hermes on Android - [x] Include `folly-flags.cmake` directly - [x] Use headers from path instead of prefabs - [x] Depend on `jscexecutor` and `hermes-executor` - [x] Fix Layout Animations on Paper due after removal of deprecated `UIImplementation` (facebook/react-native@e7d7563) - [x] Use TypeScript types directly from package - [x] Add #ifdefs for backward-incompatible code changes (e.g. `debugToken_`) - [x] Use different sourcesets for `UIImplementationProvider` - [x] Add missing `SystraceSection` in `UIManager_cloneNode` - [x] Confirm that `UIManager_cloneNode` and `UIManagerBinding` are identical to those in react-native - [x] Remove react-native.config.js - [x] Update metro-inspector-proxy patch ### Won't do - [ ] Declare dependency on `React-jsi` & `React-jsc` based on `ENV['USE_HERMES']` in RNReanimated.podspec - not necessary - [ ] Fix Jest `testEnvironment`, use `react-native-env.js` - still doesn't work - [ ] Do we still need `kotlinVersion` in build.gradle? - probably yes - [ ] Restore MBFingerTip in ReanimatedExample ### Checklist - [ ] Check compatibility with older RN versions - [ ] Check if debugging worklets with Flipper works - [ ] Check if debugging in Android Studio works
1 parent 99bcdf4 commit b87c5bd

File tree

104 files changed

+6296
-8316
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

104 files changed

+6296
-8316
lines changed

Common/cpp/Fabric/FabricUtils.cpp

Lines changed: 3 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
#include "FabricUtils.h"
99

10+
#include <react/renderer/debug/SystraceSection.h>
1011
#include <react/renderer/uimanager/UIManagerBinding.h>
1112

1213
using namespace facebook::react;
@@ -22,110 +23,10 @@ RuntimeExecutor getRuntimeExecutorFromBinding(Binding *binding) {
2223
}
2324
#endif
2425

25-
inline static const UIManagerPublic *getUIManagerPublic(
26-
const UIManager *uiManager) {
27-
return reinterpret_cast<const UIManagerPublic *>(uiManager);
28-
}
29-
3026
std::shared_ptr<const ContextContainer> getContextContainerFromUIManager(
3127
const UIManager *uiManager) {
32-
return getUIManagerPublic(uiManager)->contextContainer_;
33-
}
34-
35-
inline static UIManagerDelegate *getDelegateFromUIManager(
36-
const UIManager *uiManager) {
37-
return getUIManagerPublic(uiManager)->delegate_;
38-
}
39-
40-
void UIManager_dispatchCommand(
41-
const std::shared_ptr<UIManager> &uiManager,
42-
const ShadowNode::Shared &shadowNode,
43-
std::string const &commandName,
44-
folly::dynamic const &args) {
45-
auto delegate_ = getDelegateFromUIManager(&*uiManager);
46-
47-
// copied from UIManager.cpp
48-
if (delegate_) {
49-
delegate_->uiManagerDidDispatchCommand(shadowNode, commandName, args);
50-
}
51-
}
52-
53-
LayoutMetrics UIManager_getRelativeLayoutMetrics(
54-
const std::shared_ptr<UIManager> &uiManager,
55-
ShadowNode const &shadowNode,
56-
ShadowNode const *ancestorShadowNode,
57-
LayoutableShadowNode::LayoutInspectingPolicy policy) {
58-
// based on implementation from UIManager.cpp
59-
const auto &shadowTreeRegistry = uiManager->getShadowTreeRegistry();
60-
61-
// We might store here an owning pointer to `ancestorShadowNode` to ensure
62-
// that the node is not deallocated during method execution lifetime.
63-
auto owningAncestorShadowNode = ShadowNode::Shared{};
64-
65-
if (!ancestorShadowNode) {
66-
shadowTreeRegistry.visit(
67-
shadowNode.getSurfaceId(), [&](ShadowTree const &shadowTree) {
68-
owningAncestorShadowNode =
69-
shadowTree.getCurrentRevision().rootShadowNode;
70-
ancestorShadowNode = owningAncestorShadowNode.get();
71-
});
72-
} else {
73-
// It is possible for JavaScript (or other callers) to have a reference
74-
// to a previous version of ShadowNodes, but we enforce that
75-
// metrics are only calculated on most recently committed versions.
76-
owningAncestorShadowNode =
77-
uiManager->getNewestCloneOfShadowNode(*ancestorShadowNode);
78-
ancestorShadowNode = owningAncestorShadowNode.get();
79-
}
80-
81-
auto layoutableAncestorShadowNode =
82-
traitCast<LayoutableShadowNode const *>(ancestorShadowNode);
83-
84-
if (!layoutableAncestorShadowNode) {
85-
return EmptyLayoutMetrics;
86-
}
87-
88-
return LayoutableShadowNode::computeRelativeLayoutMetrics(
89-
shadowNode.getFamily(), *layoutableAncestorShadowNode, policy);
90-
}
91-
92-
ShadowNode::Shared UIManager_cloneNode(
93-
const UIManager *uiManager,
94-
const ShadowNode::Shared &shadowNode,
95-
const ShadowNode::SharedListOfShared &children,
96-
const RawProps *rawProps) {
97-
auto delegate_ = getDelegateFromUIManager(uiManager);
98-
auto contextContainer_ = getContextContainerFromUIManager(uiManager);
99-
100-
// copied from UIManager.cpp
101-
PropsParserContext propsParserContext{
102-
shadowNode->getFamily().getSurfaceId(), *contextContainer_.get()};
103-
104-
auto &componentDescriptor = shadowNode->getComponentDescriptor();
105-
auto clonedShadowNode = componentDescriptor.cloneShadowNode(
106-
*shadowNode,
107-
{
108-
/* .props = */
109-
rawProps ? componentDescriptor.cloneProps(
110-
propsParserContext, shadowNode->getProps(), *rawProps)
111-
: ShadowNodeFragment::propsPlaceholder(),
112-
/* .children = */ children,
113-
});
114-
115-
if (delegate_) {
116-
delegate_->uiManagerDidCloneShadowNode(
117-
*shadowNode.get(), *clonedShadowNode);
118-
}
119-
120-
return clonedShadowNode;
121-
}
122-
123-
void UIManager_appendChild(
124-
const ShadowNode::Shared &parentShadowNode,
125-
const ShadowNode::Shared &childShadowNode) {
126-
// copied from UIManager.cpp
127-
auto &componentDescriptor = parentShadowNode->getComponentDescriptor();
128-
componentDescriptor.appendChild(parentShadowNode, childShadowNode);
28+
return reinterpret_cast<const UIManagerPublic *>(uiManager)
29+
->contextContainer_;
12930
}
13031

13132
} // namespace reanimated

Common/cpp/Fabric/FabricUtils.h

Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,16 @@
22
#ifdef RCT_NEW_ARCH_ENABLED
33

44
#ifdef ANDROID
5-
#include <Binding.h>
65
#include <fbjni/fbjni.h>
6+
#include <react/fabric/Binding.h>
77
#endif
88
#include <react/renderer/uimanager/UIManager.h>
99

1010
#include <memory>
1111
#include <string>
1212

13-
using namespace facebook::react;
13+
using namespace facebook;
14+
using namespace react;
1415

1516
namespace reanimated {
1617

@@ -52,28 +53,6 @@ RuntimeExecutor getRuntimeExecutorFromBinding(Binding *binding);
5253
std::shared_ptr<const ContextContainer> getContextContainerFromUIManager(
5354
const UIManager *uiManager);
5455

55-
void UIManager_dispatchCommand(
56-
const std::shared_ptr<UIManager> &uiManager,
57-
const ShadowNode::Shared &shadowNode,
58-
std::string const &commandName,
59-
folly::dynamic const &args);
60-
61-
LayoutMetrics UIManager_getRelativeLayoutMetrics(
62-
const std::shared_ptr<UIManager> &uiManager,
63-
ShadowNode const &shadowNode,
64-
ShadowNode const *ancestorShadowNode,
65-
LayoutableShadowNode::LayoutInspectingPolicy policy);
66-
67-
ShadowNode::Shared UIManager_cloneNode(
68-
const UIManager *uiManager,
69-
const ShadowNode::Shared &shadowNode,
70-
const ShadowNode::SharedListOfShared &children = nullptr,
71-
const RawProps *rawProps = nullptr);
72-
73-
void UIManager_appendChild(
74-
const ShadowNode::Shared &parentShadowNode,
75-
const ShadowNode::Shared &childShadowNode);
76-
7756
} // namespace reanimated
7857

7958
#endif // RCT_NEW_ARCH_ENABLED

Common/cpp/Fabric/ReanimatedUIManagerBinding.cpp

Lines changed: 54 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
#include "FabricUtils.h"
55
#include "NewestShadowNodesRegistry.h"
66

7+
#include <react/renderer/debug/SystraceSection.h>
8+
79
#include <utility>
810

911
using namespace facebook;
@@ -51,7 +53,7 @@ ReanimatedUIManagerBinding::ReanimatedUIManagerBinding(
5153
RuntimeExecutor runtimeExecutor,
5254
std::unique_ptr<EventHandler const> eventHandler,
5355
std::shared_ptr<NewestShadowNodesRegistry> newestShadowNodesRegistry)
54-
: UIManagerBinding(uiManager, runtimeExecutor),
56+
: UIManagerBinding(uiManager),
5557
uiManager_(std::move(uiManager)),
5658
newestShadowNodesRegistry_(newestShadowNodesRegistry) {
5759
if (eventHandler != nullptr) {
@@ -62,25 +64,44 @@ ReanimatedUIManagerBinding::ReanimatedUIManagerBinding(
6264

6365
ReanimatedUIManagerBinding::~ReanimatedUIManagerBinding() {}
6466

65-
static inline ShadowNode::Shared cloneNode(
67+
static inline ShadowNode::Shared cloneNodeUsingNewest(
6668
UIManager *uiManager,
6769
NewestShadowNodesRegistry *newestShadowNodesRegistry,
68-
const ShadowNode::Shared &shadowNode,
69-
const ShadowNode::SharedListOfShared &children = nullptr,
70-
const RawProps *rawProps = nullptr) {
70+
ShadowNode const &shadowNode,
71+
ShadowNode::SharedListOfShared const &children = nullptr,
72+
RawProps const *rawProps = nullptr) {
7173
{
7274
auto lock = newestShadowNodesRegistry->createLock();
73-
auto newest = newestShadowNodesRegistry->get(shadowNode->getTag());
75+
auto newest = newestShadowNodesRegistry->get(shadowNode.getTag());
7476
if (newest != nullptr) {
7577
// ShadowNode managed by Reanimated, use newest ShadowNode from registry
76-
auto clone = UIManager_cloneNode(uiManager, newest, children, rawProps);
78+
auto clone = uiManager->cloneNode(*newest, children, rawProps);
7779
newestShadowNodesRegistry->update(clone);
7880
return clone;
7981
}
8082
} // release lock since we don't need registry anymore
8183

8284
// ShadowNode not managed by Reanimated (yet?)
83-
return UIManager_cloneNode(uiManager, shadowNode, children, rawProps);
85+
return uiManager->cloneNode(shadowNode, children, rawProps);
86+
}
87+
88+
static inline void appendChildUsingNewest(
89+
UIManager *uiManager,
90+
NewestShadowNodesRegistry *newestShadowNodesRegistry,
91+
const ShadowNode::Shared &parentShadowNode,
92+
const ShadowNode::Shared &childShadowNode) {
93+
{
94+
auto lock = newestShadowNodesRegistry->createLock();
95+
auto newestChildShadowNode =
96+
newestShadowNodesRegistry->get(childShadowNode->getTag());
97+
if (newestChildShadowNode != nullptr) {
98+
uiManager->appendChild(parentShadowNode, newestChildShadowNode);
99+
return;
100+
}
101+
} // release lock since we don't need registry anymore
102+
103+
// child ShadowNode not managed by Reanimated (yet?)
104+
uiManager->appendChild(parentShadowNode, childShadowNode);
84105
}
85106

86107
jsi::Value ReanimatedUIManagerBinding::get(
@@ -94,6 +115,7 @@ jsi::Value ReanimatedUIManagerBinding::get(
94115

95116
// based on implementation from UIManagerBinding.cpp
96117
auto methodName = name.utf8(runtime);
118+
SystraceSection s("ReanimatedUIManagerBinding::get", "name", methodName);
97119
UIManager *uiManager = uiManager_.get();
98120
NewestShadowNodesRegistry *newestShadowNodesRegistry =
99121
newestShadowNodesRegistry_.get();
@@ -106,15 +128,15 @@ jsi::Value ReanimatedUIManagerBinding::get(
106128
1,
107129
[uiManager, newestShadowNodesRegistry](
108130
jsi::Runtime &runtime,
109-
jsi::Value const &thisValue,
131+
jsi::Value const & /*thisValue*/,
110132
jsi::Value const *arguments,
111-
size_t count) noexcept -> jsi::Value {
133+
size_t /*count*/) noexcept -> jsi::Value {
112134
return valueFromShadowNode(
113135
runtime,
114-
cloneNode(
136+
cloneNodeUsingNewest(
115137
uiManager,
116138
newestShadowNodesRegistry,
117-
shadowNodeFromValue(runtime, arguments[0])));
139+
*shadowNodeFromValue(runtime, arguments[0])));
118140
});
119141
}
120142

@@ -126,15 +148,15 @@ jsi::Value ReanimatedUIManagerBinding::get(
126148
1,
127149
[uiManager, newestShadowNodesRegistry](
128150
jsi::Runtime &runtime,
129-
jsi::Value const &thisValue,
151+
jsi::Value const & /*thisValue*/,
130152
jsi::Value const *arguments,
131-
size_t count) noexcept -> jsi::Value {
153+
size_t /*count*/) noexcept -> jsi::Value {
132154
return valueFromShadowNode(
133155
runtime,
134-
cloneNode(
156+
cloneNodeUsingNewest(
135157
uiManager,
136158
newestShadowNodesRegistry,
137-
shadowNodeFromValue(runtime, arguments[0]),
159+
*shadowNodeFromValue(runtime, arguments[0]),
138160
ShadowNode::emptySharedShadowNodeSharedList()));
139161
});
140162
}
@@ -147,16 +169,16 @@ jsi::Value ReanimatedUIManagerBinding::get(
147169
2,
148170
[uiManager, newestShadowNodesRegistry](
149171
jsi::Runtime &runtime,
150-
jsi::Value const &thisValue,
172+
jsi::Value const & /*thisValue*/,
151173
jsi::Value const *arguments,
152-
size_t count) noexcept -> jsi::Value {
174+
size_t /*count*/) noexcept -> jsi::Value {
153175
auto const &rawProps = RawProps(runtime, arguments[1]);
154176
return valueFromShadowNode(
155177
runtime,
156-
cloneNode(
178+
cloneNodeUsingNewest(
157179
uiManager,
158180
newestShadowNodesRegistry,
159-
shadowNodeFromValue(runtime, arguments[0]),
181+
*shadowNodeFromValue(runtime, arguments[0]),
160182
nullptr,
161183
&rawProps));
162184
});
@@ -170,16 +192,16 @@ jsi::Value ReanimatedUIManagerBinding::get(
170192
2,
171193
[uiManager, newestShadowNodesRegistry](
172194
jsi::Runtime &runtime,
173-
jsi::Value const &thisValue,
195+
jsi::Value const & /*thisValue*/,
174196
jsi::Value const *arguments,
175-
size_t count) noexcept -> jsi::Value {
197+
size_t /*count*/) noexcept -> jsi::Value {
176198
auto const &rawProps = RawProps(runtime, arguments[1]);
177199
return valueFromShadowNode(
178200
runtime,
179-
cloneNode(
201+
cloneNodeUsingNewest(
180202
uiManager,
181203
newestShadowNodesRegistry,
182-
shadowNodeFromValue(runtime, arguments[0]),
204+
*shadowNodeFromValue(runtime, arguments[0]),
183205
ShadowNode::emptySharedShadowNodeSharedList(),
184206
&rawProps));
185207
});
@@ -190,21 +212,16 @@ jsi::Value ReanimatedUIManagerBinding::get(
190212
runtime,
191213
name,
192214
2,
193-
[newestShadowNodesRegistry](
215+
[uiManager, newestShadowNodesRegistry](
194216
jsi::Runtime &runtime,
195-
jsi::Value const &thisValue,
217+
jsi::Value const & /*thisValue*/,
196218
jsi::Value const *arguments,
197-
size_t count) noexcept -> jsi::Value {
198-
auto parent = shadowNodeFromValue(runtime, arguments[0]);
199-
auto child = shadowNodeFromValue(runtime, arguments[1]);
200-
{
201-
auto lock = newestShadowNodesRegistry->createLock();
202-
auto newest = newestShadowNodesRegistry->get(child->getTag());
203-
if (newest != nullptr) {
204-
child = newest;
205-
}
206-
}
207-
UIManager_appendChild(parent, child);
219+
size_t /*count*/) noexcept -> jsi::Value {
220+
appendChildUsingNewest(
221+
uiManager,
222+
newestShadowNodesRegistry,
223+
shadowNodeFromValue(runtime, arguments[0]),
224+
shadowNodeFromValue(runtime, arguments[1]));
208225
return jsi::Value::undefined();
209226
});
210227
}

Common/cpp/NativeModules/NativeReanimatedModule.cpp

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -597,9 +597,7 @@ void NativeReanimatedModule::dispatchCommand(
597597
ShadowNode::Shared shadowNode = shadowNodeFromValue(rt, shadowNodeValue);
598598
std::string commandName = stringFromValue(rt, commandNameValue);
599599
folly::dynamic args = commandArgsFromValue(rt, argsValue);
600-
601-
// TODO: use uiManager_->dispatchCommand once it's public
602-
UIManager_dispatchCommand(uiManager_, shadowNode, commandName, args);
600+
uiManager_->dispatchCommand(shadowNode, commandName, args);
603601
}
604602

605603
jsi::Value NativeReanimatedModule::measure(
@@ -608,11 +606,8 @@ jsi::Value NativeReanimatedModule::measure(
608606
// based on implementation from UIManagerBinding.cpp
609607

610608
auto shadowNode = shadowNodeFromValue(rt, shadowNodeValue);
611-
// TODO: use uiManager_->getRelativeLayoutMetrics once it's public
612-
// auto layoutMetrics = uiManager_->getRelativeLayoutMetrics(
613-
// *shadowNode, nullptr, {/* .includeTransform = */ true});
614-
auto layoutMetrics = UIManager_getRelativeLayoutMetrics(
615-
uiManager_, *shadowNode, nullptr, {/* .includeTransform = */ true});
609+
auto layoutMetrics = uiManager_->getRelativeLayoutMetrics(
610+
*shadowNode, nullptr, {/* .includeTransform = */ true});
616611

617612
if (layoutMetrics == EmptyLayoutMetrics) {
618613
// Originally, in this case React Native returns `{0, 0, 0, 0, 0, 0}`, most
@@ -626,7 +621,8 @@ jsi::Value NativeReanimatedModule::measure(
626621

627622
auto layoutableShadowNode =
628623
traitCast<LayoutableShadowNode const *>(newestCloneOfShadowNode.get());
629-
facebook::react::Point originRelativeToParent = layoutableShadowNode
624+
facebook::react::Point originRelativeToParent =
625+
layoutableShadowNode != nullptr
630626
? layoutableShadowNode->getLayoutMetrics().frame.origin
631627
: facebook::react::Point();
632628

0 commit comments

Comments
 (0)