Skip to content

Commit

Permalink
Add turbo module support in the default app template (#32752)
Browse files Browse the repository at this point in the history
Summary:
Pull Request resolved: #32752

Changelog: [internal] Add an optional support for Turbomodule. Define RCT_TM_FABRIC_ENABLED to enable the new architecture.

Reviewed By: philIip

Differential Revision: D33052777

fbshipit-source-id: 6d32790586bb51f9c9244344522c95245c912114
  • Loading branch information
sota000 authored and facebook-github-bot committed Dec 16, 2021
1 parent 82b8f40 commit 8ec0e69
Show file tree
Hide file tree
Showing 6 changed files with 169 additions and 2 deletions.
2 changes: 1 addition & 1 deletion React-Core.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ Pod::Spec.new do |s|
s.compiler_flags = folly_compiler_flags + ' ' + boost_compiler_flags
s.header_dir = "React"
s.framework = "JavaScriptCore"
s.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => "\"$(PODS_TARGET_SRCROOT)/ReactCommon\" \"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/DoubleConversion\" \"$(PODS_ROOT)/RCT-Folly\" \"${PODS_ROOT}/Headers/Public/React-hermes\" \"${PODS_ROOT}/Headers/Public/hermes-engine\" \"${PODS_ROOT}/Headers/Public/FlipperKit\"", "DEFINES_MODULE" => "YES" }
s.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => "\"$(PODS_TARGET_SRCROOT)/ReactCommon\" \"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/DoubleConversion\" \"$(PODS_ROOT)/RCT-Folly\" \"${PODS_ROOT}/Headers/Public/React-hermes\" \"${PODS_ROOT}/Headers/Public/hermes-engine\" \"${PODS_ROOT}/Headers/Public/FlipperKit\" \"$(PODS_ROOT)/Headers/Public/ReactCommon\"", "DEFINES_MODULE" => "YES" }
s.user_target_xcconfig = { "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/Headers/Private/React-Core\""}
s.default_subspec = "Default"

Expand Down
26 changes: 26 additions & 0 deletions React/AppSetup/RCTAppSetupUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,35 @@
#import <React/RCTBridge.h>
#import <React/RCTRootView.h>

#if RCT_TM_FABRIC_ENABLED

#ifndef RCT_USE_HERMES
#if __has_include(<reacthermes/HermesExecutorFactory.h>)
#define RCT_USE_HERMES 1
#else
#define RCT_USE_HERMES 0
#endif
#endif

#if RCT_USE_HERMES
#import <reacthermes/HermesExecutorFactory.h>
#else
#import <React/JSCExecutorFactory.h>
#endif

#import <ReactCommon/RCTTurboModuleManager.h>
#endif

@interface RCTAppSetupUtils : NSObject
+ (void)prepareApp:(UIApplication *_Nonnull)application;
+ (RCTRootView *_Nonnull)defaultRootViewWithBridge:(RCTBridge *_Nonnull)bridge
moduleName:(NSString *_Nonnull)moduleName
initialProperties:(nullable NSDictionary *)initialProperties;

#if RCT_TM_FABRIC_ENABLED
+ (id<RCTTurboModule> _Nonnull)defaultModuleInstanceFromClass:(Class _Nonnull)moduleClass;
+ (std::unique_ptr<facebook::react::JSExecutorFactory>)
defaultJsExecutorFactoryForBridge:(RCTBridge *_Nonnull)bridge
withTurboModuleManager:(RCTTurboModuleManager *_Nonnull)turboModuleManager;
#endif
@end
78 changes: 78 additions & 0 deletions React/AppSetup/RCTAppSetupUtils.mm
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,18 @@

#import "RCTAppSetupUtils.h"

#if RCT_TM_FABRIC_ENABLED
#import <React/CoreModulesPlugins.h>
#import <React/RCTDataRequestHandler.h>
#import <React/RCTFileRequestHandler.h>
#import <React/RCTGIFImageDecoder.h>
#import <React/RCTHTTPRequestHandler.h>
#import <React/RCTImageLoader.h>
#import <React/RCTJSIExecutorRuntimeInstaller.h>
#import <React/RCTLocalAssetImageLoader.h>
#import <React/RCTNetworking.h>
#endif

