diff --git a/packages/react-native/ReactCommon/react/bridgeless/platform/ios/Core/RCTInstance.mm b/packages/react-native/ReactCommon/react/bridgeless/platform/ios/Core/RCTInstance.mm index 4a3316cddc9..f4e52c0a501 100644 --- a/packages/react-native/ReactCommon/react/bridgeless/platform/ios/Core/RCTInstance.mm +++ b/packages/react-native/ReactCommon/react/bridgeless/platform/ios/Core/RCTInstance.mm @@ -82,6 +82,8 @@ void RCTInstanceSetRuntimeDiagnosticFlags(NSString *flags) RCTBridgeModuleDecorator *_bridgeModuleDecorator; } +#pragma mark - Public + - (instancetype)initWithDelegate:(id)delegate jsEngineInstance:(std::shared_ptr)jsEngineInstance bundleManager:(RCTBundleManager *)bundleManager @@ -118,16 +120,95 @@ void RCTInstanceSetRuntimeDiagnosticFlags(NSString *flags) } [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(notifyEventDispatcherObserversOfEvent_DEPRECATED:) + selector:@selector(_notifyEventDispatcherObserversOfEvent_DEPRECATED:) name:@"RCTNotifyEventDispatcherObserversOfEvent_DEPRECATED" object:nil]; - [self start]; + [self _start]; } return self; } -- (void)start +- (void)invalidate +{ + std::lock_guard lock(self->_invalidationMutex); + self->_valid = false; + + [_surfacePresenter suspend]; + [_jsThreadManager dispatchToJSThread:^{ + /** + * Every TurboModule is invalidated on its own method queue. + * TurboModuleManager invalidate blocks the calling thread until all TurboModules are invalidated. + */ + [self->_turboModuleManager invalidate]; + + // Clean up all the Resources + self->_reactInstance = nullptr; + self->_jsEngineInstance = nullptr; + self->_appTMMDelegate = nil; + self->_delegate = nil; + self->_displayLink = nil; + + self->_turboModuleManager = nil; + self->_performanceLogger = nil; + + // Terminate the JavaScript thread, so that no other work executes after this block. + self->_jsThreadManager = nil; + }]; +} + +#pragma mark - RCTTurboModuleManagerDelegate + +- (Class)getModuleClassFromName:(const char *)name +{ + if ([_appTMMDelegate respondsToSelector:@selector(getModuleClassFromName:)]) { + return [_appTMMDelegate getModuleClassFromName:name]; + } + + return nil; +} + +- (id)getModuleInstanceFromClass:(Class)moduleClass +{ + if ([_appTMMDelegate respondsToSelector:@selector(getModuleInstanceFromClass:)]) { + id module = [_appTMMDelegate getModuleInstanceFromClass:moduleClass]; + [self _attachBridgelessAPIsToModule:module]; + return module; + } + + return nil; +} + +- (std::shared_ptr)getTurboModule:(const std::string &)name + jsInvoker:(std::shared_ptr)jsInvoker +{ + if ([_appTMMDelegate respondsToSelector:@selector(getTurboModule:jsInvoker:)]) { + return [_appTMMDelegate getTurboModule:name jsInvoker:jsInvoker]; + } + + return nullptr; +} + +#pragma mark - ReactInstanceForwarding + +- (void)callFunctionOnModule:(NSString *)moduleName method:(NSString *)method args:(NSArray *)args +{ + if (_valid) { + _reactInstance->callFunctionOnModule( + [moduleName UTF8String], [method UTF8String], convertIdToFollyDynamic(args ?: @[])); + } +} + +- (void)registerSegmentWithId:(NSNumber *)segmentId path:(NSString *)path +{ + if (_valid) { + self->_reactInstance->registerSegment(static_cast([segmentId unsignedIntValue]), path.UTF8String); + } +} + +#pragma mark - Private + +- (void)_start { // Set up timers auto objCTimerRegistry = std::make_unique(); @@ -219,43 +300,12 @@ void RCTInstanceSetRuntimeDiagnosticFlags(NSString *flags) // Attempt to load bundle synchronously, fallback to asynchronously. [strongSelf->_performanceLogger markStartForTag:RCTPLScriptDownload]; - [strongSelf loadJSBundle:[strongSelf->_bridgeModuleDecorator.bundleManager bundleURL]]; + [strongSelf _loadJSBundle:[strongSelf->_bridgeModuleDecorator.bundleManager bundleURL]]; }); [_performanceLogger markStopForTag:RCTPLReactInstanceInit]; } -#pragma mark - RCTTurboModuleManagerDelegate -- (Class)getModuleClassFromName:(const char *)name -{ - if ([_appTMMDelegate respondsToSelector:@selector(getModuleClassFromName:)]) { - return [_appTMMDelegate getModuleClassFromName:name]; - } - - return nil; -} - -- (id)getModuleInstanceFromClass:(Class)moduleClass -{ - if ([_appTMMDelegate respondsToSelector:@selector(getModuleInstanceFromClass:)]) { - id module = [_appTMMDelegate getModuleInstanceFromClass:moduleClass]; - [self _attachBridgelessAPIsToModule:module]; - return module; - } - - return nil; -} - -- (std::shared_ptr)getTurboModule:(const std::string &)name - jsInvoker:(std::shared_ptr)jsInvoker -{ - if ([_appTMMDelegate respondsToSelector:@selector(getTurboModule:jsInvoker:)]) { - return [_appTMMDelegate getTurboModule:name jsInvoker:jsInvoker]; - } - - return nullptr; -} - - (void)_attachBridgelessAPIsToModule:(id)module FB_OBJC_DIRECT { __weak RCTInstance *weakInstance = self; @@ -287,26 +337,7 @@ void RCTInstanceSetRuntimeDiagnosticFlags(NSString *flags) [_bridgeModuleDecorator attachInteropAPIsToModule:(id)module]; } -#pragma mark - ReactInstanceForwarding - -- (void)callFunctionOnModule:(NSString *)moduleName method:(NSString *)method args:(NSArray *)args -{ - if (_valid) { - _reactInstance->callFunctionOnModule( - [moduleName UTF8String], [method UTF8String], convertIdToFollyDynamic(args ?: @[])); - } -} - -- (void)registerSegmentWithId:(NSNumber *)segmentId path:(NSString *)path -{ - if (_valid) { - self->_reactInstance->registerSegment(static_cast([segmentId unsignedIntValue]), path.UTF8String); - } -} - -#pragma mark - Private - -- (void)loadJSBundle:(NSURL *)sourceURL FB_OBJC_DIRECT +- (void)_loadJSBundle:(NSURL *)sourceURL FB_OBJC_DIRECT { #if RCT_DEV_MENU && __has_include() { @@ -342,17 +373,17 @@ void RCTInstanceSetRuntimeDiagnosticFlags(NSString *flags) [strongSelf invalidate]; return; } - // DevSettings module is needed by loadScriptFromSource's callback so prior initialization is required + // DevSettings module is needed by _loadScriptFromSource's callback so prior initialization is required RCTDevSettings *const devSettings = (RCTDevSettings *)[strongSelf->_turboModuleManager moduleForName:"DevSettings"]; - [strongSelf loadScriptFromSource:source]; + [strongSelf _loadScriptFromSource:source]; // Set up hot module reloading in Dev only. [strongSelf->_performanceLogger markStopForTag:RCTPLScriptDownload]; [devSettings setupHMRClientWithBundleURL:sourceURL]; }]; } -- (void)loadScriptFromSource:(RCTSource *)source FB_OBJC_DIRECT +- (void)_loadScriptFromSource:(RCTSource *)source FB_OBJC_DIRECT { std::lock_guard lock(self->_invalidationMutex); if (!_valid) { @@ -370,7 +401,7 @@ void RCTInstanceSetRuntimeDiagnosticFlags(NSString *flags) } } -- (void)notifyEventDispatcherObserversOfEvent_DEPRECATED:(NSNotification *)notification +- (void)_notifyEventDispatcherObserversOfEvent_DEPRECATED:(NSNotification *)notification { NSDictionary *userInfo = notification.userInfo; id event = [userInfo objectForKey:@"event"]; @@ -383,32 +414,4 @@ void RCTInstanceSetRuntimeDiagnosticFlags(NSString *flags) } } -- (void)invalidate -{ - std::lock_guard lock(self->_invalidationMutex); - self->_valid = false; - - [_surfacePresenter suspend]; - [_jsThreadManager dispatchToJSThread:^{ - /** - * Every TurboModule is invalidated on its own method queue. - * TurboModuleManager invalidate blocks the calling thread until all TurboModules are invalidated. - */ - [self->_turboModuleManager invalidate]; - - // Clean up all the Resources - self->_reactInstance = nullptr; - self->_jsEngineInstance = nullptr; - self->_appTMMDelegate = nil; - self->_delegate = nil; - self->_displayLink = nil; - - self->_turboModuleManager = nil; - self->_performanceLogger = nil; - - // Terminate the JavaScript thread, so that no other work executes after this block. - self->_jsThreadManager = nil; - }]; -} - @end