Skip to content

Commit 3a55feb

Browse files
zeyapfacebook-github-bot
authored andcommitted
Serve C++ Native Animated from core (non sharedbackend path) (#57179)
Summary: ## Changelog: [Internal] - Serve C++ Native Animated from core (non sharedbackend path) Wire the C++ implementation of Native Animated (the `AnimatedModule`) into the framework core so that, when `cxxNativeAnimatedEnabled` is enabled, it is served without per-app wiring. The flag is flipped in a separate diff. Android drives the animated render loop internally, so `DefaultTurboModules` serves `AnimatedModule` whenever `cxxNativeAnimatedEnabled` is on. iOS/macOS need the platform `RCTAnimatedModuleProvider` to drive rendering when the shared animated backend is off; with the shared backend on, `DefaultTurboModules` serves it instead. The default `RCTReactNativeFactory` delegate installs the provider, and a `React-RCTAnimatedModuleProvider` podspec is added for CocoaPods. Reviewed By: christophpurrer Differential Revision: D108197770
1 parent 549e4e2 commit 3a55feb

6 files changed

Lines changed: 97 additions & 2 deletions

File tree

packages/react-native/Libraries/AppDelegate/RCTDefaultReactNativeFactoryDelegate.mm

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,16 @@
1313
#import <React/RCTHermesInstanceFactory.h>
1414
#endif
1515

16+
#import <RCTAnimatedModuleProvider/RCTAnimatedModuleProvider.h>
17+
#import <react/featureflags/ReactNativeFeatureFlags.h>
1618
#import <react/nativemodule/defaults/DefaultTurboModules.h>
1719

18-
@implementation RCTDefaultReactNativeFactoryDelegate
20+
@implementation RCTDefaultReactNativeFactoryDelegate {
21+
// C++ Native Animated provider, created once on first use (getTurboModule: may be called
22+
// concurrently for different module names).
23+
RCTAnimatedModuleProvider *_animatedModuleProvider;
24+
dispatch_once_t _animatedModuleProviderToken;
25+
}
1926

2027
@synthesize dependencyProvider;
2128

@@ -89,6 +96,16 @@ - (void)hostDidStart:(RCTHost *)host
8996
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const std::string &)name
9097
jsInvoker:(std::shared_ptr<facebook::react::CallInvoker>)jsInvoker
9198
{
99+
// The dedicated provider supplies the platform-driven C++ Animated module only when the shared
100+
// animated backend is off; with it on, DefaultTurboModules serves AnimatedModule instead.
101+
if (!facebook::react::ReactNativeFeatureFlags::useSharedAnimatedBackend()) {
102+
dispatch_once(&_animatedModuleProviderToken, ^{
103+
_animatedModuleProvider = [RCTAnimatedModuleProvider new];
104+
});
105+
if (auto animatedModule = [_animatedModuleProvider getTurboModule:name jsInvoker:jsInvoker]) {
106+
return animatedModule;
107+
}
108+
}
92109
return facebook::react::DefaultTurboModules::getTurboModule(name, jsInvoker);
93110
}
94111

packages/react-native/Libraries/AppDelegate/React-RCTAppDelegate.podspec

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ Pod::Spec.new do |s|
6262
s.dependency "React-CoreModules"
6363
s.dependency "React-RCTFBReactNativeSpec"
6464
s.dependency "React-defaultsnativemodule"
65+
s.dependency "React-RCTAnimatedModuleProvider"
6566
if use_hermes()
6667
s.dependency 'React-hermes'
6768
end

packages/react-native/Package.swift

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -626,11 +626,18 @@ let reactRCTVibration = RNTarget(
626626
dependencies: [.yoga, .jsi, .reactTurboModuleCore]
627627
)
628628

629+
/// React-RCTAnimatedModuleProvider.podspec
630+
let reactRCTAnimatedModuleProvider = RNTarget(
631+
name: .reactRCTAnimatedModuleProvider,
632+
path: "ReactApple/RCTAnimatedModuleProvider",
633+
dependencies: [.reactNativeDependencies, .jsi, .reactCore, .reactFeatureFlags, .reactFabric, .reactTurboModuleCore, .yoga, .hermesPrebuilt]
634+
)
635+
629636
/// React-RCTAppDelegate.podspec
630637
let reactAppDelegate = RNTarget(
631638
name: .reactAppDelegate,
632639
path: "Libraries/AppDelegate",
633-
dependencies: [.reactNativeDependencies, .jsi, .reactJsiExecutor, .reactRuntime, .reactRCTImage, .reactHermes, .reactCore, .reactFabric, .reactTurboModuleCore, .hermesPrebuilt, .yoga]
640+
dependencies: [.reactNativeDependencies, .jsi, .reactJsiExecutor, .reactRuntime, .reactRCTImage, .reactHermes, .reactCore, .reactFabric, .reactTurboModuleCore, .reactRCTAnimatedModuleProvider, .hermesPrebuilt, .yoga]
634641
)
635642