#ifdef FB_SONARKIT_ENABLED
#import <FlipperKit/FlipperClient.h>
#import <FlipperKitLayoutPlugin/FlipperKitLayoutPlugin.h>
Expand Down Expand Up @@ -35,6 +47,10 @@ + (void)prepareApp:(UIApplication *)application
#ifdef FB_SONARKIT_ENABLED
InitializeFlipper(application);
#endif

#if RCT_TM_FABRIC_ENABLED
RCTEnableTurboModule(YES);
#endif
}

+ (RCTRootView *)defaultRootViewWithBridge:(RCTBridge *)bridge
Expand All @@ -44,4 +60,66 @@ + (RCTRootView *)defaultRootViewWithBridge:(RCTBridge *)bridge
return [[RCTRootView alloc] initWithBridge:bridge moduleName:moduleName initialProperties:initialProperties];
}

#if RCT_TM_FABRIC_ENABLED
+ (id<RCTTurboModule>)defaultModuleInstanceFromClass:(Class)moduleClass
{
// Set up the default RCTImageLoader and RCTNetworking modules.
if (moduleClass == RCTImageLoader.class) {
return [[moduleClass alloc] initWithRedirectDelegate:nil
loadersProvider:^NSArray<id<RCTImageURLLoader>> *(RCTModuleRegistry *moduleRegistry) {
return @[ [RCTLocalAssetImageLoader new] ];
}
decodersProvider:^NSArray<id<RCTImageDataDecoder>> *(RCTModuleRegistry *moduleRegistry) {
return @[ [RCTGIFImageDecoder new] ];
}];
} else if (moduleClass == RCTNetworking.class) {
return [[moduleClass alloc]
initWithHandlersProvider:^NSArray<id<RCTURLRequestHandler>> *(RCTModuleRegistry *moduleRegistry) {
return @[
[RCTHTTPRequestHandler new],
[RCTDataRequestHandler new],
[RCTFileRequestHandler new],
];
}];
}
// No custom initializer here.
return [moduleClass new];
}

