diff --git a/Libraries/AppDelegate/RCTAppDelegate.mm b/Libraries/AppDelegate/RCTAppDelegate.mm index c7fc6e9b09dc76..0d2e7d5a903c08 100644 --- a/Libraries/AppDelegate/RCTAppDelegate.mm +++ b/Libraries/AppDelegate/RCTAppDelegate.mm @@ -17,12 +17,15 @@ #import #import #import +#import +#import static NSString *const kRNConcurrentRoot = @"concurrentRoot"; @interface RCTAppDelegate () { std::shared_ptr _reactNativeConfig; facebook::react::ContextContainer::Shared _contextContainer; + std::shared_ptr _runtimeScheduler; } @end @@ -35,6 +38,10 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( BOOL enableTM = NO; #if RCT_NEW_ARCH_ENABLED enableTM = self.turboModuleEnabled; + + _contextContainer = std::make_shared(); + _reactNativeConfig = std::make_shared(); + _contextContainer->insert("ReactNativeConfig", _reactNativeConfig); #endif RCTAppSetupPrepareApp(application, enableTM); @@ -43,9 +50,6 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( self.bridge = [self createBridgeWithDelegate:self launchOptions:launchOptions]; } #if RCT_NEW_ARCH_ENABLED - _contextContainer = std::make_shared(); - _reactNativeConfig = std::make_shared(); - _contextContainer->insert("ReactNativeConfig", _reactNativeConfig); self.bridgeAdapter = [[RCTSurfacePresenterBridgeAdapter alloc] initWithBridge:self.bridge contextContainer:_contextContainer]; self.bridge.surfacePresenter = self.bridgeAdapter.surfacePresenter; @@ -111,13 +115,16 @@ - (UIViewController *)createRootViewController #if RCT_NEW_ARCH_ENABLED #pragma mark - RCTCxxBridgeDelegate - - (std::unique_ptr)jsExecutorFactoryForBridge:(RCTBridge *)bridge { - self.turboModuleManager = [[RCTTurboModuleManager alloc] initWithBridge:bridge - delegate:self - jsInvoker:bridge.jsCallInvoker]; - return RCTAppSetupDefaultJsExecutorFactory(bridge, _turboModuleManager); + _runtimeScheduler = _runtimeScheduler = + std::make_shared(RCTRuntimeExecutorFromBridge(bridge)); + std::shared_ptr callInvoker = + std::make_shared(_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 diff --git a/React/AppSetup/RCTAppSetupUtils.h b/React/AppSetup/RCTAppSetupUtils.h index 06e12d7317c421..990fb77ef1a224 100644 --- a/React/AppSetup/RCTAppSetupUtils.h +++ b/React/AppSetup/RCTAppSetupUtils.h @@ -31,11 +31,17 @@ #endif #if RCT_NEW_ARCH_ENABLED +// Forward declaration to decrease compilation coupling +namespace facebook::react { +class RuntimeScheduler; +} + RCT_EXTERN id RCTAppSetupDefaultModuleFromClass(Class moduleClass); std::unique_ptr RCTAppSetupDefaultJsExecutorFactory( RCTBridge *bridge, - RCTTurboModuleManager *turboModuleManager); + RCTTurboModuleManager *turboModuleManager, + std::shared_ptr const &runtimeScheduler); #endif #endif // __cplusplus diff --git a/React/AppSetup/RCTAppSetupUtils.mm b/React/AppSetup/RCTAppSetupUtils.mm index 4d58caebfe2e13..c7701867ecf9c7 100644 --- a/React/AppSetup/RCTAppSetupUtils.mm +++ b/React/AppSetup/RCTAppSetupUtils.mm @@ -21,6 +21,8 @@ // Fabric #import +#import +#import #endif #ifdef FB_SONARKIT_ENABLED @@ -96,7 +98,8 @@ void RCTAppSetupPrepareApp(UIApplication *application, BOOL turboModuleEnabled) std::unique_ptr RCTAppSetupDefaultJsExecutorFactory( RCTBridge *bridge, - RCTTurboModuleManager *turboModuleManager) + RCTTurboModuleManager *turboModuleManager, + std::shared_ptr const &runtimeScheduler) { // Necessary to allow NativeModules to lookup TurboModules [bridge setRCTTurboModuleRegistry:turboModuleManager]; @@ -118,14 +121,18 @@ void RCTAppSetupPrepareApp(UIApplication *application, BOOL turboModuleEnabled) #else return std::make_unique( #endif - facebook::react::RCTJSIExecutorRuntimeInstaller([turboModuleManager, bridge](facebook::jsi::Runtime &runtime) { - if (!bridge || !turboModuleManager) { - return; - } - facebook::react::RuntimeExecutor syncRuntimeExecutor = - [&](std::function &&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 &&callback) { callback(runtime); }; + [turboModuleManager installJSBindingWithRuntimeExecutor:syncRuntimeExecutor]; + })); } #endif diff --git a/packages/rn-tester/RNTester/AppDelegate.mm b/packages/rn-tester/RNTester/AppDelegate.mm index 8fafba034302ba..6803451e67ac58 100644 --- a/packages/rn-tester/RNTester/AppDelegate.mm +++ b/packages/rn-tester/RNTester/AppDelegate.mm @@ -48,6 +48,9 @@ #import #import +#import +#import +#import #endif #if DEBUG @@ -70,6 +73,7 @@ @interface AppDelegate () RCTSurfacePresenterBridgeAdapter *_bridgeAdapter; std::shared_ptr _reactNativeConfig; facebook::react::ContextContainer::Shared _contextContainer; + std::shared_ptr _runtimeScheduler; #endif RCTTurboModuleManager *_turboModuleManager; @@ -84,17 +88,18 @@ - (BOOL)application:(__unused UIApplication *)application didFinishLaunchingWith { RCTEnableTurboModule(YES); +#ifdef RN_FABRIC_ENABLED + _contextContainer = std::make_shared(); + _reactNativeConfig = std::make_shared(); + _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(); - _reactNativeConfig = std::make_shared(); - - _contextContainer->insert("ReactNativeConfig", _reactNativeConfig); - _bridgeAdapter = [[RCTSurfacePresenterBridgeAdapter alloc] initWithBridge:_bridge contextContainer:_contextContainer]; _bridge.surfacePresenter = _bridgeAdapter.surfacePresenter; @@ -174,11 +179,19 @@ - (void)loadSourceForBridge:(RCTBridge *)bridge #pragma mark - RCTCxxBridgeDelegate +// This function is called during +// `[[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];` - (std::unique_ptr)jsExecutorFactoryForBridge:(RCTBridge *)bridge { - _turboModuleManager = [[RCTTurboModuleManager alloc] initWithBridge:bridge - delegate:self - jsInvoker:bridge.jsCallInvoker]; + std::shared_ptr callInvoker = bridge.jsCallInvoker; + +#ifdef RCT_NEW_ARCH_ENABLED + _runtimeScheduler = std::make_shared(RCTRuntimeExecutorFromBridge(bridge)); + _contextContainer->erase("RuntimeScheduler"); + _contextContainer->insert("RuntimeScheduler", _runtimeScheduler); + callInvoker = std::make_shared(_runtimeScheduler); +#endif + _turboModuleManager = [[RCTTurboModuleManager alloc] initWithBridge:bridge delegate:self jsInvoker:callInvoker]; [bridge setRCTTurboModuleRegistry:_turboModuleManager]; #if RCT_DEV @@ -190,6 +203,7 @@ - (void)loadSourceForBridge:(RCTBridge *)bridge #endif __weak __typeof(self) weakSelf = self; + #if RCT_USE_HERMES return std::make_unique( #else @@ -200,6 +214,9 @@ - (void)loadSourceForBridge:(RCTBridge *)bridge return; } __typeof(self) strongSelf = weakSelf; + if (strongSelf && strongSelf->_runtimeScheduler) { + facebook::react::RuntimeSchedulerBinding::createAndInstallIfNeeded(runtime, strongSelf->_runtimeScheduler); + } if (strongSelf) { facebook::react::RuntimeExecutor syncRuntimeExecutor = [&](std::function &&callback) { callback(runtime); };