636643
/// React-RCTLinking.podspec
@@ -716,6 +723,7 @@ let targets = [
716723
reactViewTransitionNativeModule,
717724
reactFeatureflagsNativemodule,
718725
reactNativeModuleDom,
726+
reactRCTAnimatedModuleProvider,
719727
reactAppDelegate,
720728
reactSettings,
721729
reactRuntimeExecutor,
@@ -895,6 +903,7 @@ extension String {
895903
static let reactRCTActionSheet = "React-RCTActionSheet" // Empty target
896904
static let reactRCTLinking = "React-RCTLinking"
897905
static let reactCoreModules = "React-CoreModules"
906+
static let reactRCTAnimatedModuleProvider = "RCTAnimatedModuleProvider"
898907
static let reactTurboModuleBridging = "ReactCommon/turbomodule/bridging"
899908
static let reactTurboModuleCore = "ReactCommon/turbomodule/core"
900909
static let reactTurboModuleCoreDefaults = "ReactCommon/turbomodule/core/defaults"
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# Copyright (c) Meta Platforms, Inc. and affiliates.
2+
#
3+
# This source code is licensed under the MIT license found in the
4+
# LICENSE file in the root directory of this source tree.
5+
6+
require "json"
7+
8+
package = JSON.parse(File.read(File.join(__dir__, "..", "..", "package.json")))
9+
version = package['version']
10+
11+
source = { :git => 'https://github.com/facebook/react-native.git' }
12+
if version == '1000.0.0'
13+
# This is an unpublished version, use the latest commit hash of the react-native repo, which we're presumably in.
14+
source[:commit] = `git rev-parse HEAD`.strip if system("git rev-parse --git-dir > /dev/null 2>&1")
15+
else
16+
source[:tag] = "v#{version}"
17+
end
18+
19+
is_new_arch_enabled = ENV["RCT_NEW_ARCH_ENABLED"] != "0"
20+
new_arch_enabled_flag = (is_new_arch_enabled ? " -DRCT_NEW_ARCH_ENABLED=1" : "")
21+
other_cflags = "$(inherited) " + new_arch_enabled_flag + js_engine_flags()
22+
23+
header_search_paths = [
24+
"$(PODS_TARGET_SRCROOT)/../../ReactCommon",
25+
"$(PODS_ROOT)/Headers/Private/React-Core",
26+
"$(PODS_ROOT)/Headers/Public/ReactCommon",
27+
]
28+
29+
Pod::Spec.new do |s|
30+
s.name = "React-RCTAnimatedModuleProvider"
31+
s.version = version
32+
s.summary = "Provides the C++ Native Animated TurboModule to React Native apps."
33+
s.homepage = "https://reactnative.dev/"
34+
s.documentation_url = "https://reactnative.dev/"
35+
s.license = package["license"]
36+
s.author = "Meta Platforms, Inc. and its affiliates"
37+
s.platforms = min_supported_versions
38+
s.source = source
39+
s.source_files = podspec_sources("*.{m,mm,h}", "*.h")
40+
s.public_header_files = "*.h"
41+
s.module_name = "RCTAnimatedModuleProvider"
42+
s.header_dir = "RCTAnimatedModuleProvider"
43+
44+
s.compiler_flags = other_cflags
45+
s.pod_target_xcconfig = {
46+
"HEADER_SEARCH_PATHS" => header_search_paths,
47+
"OTHER_CPLUSPLUSFLAGS" => other_cflags,
48+
"CLANG_CXX_LANGUAGE_STANDARD" => rct_cxx_language_standard(),
49+
"DEFINES_MODULE" => "YES"
50+
}
51+
52+
s.dependency "React-Core"
53+
s.dependency "React-featureflags"
54+
s.dependency "React-Fabric/animated"
55+
56+
add_dependency(s, "ReactCommon", :subspec => "turbomodule/core", :additional_framework_paths => ["react/nativemodule/core"])
57+
58+
depend_on_js_engine(s)
59+
add_rn_third_party_dependencies(s)
60+
add_rncore_dependency(s)
61+
end

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,13 @@ namespace facebook::react {
6565
}
6666

6767
if (ReactNativeFeatureFlags::cxxNativeAnimatedEnabled() &&
68+
// on Android, the render loop for AnimatedModule is driven
69+
// internally whether or not shared backend is enabled; ios uses
70+
// RCTAnimatedModuleProvider.mm to drive the render loop when shared backend
71+
// is off
72+
#ifndef __ANDROID__
6873
ReactNativeFeatureFlags::useSharedAnimatedBackend() &&
74+
#endif
6975
name == AnimatedModule::kModuleName) {
7076
return std::make_shared<AnimatedModule>(
7177
jsInvoker, std::make_shared<NativeAnimatedNodesManagerProvider>());

packages/react-native/scripts/react_native_pods.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ def use_react_native! (
167167
pod 'React-jsi', :path => "#{prefix}/ReactCommon/jsi"
168168
pod 'RCTSwiftUI', :path => "#{prefix}/ReactApple/RCTSwiftUI"
169169
pod 'RCTSwiftUIWrapper', :path => "#{prefix}/ReactApple/RCTSwiftUIWrapper"
170+
pod 'React-RCTAnimatedModuleProvider', :path => "#{prefix}/ReactApple/RCTAnimatedModuleProvider"
170171

171172
if hermes_enabled
172173
setup_hermes!(:react_native_path => prefix)

0 commit comments

Comments
 (0)