+ (std::unique_ptr<facebook::react::JSExecutorFactory>)defaultJsExecutorFactoryForBridge:(RCTBridge *)bridge
withTurboModuleManager:
(RCTTurboModuleManager *)turboModuleManager;
{
// Necessary to allow NativeModules to lookup TurboModules
[bridge setRCTTurboModuleRegistry:turboModuleManager];

#if RCT_DEV
if (!RCTTurboModuleEagerInitEnabled()) {
/**
* Instantiating DevMenu has the side-effect of registering
* shortcuts for CMD + d, CMD + i, and CMD + n via RCTDevMenu.
* Therefore, when TurboModules are enabled, we must manually create this
* NativeModule.
*/
[turboModuleManager moduleForName:"RCTDevMenu"];
}
#endif

#if RCT_USE_HERMES
return std::make_unique<facebook::react::HermesExecutorFactory>(
#else
return std::make_unique<facebook::react::JSCExecutorFactory>(
#endif
facebook::react::RCTJSIExecutorRuntimeInstaller([turboModuleManager, bridge](facebook::jsi::Runtime &runtime) {
if (!bridge || !turboModuleManager) {
return;
}
facebook::react::RuntimeExecutor syncRuntimeExecutor =
[&](std::function<void(facebook::jsi::Runtime & runtime_)> &&callback) { callback(runtime); };
[turboModuleManager installJSBindingWithRuntimeExecutor:syncRuntimeExecutor];
}));
}

#endif

@end
2 changes: 1 addition & 1 deletion packages/rn-tester/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -901,7 +901,7 @@ SPEC CHECKSUMS:
React: f64c9f6db5428717922a3292ba6a448615a2e143
React-callinvoker: c5d61e29df57793f0dc10ec2bc01c846f863e51f
React-Codegen: 2256e335ccce7326eeca6d7a668e05c4de259289
React-Core: 50d95abfb3c60d95e33a4b74e05e2a414bea4b73
React-Core: 2753750098f0ad7e351a61c2e63d44ae0e95c3fe
React-CoreModules: a8e2bdc1ebbf8d440478456197abd58d1691f61a
React-cxxreact: cfc1663dae1ea52b465bbf021ef7b1527c5dc80c
React-Fabric: 002345cff43721617e0a3c0866f6f76bae8c50ff
Expand Down
14 changes: 14 additions & 0 deletions template/ios/HelloWorld.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,7 @@
baseConfigurationReference = 3B4392A12AC88292D35C810B /* Pods-HelloWorld.debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_CXX_LANGUAGE_STANDARD = "c++17";
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = 1;
ENABLE_BITCODE = NO;
Expand All @@ -508,6 +509,7 @@
baseConfigurationReference = 5709B34CF0A7D63546082F79 /* Pods-HelloWorld.release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_CXX_LANGUAGE_STANDARD = "c++17";
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = 1;
INFOPLIST_FILE = HelloWorld/Info.plist;
Expand Down Expand Up @@ -588,6 +590,12 @@
);
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
OTHER_CPLUSPLUSFLAGS = (
"$(OTHER_CFLAGS)",
"-DFOLLY_NO_CONFIG",
"-DFOLLY_MOBILE=1",
"-DFOLLY_USE_LIBCPP=1",
);
SDKROOT = iphoneos;
};
name = Debug;
Expand Down Expand Up @@ -645,6 +653,12 @@
"\"$(inherited)\"",
);
MTL_ENABLE_DEBUG_INFO = NO;
OTHER_CPLUSPLUSFLAGS = (
"$(OTHER_CFLAGS)",
"-DFOLLY_NO_CONFIG",
"-DFOLLY_MOBILE=1",
"-DFOLLY_USE_LIBCPP=1",
);
SDKROOT = iphoneos;
VALIDATE_PRODUCT = YES;
};
Expand Down
49 changes: 49 additions & 0 deletions template/ios/HelloWorld/AppDelegate.mm
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,17 @@

#import <React/RCTAppSetupUtils.h>

#if RCT_TM_FABRIC_ENABLED
#import <React/CoreModulesPlugins.h>
#import <React/RCTCxxBridgeDelegate.h>
#import <ReactCommon/RCTTurboModuleManager.h>

@interface AppDelegate () <RCTCxxBridgeDelegate, RCTTurboModuleManagerDelegate> {
RCTTurboModuleManager *_turboModuleManager;
}
@end
#endif

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
Expand Down Expand Up @@ -40,4 +51,42 @@ - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
#endif
}

#if RCT_TM_FABRIC_ENABLED

#pragma mark - RCTCxxBridgeDelegate

- (std::unique_ptr<facebook::react::JSExecutorFactory>)jsExecutorFactoryForBridge:(RCTBridge *)bridge
{
_turboModuleManager = [[RCTTurboModuleManager alloc] initWithBridge:bridge
delegate:self
jsInvoker:bridge.jsCallInvoker];
return [RCTAppSetupUtils defaultJsExecutorFactoryForBridge:bridge withTurboModuleManager:_turboModuleManager];
}

#pragma mark RCTTurboModuleManagerDelegate

- (Class)getModuleClassFromName:(const char *)name
{
return RCTCoreModulesClassProvider(name);
}

- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const std::string &)name
jsInvoker:(std::shared_ptr<facebook::react::CallInvoker>)jsInvoker
{
return nullptr;
}

- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const std::string &)name
initParams:(const facebook::react::ObjCTurboModule::InitParams &)params
{
return nullptr;
}

- (id<RCTTurboModule>)getModuleInstanceFromClass:(Class)moduleClass
{
return [RCTAppSetupUtils defaultModuleInstanceFromClass: moduleClass];
}

#endif

@end

0 comments on commit 8ec0e69

Please sign in to comment.