mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Install the RuntimeScheduler when the New Architecture is enabled (#36209)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/36209 ThisChange automatically enable the RuntimeScheduler when the new architecture is enabled, both on RNester and in the Template app. Note that no migration steps are required. ## Changelog [iOS][Changed] - Automatically install the RuntimeScheduler Reviewed By: sammy-SC Differential Revision: D43392059 fbshipit-source-id: 609ded9bdc3db13a0d54ff44d0d4687dfc8617a5
This commit is contained in:
1 parent
8be9dbfcc1
commit
3e88fd01ce
7 files changed
+154
-26
No files matched your search
@@ -17,12 +17,15 @@
|
||||
#import <React/RCTSurfacePresenterBridgeAdapter.h>
|
||||
#import <ReactCommon/RCTTurboModuleManager.h>
|
||||
#import <react/config/ReactNativeConfig.h>
|
||||
#import <react/renderer/runtimescheduler/RuntimeScheduler.h>
|
||||
#import <react/renderer/runtimescheduler/RuntimeSchedulerCallInvoker.h>
|
||||
|
||||
static NSString *const kRNConcurrentRoot = @"concurrentRoot";
|
||||
|
||||
@interface RCTAppDelegate () <RCTTurboModuleManagerDelegate, RCTCxxBridgeDelegate> {
|
||||
std::shared_ptr<const facebook::react::ReactNativeConfig> _reactNativeConfig;
|
||||
facebook::react::ContextContainer::Shared _contextContainer;
|
||||
std::shared_ptr<facebook::react::RuntimeScheduler> _runtimeScheduler;
|
||||
}
|
||||
@end
|
||||
|
||||
@@ -35,6 +38,10 @@ static NSString *const kRNConcurrentRoot = @"concurrentRoot";
|
||||
BOOL enableTM = NO;
|
||||
#if RCT_NEW_ARCH_ENABLED
|
||||
enableTM = self.turboModuleEnabled;
|
||||
|
||||
_contextContainer = std::make_shared<facebook::react::ContextContainer const>();
|
||||
_reactNativeConfig = std::make_shared<facebook::react::EmptyReactNativeConfig const>();
|
||||
_contextContainer->insert("ReactNativeConfig", _reactNativeConfig);
|
||||
#endif
|
||||
|
||||
RCTAppSetupPrepareApp(application, enableTM);
|
||||
@@ -43,9 +50,6 @@ static NSString *const kRNConcurrentRoot = @"concurrentRoot";
|
||||
self.bridge = [self createBridgeWithDelegate:self launchOptions:launchOptions];
|
||||
}
|
||||
#if RCT_NEW_ARCH_ENABLED
|
||||
_contextContainer = std::make_shared<facebook::react::ContextContainer const>();
|
||||
_reactNativeConfig = std::make_shared<facebook::react::EmptyReactNativeConfig const>();
|
||||
_contextContainer->insert("ReactNativeConfig", _reactNativeConfig);
|
||||
self.bridgeAdapter = [[RCTSurfacePresenterBridgeAdapter alloc] initWithBridge:self.bridge
|
||||
contextContainer:_contextContainer];
|
||||
self.bridge.surfacePresenter = self.bridgeAdapter.surfacePresenter;
|
||||
@@ -112,13 +116,16 @@ static NSString *const kRNConcurrentRoot = @"concurrentRoot";
|
||||
|
||||
#if RCT_NEW_ARCH_ENABLED
|
||||
#pragma mark - RCTCxxBridgeDelegate
|
||||
|
||||
- (std::unique_ptr<facebook::react::JSExecutorFactory>)jsExecutorFactoryForBridge:(RCTBridge *)bridge
|
||||
{
|
||||
self.turboModuleManager = [[RCTTurboModuleManager alloc] initWithBridge:bridge
|
||||
delegate:self
|
||||
jsInvoker:bridge.jsCallInvoker];
|
||||
return RCTAppSetupDefaultJsExecutorFactory(bridge, _turboModuleManager);
|
||||
_runtimeScheduler = _runtimeScheduler =
|
||||
std::make_shared<facebook::react::RuntimeScheduler>(RCTRuntimeExecutorFromBridge(bridge));
|
||||
std::shared_ptr<facebook::react::CallInvoker> callInvoker =
|
||||
std::make_shared<facebook::react::RuntimeSchedulerCallInvoker>(_runtimeScheduler);
|
||||
self.turboModuleManager = [[RCTTurboModuleManager alloc] initWithBridge:bridge delegate:self jsInvoker:callInvoker];
|
||||
_contextContainer->erase("RuntimeScheduler");
|
||||
_contextContainer->insert("RuntimeScheduler", _runtimeScheduler);
|
||||
return RCTAppSetupDefaultJsExecutorFactory(bridge, _turboModuleManager, _runtimeScheduler);
|
||||
}
|
||||
|
||||
#pragma mark RCTTurboModuleManagerDelegate
|
||||
|
||||
@@ -31,11 +31,17 @@
|
||||
#endif
|
||||
|
||||
#if RCT_NEW_ARCH_ENABLED
|
||||
// Forward declaration to decrease compilation coupling
|
||||
namespace facebook::react {
|
||||
class RuntimeScheduler;
|
||||
}
|
||||
|
||||
RCT_EXTERN id<RCTTurboModule> RCTAppSetupDefaultModuleFromClass(Class moduleClass);
|
||||
|
||||
std::unique_ptr<facebook::react::JSExecutorFactory> RCTAppSetupDefaultJsExecutorFactory(
|
||||
RCTBridge *bridge,
|
||||
RCTTurboModuleManager *turboModuleManager);
|
||||
RCTTurboModuleManager *turboModuleManager,
|
||||
std::shared_ptr<facebook::react::RuntimeScheduler> const &runtimeScheduler);
|
||||
#endif
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
|
||||
// Fabric
|
||||
#import <React/RCTFabricSurfaceHostingProxyRootView.h>
|
||||
#import <react/renderer/runtimescheduler/RuntimeScheduler.h>
|
||||
#import <react/renderer/runtimescheduler/RuntimeSchedulerBinding.h>
|
||||
#endif
|
||||
|
||||
#ifdef FB_SONARKIT_ENABLED
|
||||
@@ -96,7 +98,8 @@ id<RCTTurboModule> RCTAppSetupDefaultModuleFromClass(Class moduleClass)
|
||||
|
||||
std::unique_ptr<facebook::react::JSExecutorFactory> RCTAppSetupDefaultJsExecutorFactory(
|
||||
RCTBridge *bridge,
|
||||
RCTTurboModuleManager *turboModuleManager)
|
||||
RCTTurboModuleManager *turboModuleManager,
|
||||
std::shared_ptr<facebook::react::RuntimeScheduler> const &runtimeScheduler)
|
||||
{
|
||||
// Necessary to allow NativeModules to lookup TurboModules
|
||||
[bridge setRCTTurboModuleRegistry:turboModuleManager];
|
||||
@@ -118,14 +121,18 @@ std::unique_ptr<facebook::react::JSExecutorFactory> RCTAppSetupDefaultJsExecutor
|
||||
#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];
|
||||
}));
|
||||
facebook::react::RCTJSIExecutorRuntimeInstaller(
|
||||
[turboModuleManager, bridge, runtimeScheduler](facebook::jsi::Runtime &runtime) {
|
||||
if (!bridge || !turboModuleManager) {
|
||||
return;
|
||||
}
|
||||
if (runtimeScheduler) {
|
||||
facebook::react::RuntimeSchedulerBinding::createAndInstallIfNeeded(runtime, runtimeScheduler);
|
||||
}
|
||||
facebook::react::RuntimeExecutor syncRuntimeExecutor =
|
||||
[&](std::function<void(facebook::jsi::Runtime & runtime_)> &&callback) { callback(runtime); };
|
||||
[turboModuleManager installJSBindingWithRuntimeExecutor:syncRuntimeExecutor];
|
||||
}));
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -15,6 +15,10 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef RCT_NEW_ARCH_ENABLED
|
||||
#define RN_FABRIC_ENABLED
|
||||
#endif
|
||||
|
||||
#if RCT_USE_HERMES
|
||||
#import <reacthermes/HermesExecutorFactory.h>
|
||||
#else
|
||||
@@ -48,6 +52,9 @@
|
||||
#import <React/RCTSurfacePresenterBridgeAdapter.h>
|
||||
|
||||
#import <react/config/ReactNativeConfig.h>
|
||||
#import <react/renderer/runtimescheduler/RuntimeScheduler.h>
|
||||
#import <react/renderer/runtimescheduler/RuntimeSchedulerBinding.h>
|
||||
#import <react/renderer/runtimescheduler/RuntimeSchedulerCallInvoker.h>
|
||||
#endif
|
||||
|
||||
#if DEBUG
|
||||
@@ -70,6 +77,7 @@
|
||||
RCTSurfacePresenterBridgeAdapter *_bridgeAdapter;
|
||||
std::shared_ptr<const facebook::react::ReactNativeConfig> _reactNativeConfig;
|
||||
facebook::react::ContextContainer::Shared _contextContainer;
|
||||
std::shared_ptr<facebook::react::RuntimeScheduler> _runtimeScheduler;
|
||||
#endif
|
||||
|
||||
RCTTurboModuleManager *_turboModuleManager;
|
||||
@@ -84,17 +92,18 @@ static NSString *const kRNConcurrentRoot = @"concurrentRoot";
|
||||
{
|
||||
RCTEnableTurboModule(YES);
|
||||
|
||||
#ifdef RN_FABRIC_ENABLED
|
||||
_contextContainer = std::make_shared<facebook::react::ContextContainer const>();
|
||||
_reactNativeConfig = std::make_shared<facebook::react::EmptyReactNativeConfig const>();
|
||||
_contextContainer->insert("ReactNativeConfig", _reactNativeConfig);
|
||||
#endif
|
||||
|
||||
_bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
|
||||
|
||||
// Appetizer.io params check
|
||||
NSDictionary *initProps = [self prepareInitialProps];
|
||||
|
||||
#ifdef RN_FABRIC_ENABLED
|
||||
_contextContainer = std::make_shared<facebook::react::ContextContainer const>();
|
||||
_reactNativeConfig = std::make_shared<facebook::react::EmptyReactNativeConfig const>();
|
||||
|
||||
_contextContainer->insert("ReactNativeConfig", _reactNativeConfig);
|
||||
|
||||
_bridgeAdapter = [[RCTSurfacePresenterBridgeAdapter alloc] initWithBridge:_bridge contextContainer:_contextContainer];
|
||||
|
||||
_bridge.surfacePresenter = _bridgeAdapter.surfacePresenter;
|
||||
@@ -174,11 +183,19 @@ static NSString *const kRNConcurrentRoot = @"concurrentRoot";
|
||||
|
||||
#pragma mark - RCTCxxBridgeDelegate
|
||||
|
||||
// This function is called during
|
||||
// `[[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];`
|
||||
- (std::unique_ptr<facebook::react::JSExecutorFactory>)jsExecutorFactoryForBridge:(RCTBridge *)bridge
|
||||
{
|
||||
_turboModuleManager = [[RCTTurboModuleManager alloc] initWithBridge:bridge
|
||||
delegate:self
|
||||
jsInvoker:bridge.jsCallInvoker];
|
||||
std::shared_ptr<facebook::react::CallInvoker> callInvoker = bridge.jsCallInvoker;
|
||||
|
||||
#ifdef RCT_NEW_ARCH_ENABLED
|
||||
_runtimeScheduler = std::make_shared<facebook::react::RuntimeScheduler>(RCTRuntimeExecutorFromBridge(bridge));
|
||||
_contextContainer->erase("RuntimeScheduler");
|
||||
_contextContainer->insert("RuntimeScheduler", _runtimeScheduler);
|
||||
callInvoker = std::make_shared<facebook::react::RuntimeSchedulerCallInvoker>(_runtimeScheduler);
|
||||
#endif
|
||||
_turboModuleManager = [[RCTTurboModuleManager alloc] initWithBridge:bridge delegate:self jsInvoker:callInvoker];
|
||||
[bridge setRCTTurboModuleRegistry:_turboModuleManager];
|
||||
|
||||
#if RCT_DEV
|
||||
@@ -190,6 +207,7 @@ static NSString *const kRNConcurrentRoot = @"concurrentRoot";
|
||||
#endif
|
||||
|
||||
__weak __typeof(self) weakSelf = self;
|
||||
|
||||
#if RCT_USE_HERMES
|
||||
return std::make_unique<facebook::react::HermesExecutorFactory>(
|
||||
#else
|
||||
@@ -200,6 +218,9 @@ static NSString *const kRNConcurrentRoot = @"concurrentRoot";
|
||||
return;
|
||||
}
|
||||
__typeof(self) strongSelf = weakSelf;
|
||||
if (strongSelf && strongSelf->_runtimeScheduler) {
|
||||
facebook::react::RuntimeSchedulerBinding::createAndInstallIfNeeded(runtime, strongSelf->_runtimeScheduler);
|
||||
}
|
||||
if (strongSelf) {
|
||||
facebook::react::RuntimeExecutor syncRuntimeExecutor =
|
||||
[&](std::function<void(facebook::jsi::Runtime & runtime_)> &&callback) { callback(runtime); };
|
||||
|
||||
@@ -597,6 +597,68 @@ class UtilsTests < Test::Unit::TestCase
|
||||
end
|
||||
end
|
||||
|
||||
# ============================= #
|
||||
# Test - Apply Flags For Fabric #
|
||||
# ============================= #
|
||||
def test_applyFlagsForFabric_whenFabricEnabled_addsTheFlag
|
||||
# Arrange
|
||||
first_target = prepare_target("FirstTarget")
|
||||
second_target = prepare_target("SecondTarget")
|
||||
third_target = prepare_target("ThirdTarget", "com.apple.product-type.bundle")
|
||||
user_project_mock = UserProjectMock.new("a/path", [
|
||||
prepare_config("Debug"),
|
||||
prepare_config("Release"),
|
||||
],
|
||||
:native_targets => [
|
||||
first_target,
|
||||
second_target
|
||||
]
|
||||
)
|
||||
pods_projects_mock = PodsProjectMock.new([third_target], {"hermes-engine" => {}})
|
||||
installer = InstallerMock.new(pods_projects_mock, [
|
||||
AggregatedProjectMock.new(user_project_mock)
|
||||
])
|
||||
|
||||
# Act
|
||||
ReactNativePodsUtils.apply_flags_for_fabric(installer, fabric_enabled: true)
|
||||
|
||||
# Assert
|
||||
user_project_mock.build_configurations.each do |config|
|
||||
received_cflags = config.build_settings["OTHER_CFLAGS"]
|
||||
expected_cflags = "$(inherited) -DRN_FABRIC_ENABLED"
|
||||
assert_equal(received_cflags, expected_cflags)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def test_applyFlagsForFabric_whenFabricDisabled_doNothing
|
||||
# Arrange
|
||||
first_target = prepare_target("FirstTarget")
|
||||
second_target = prepare_target("SecondTarget")
|
||||
third_target = prepare_target("ThirdTarget", "com.apple.product-type.bundle")
|
||||
user_project_mock = UserProjectMock.new("a/path", [
|
||||
prepare_config("Debug"),
|
||||
prepare_config("Release"),
|
||||
],
|
||||
:native_targets => [
|
||||
first_target,
|
||||
second_target
|
||||
]
|
||||
)
|
||||
pods_projects_mock = PodsProjectMock.new([third_target], {"hermes-engine" => {}})
|
||||
installer = InstallerMock.new(pods_projects_mock, [
|
||||
AggregatedProjectMock.new(user_project_mock)
|
||||
])
|
||||
|
||||
# Act
|
||||
ReactNativePodsUtils.apply_flags_for_fabric(installer, fabric_enabled: false)
|
||||
|
||||
# Assert
|
||||
user_project_mock.build_configurations.each do |config|
|
||||
assert_nil(config.build_settings["OTHER_CFLAGS"])
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# ===== #
|
||||
# UTILS #
|
||||
|
||||
@@ -131,6 +131,28 @@ class ReactNativePodsUtils
|
||||
end
|
||||
end
|
||||
|
||||
def self.apply_flags_for_fabric(installer, fabric_enabled: false)
|
||||
return if !fabric_enabled
|
||||
|
||||
fabric_flag = "-DRN_FABRIC_ENABLED"
|
||||
projects = installer.aggregate_targets
|
||||
.map{ |t| t.user_project }
|
||||
.uniq{ |p| p.path }
|
||||
.push(installer.pods_project)
|
||||
|
||||
projects.each do |project|
|
||||
project.build_configurations.each do |config|
|
||||
cflags = config.build_settings["OTHER_CFLAGS"] ? config.build_settings["OTHER_CFLAGS"] : "$(inherited)"
|
||||
|
||||
if !cflags.include?(fabric_flag)
|
||||
cflags = "#{cflags} #{fabric_flag}"
|
||||
end
|
||||
config.build_settings["OTHER_CFLAGS"] = cflags
|
||||
end
|
||||
project.save()
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def self.fix_library_search_path(config)
|
||||
|
||||
@@ -212,10 +212,13 @@ def react_native_post_install(installer, react_native_path = "../node_modules/re
|
||||
flipper_post_install(installer)
|
||||
end
|
||||
|
||||
fabric_enabled = ReactNativePodsUtils.has_pod(installer, 'React-Fabric')
|
||||
|
||||
ReactNativePodsUtils.exclude_i386_architecture_while_using_hermes(installer)
|
||||
ReactNativePodsUtils.fix_library_search_paths(installer)
|
||||
ReactNativePodsUtils.update_search_paths(installer)
|
||||
ReactNativePodsUtils.set_node_modules_user_settings(installer, react_native_path)
|
||||
ReactNativePodsUtils.apply_flags_for_fabric(installer, fabric_enabled: fabric_enabled)
|
||||
|
||||
NewArchitectureHelper.set_clang_cxx_language_standard_if_needed(installer)
|
||||
is_new_arch_enabled = ENV['RCT_NEW_ARCH_ENABLED'] == "1"
|
||||
|
||||
Reference in new issue
Block a user