Skip to content

Commit 786c320

Browse files
zeyapfacebook-github-bot
authored andcommitted
Add c++ AnimatedModule to DefaultTurboModules
Summary: This is added so that one can easily enables c++ AnimatedModule in open source. If an app doesn't use `RCTAnimatedModuleProvider`(ios) or `AnimatedCxxReactPackage`(android), it can fallback to this default AnimatedModule when it has both c++animated and shared backend enabled - shared backend removes the need to pass down start/stop callbacks to NativeAnimatedNodesManagerProvider, so we can cleanly initialize it as static default - RCTAnimatedModuleProvider uses the version of AnimatedModule that still relies on a dedicated CADisplayLink for start/stop - AnimatedCxxReactPackage also bundles internal ViewEventModule (for NativeViewEvents) that shares `NativeAnimatedNodesManagerProvider` with AnimatedModule, but NativeViewEvents is not needed for open source - Alternatively we could also expose `NativeAnimatedNodesManagerProvider` via UIManager so other turbomodules can also use it. However I don't think it makes sense to double down on another animation API on UIManager given we have shared backend. - This assumes DefaultTurboModules is always the fallback module provider. So it'll not override when app already uses RCTAnimatedModuleProvider or AnimatedCxxReactPackage ## Changelog: [General] [Added] - Add c++ AnimatedModule to DefaultTurboModules Differential Revision: D94244698
1 parent 00184ac commit 786c320

3 files changed

Lines changed: 94 additions & 74 deletions

File tree

packages/react-native/ReactApple/RCTAnimatedModuleProvider/RCTAnimatedModuleProvider.mm

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,10 @@ - (void)_onDisplayLinkTick
7070
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const std::string &)name
7171
jsInvoker:(std::shared_ptr<facebook::react::CallInvoker>)jsInvoker
7272
{
73-
if (facebook::react::ReactNativeFeatureFlags::cxxNativeAnimatedEnabled()) {
73+
if (facebook::react::ReactNativeFeatureFlags::cxxNativeAnimatedEnabled() &&
74+
// initialization is moved to DefaultTurboModules when using shared animated backend
75+
// TODO: T257053961 deprecate RCTAnimatedModuleProvider.
76+
!facebook::react::ReactNativeFeatureFlags::useSharedAnimatedBackend()) {
7477
if (name == facebook::react::AnimatedModule::kModuleName) {
7578
__weak RCTAnimatedModuleProvider *weakSelf = self;
7679
auto provider = std::make_shared<facebook::react::NativeAnimatedNodesManagerProvider>(

packages/react-native/ReactCommon/react/nativemodule/defaults/DefaultTurboModules.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <react/nativemodule/intersectionobserver/NativeIntersectionObserver.h>
1414
#include <react/nativemodule/microtasks/NativeMicrotasks.h>
1515
#include <react/nativemodule/webperformance/NativePerformance.h>
16+
#include <react/renderer/animated/AnimatedModule.h>
1617

1718
#ifdef REACT_NATIVE_DEBUGGER_ENABLED_DEVONLY
1819
#include <react/nativemodule/devtoolsruntimesettings/DevToolsRuntimeSettingsModule.h>
@@ -49,6 +50,13 @@ namespace facebook::react {
4950
}
5051
}
5152

53+
if (ReactNativeFeatureFlags::cxxNativeAnimatedEnabled() &&
54+
ReactNativeFeatureFlags::useSharedAnimatedBackend() &&
55+
name == AnimatedModule::kModuleName) {
56+
return std::make_shared<AnimatedModule>(
57+
jsInvoker, std::make_shared<NativeAnimatedNodesManagerProvider>());
58+
}
59+
5260
#ifdef REACT_NATIVE_DEBUGGER_ENABLED_DEVONLY
5361
if (name == DevToolsRuntimeSettingsModule::kModuleName) {
5462
return std::make_shared<DevToolsRuntimeSettingsModule>(jsInvoker);

packages/react-native/ReactCommon/react/renderer/animated/NativeAnimatedNodesManagerProvider.cpp

Lines changed: 82 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,19 @@ std::shared_ptr<NativeAnimatedNodesManager>
4545
NativeAnimatedNodesManagerProvider::getOrCreate(
4646
jsi::Runtime& runtime,
4747
std::shared_ptr<CallInvoker> jsInvoker) {
48-
if (nativeAnimatedNodesManager_ == nullptr) {
49-
auto* uiManager = &UIManagerBinding::getBinding(runtime)->getUIManager();
48+
if (nativeAnimatedNodesManager_ != nullptr) {
49+
return nativeAnimatedNodesManager_;
50+
}
51+
52+
auto* uiManager = &UIManagerBinding::getBinding(runtime)->getUIManager();
53+
54+
if (!ReactNativeFeatureFlags::useSharedAnimatedBackend()) {
55+
// === PATH 1: Legacy Backend (useSharedAnimatedBackend = false) ===
56+
// Uses the architecture with MergedValueDispatcher and
57+
// AnimatedMountingOverrideDelegate
58+
59+
// TODO: remove force casting.
60+
auto* scheduler = (Scheduler*)uiManager->getDelegate();
5061

5162
mergedValueDispatcher_ = std::make_unique<MergedValueDispatcher>(
5263
[jsInvoker](std::function<void()>&& func) {
@@ -66,8 +77,6 @@ NativeAnimatedNodesManagerProvider::getOrCreate(
6677
uiManager->synchronouslyUpdateViewOnUIThread(viewTag, props);
6778
};
6879

69-
// TODO: remove force casting.
70-
auto* scheduler = (Scheduler*)uiManager->getDelegate();
7180
auto resolvePlatformColor = [scheduler, uiManager](
7281
SurfaceId surfaceId,
7382
const RawValue& value,
@@ -84,78 +93,78 @@ NativeAnimatedNodesManagerProvider::getOrCreate(
8493
}
8594
};
8695

87-
if (ReactNativeFeatureFlags::useSharedAnimatedBackend()) {
88-
auto animationBackend = uiManager->unstable_getAnimationBackend().lock();
89-
react_native_assert(
90-
animationBackend != nullptr && "animationBackend is nullptr");
91-
animationBackend->registerJSInvoker(jsInvoker);
92-
93-
nativeAnimatedNodesManager_ =
94-
std::make_shared<NativeAnimatedNodesManager>(animationBackend);
95-
} else {
96-
nativeAnimatedNodesManager_ =
97-
std::make_shared<NativeAnimatedNodesManager>(
98-
std::move(directManipulationCallback),
99-
std::move(fabricCommitCallback),
100-
std::move(resolvePlatformColor),
101-
std::move(startOnRenderCallback_),
102-
std::move(stopOnRenderCallback_),
103-
std::move(frameRateListenerCallback_));
104-
105-
nativeAnimatedDelegate_ =
106-
std::make_shared<UIManagerNativeAnimatedDelegateImpl>(
107-
nativeAnimatedNodesManager_);
108-
}
109-
110-
addEventEmitterListener(
111-
nativeAnimatedNodesManager_->getEventEmitterListener());
112-
113-
uiManager->addEventListener(
114-
std::make_shared<EventListener>(
115-
[eventEmitterListenerContainerWeak =
116-
std::weak_ptr<EventEmitterListenerContainer>(
117-
eventEmitterListenerContainer_)](
118-
const RawEvent& rawEvent) {
119-
const auto& eventTarget = rawEvent.eventTarget;
120-
const auto& eventPayload = rawEvent.eventPayload;
121-
if (eventTarget && eventPayload) {
122-
if (auto eventEmitterListenerContainer =
123-
eventEmitterListenerContainerWeak.lock();
124-
eventEmitterListenerContainer != nullptr) {
125-
return eventEmitterListenerContainer->willDispatchEvent(
126-
eventTarget->getTag(), rawEvent.type, *eventPayload);
127-
}
128-
}
129-
return false;
130-
}));
96+
nativeAnimatedNodesManager_ = std::make_shared<NativeAnimatedNodesManager>(
97+
std::move(directManipulationCallback),
98+
std::move(fabricCommitCallback),
99+
std::move(resolvePlatformColor),
100+
std::move(startOnRenderCallback_),
101+
std::move(stopOnRenderCallback_),
102+
std::move(frameRateListenerCallback_));
103+
104+
nativeAnimatedDelegate_ =
105+
std::make_shared<UIManagerNativeAnimatedDelegateImpl>(
106+
nativeAnimatedNodesManager_);
107+
108+
animatedMountingOverrideDelegate_ =
109+
std::make_shared<AnimatedMountingOverrideDelegate>(
110+
*nativeAnimatedNodesManager_, *scheduler);
111+
112+
// Register on existing surfaces
113+
uiManager->getShadowTreeRegistry().enumerate(
114+
[animatedMountingOverrideDelegate =
115+
std::weak_ptr<const AnimatedMountingOverrideDelegate>(
116+
animatedMountingOverrideDelegate_)](
117+
const ShadowTree& shadowTree, bool& /*stop*/) {
118+
shadowTree.getMountingCoordinator()->setMountingOverrideDelegate(
119+
animatedMountingOverrideDelegate);
120+
});
131121

132-
uiManager->setNativeAnimatedDelegate(nativeAnimatedDelegate_);
122+
// Register on surfaces started in the future
123+
uiManager->setOnSurfaceStartCallback(
124+
[animatedMountingOverrideDelegate =
125+
std::weak_ptr<const AnimatedMountingOverrideDelegate>(
126+
animatedMountingOverrideDelegate_)](
127+
const ShadowTree& shadowTree) {
128+
shadowTree.getMountingCoordinator()->setMountingOverrideDelegate(
129+
animatedMountingOverrideDelegate);
130+
});
133131

134-
if (!ReactNativeFeatureFlags::useSharedAnimatedBackend()) {
135-
animatedMountingOverrideDelegate_ =
136-
std::make_shared<AnimatedMountingOverrideDelegate>(
137-
*nativeAnimatedNodesManager_, *scheduler);
138-
139-
// Register on existing surfaces
140-
uiManager->getShadowTreeRegistry().enumerate(
141-
[animatedMountingOverrideDelegate =
142-
std::weak_ptr<const AnimatedMountingOverrideDelegate>(
143-
animatedMountingOverrideDelegate_)](
144-
const ShadowTree& shadowTree, bool& /*stop*/) {
145-
shadowTree.getMountingCoordinator()->setMountingOverrideDelegate(
146-
animatedMountingOverrideDelegate);
147-
});
148-
// Register on surfaces started in the future
149-
uiManager->setOnSurfaceStartCallback(
150-
[animatedMountingOverrideDelegate =
151-
std::weak_ptr<const AnimatedMountingOverrideDelegate>(
152-
animatedMountingOverrideDelegate_)](
153-
const ShadowTree& shadowTree) {
154-
shadowTree.getMountingCoordinator()->setMountingOverrideDelegate(
155-
animatedMountingOverrideDelegate);
156-
});
157-
}
132+
uiManager->setNativeAnimatedDelegate(nativeAnimatedDelegate_);
133+
} else {
134+
// === PATH 2: Shared AnimationBackend (useSharedAnimatedBackend = true) ===
135+
// Uses the shared AnimationBackend from UIManager. The backend handles all
136+
// animation commits and platform integration internally.
137+
138+
auto animationBackend = uiManager->unstable_getAnimationBackend().lock();
139+
react_native_assert(
140+
animationBackend != nullptr && "animationBackend is nullptr");
141+
animationBackend->registerJSInvoker(jsInvoker);
142+
143+
nativeAnimatedNodesManager_ =
144+
std::make_shared<NativeAnimatedNodesManager>(animationBackend);
158145
}
146+
147+
addEventEmitterListener(
148+
nativeAnimatedNodesManager_->getEventEmitterListener());
149+
150+
uiManager->addEventListener(
151+
std::make_shared<EventListener>(
152+
[eventEmitterListenerContainerWeak =
153+
std::weak_ptr<EventEmitterListenerContainer>(
154+
eventEmitterListenerContainer_)](const RawEvent& rawEvent) {
155+
const auto& eventTarget = rawEvent.eventTarget;
156+
const auto& eventPayload = rawEvent.eventPayload;
157+
if (eventTarget && eventPayload) {
158+
if (auto eventEmitterListenerContainer =
159+
eventEmitterListenerContainerWeak.lock();
160+
eventEmitterListenerContainer != nullptr) {
161+
return eventEmitterListenerContainer->willDispatchEvent(
162+
eventTarget->getTag(), rawEvent.type, *eventPayload);
163+
}
164+
}
165+
return false;
166+
}));
167+
159168
return nativeAnimatedNodesManager_;
160169
}
161170

0 commit comments

Comments
 (0)