Skip to content

Commit

Permalink
Bridgeless mode: Attach bridge/bridgeless apis to interop modules (fa…
Browse files Browse the repository at this point in the history
…cebook#38202)

Summary:
Pull Request resolved: facebook#38202

## Context
Native modules can synthesize these bridge/bridgeless-agnostic abstractions:
- viewRegistry_DEPRECATED
- bundleManager
- callableJSModules
- moduleRegistry

## The Problem
The TurboModule interop layer wasn't attaching these abstractions to legacy modules.

## The Issue
In Bridgeless mode, the React instance attaches these abstractions to **all** modules, by implementing TurboModuleManagerDelegate.

But, the TurboModuleManager creates legacy modules without calling into the TurboModuleManagerDelegate. So, legacy modules never had these abstractions attached.

## The Fix
Move the attachment logic to within TurboModuleManager.

Changelog: [Internal]

Reviewed By: dmytrorykun

Differential Revision: D47074304

fbshipit-source-id: 87408106c00db8011740068ac0bd7dacd6b5ff81
  • Loading branch information
RSNara authored and facebook-github-bot committed Jul 5, 2023
1 parent 8ab233d commit 5f84d73
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 39 deletions.
3 changes: 2 additions & 1 deletion packages/react-native/React/Base/RCTBridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#import <React/RCTBridgeDelegate.h>
#import <React/RCTBridgeModule.h>
#import <React/RCTBridgeModuleDecorator.h>
#import <React/RCTDefines.h>
#import <React/RCTFrameUpdate.h>
#import <React/RCTInvalidating.h>
Expand Down Expand Up @@ -149,7 +150,7 @@ RCT_EXTERN void RCTSetTurboModuleCleanupMode(RCTTurboModuleCleanupMode mode);
* It allows the bridge to attach properties to ObjC modules that give those modules
* access to Bridge APIs.
*/
- (void)attachBridgeAPIsToObjCModule:(id<RCTBridgeModule>)module;
- (RCTBridgeModuleDecorator *)bridgeModuleDecorator;

/**
* Convenience method for retrieving all modules conforming to a given protocol.
Expand Down
4 changes: 2 additions & 2 deletions packages/react-native/React/Base/RCTBridge.m
Original file line number Diff line number Diff line change
Expand Up @@ -226,9 +226,9 @@ - (void)setRCTTurboModuleRegistry:(id<RCTTurboModuleRegistry>)turboModuleRegistr
[self.batchedBridge setRCTTurboModuleRegistry:turboModuleRegistry];
}

- (void)attachBridgeAPIsToObjCModule:(id<RCTBridgeModule>)module
- (RCTBridgeModuleDecorator *)bridgeModuleDecorator
{
[self.batchedBridge attachBridgeAPIsToObjCModule:module];
return [self.batchedBridge bridgeModuleDecorator];
}

- (void)didReceiveReloadCommand
Expand Down
14 changes: 6 additions & 8 deletions packages/react-native/React/CxxBridge/RCTCxxBridge.mm
Original file line number Diff line number Diff line change
Expand Up @@ -245,14 +245,12 @@ - (void)setRCTTurboModuleRegistry:(id<RCTTurboModuleRegistry>)turboModuleRegistr
[_objCModuleRegistry setTurboModuleRegistry:_turboModuleRegistry];
}

- (void)attachBridgeAPIsToObjCModule:(id<RCTBridgeModule>)module
{
RCTBridgeModuleDecorator *bridgeModuleDecorator =
[[RCTBridgeModuleDecorator alloc] initWithViewRegistry:_viewRegistry_DEPRECATED
moduleRegistry:_objCModuleRegistry
bundleManager:_bundleManager
callableJSModules:_callableJSModules];
[bridgeModuleDecorator attachInteropAPIsToModule:module];
- (RCTBridgeModuleDecorator *)bridgeModuleDecorator
{
return [[RCTBridgeModuleDecorator alloc] initWithViewRegistry:_viewRegistry_DEPRECATED
moduleRegistry:_objCModuleRegistry
bundleManager:_bundleManager
callableJSModules:_callableJSModules];
}

- (std::shared_ptr<MessageQueueThread>)jsMessageThread
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -224,26 +224,26 @@ - (void)_start
RuntimeExecutor bufferedRuntimeExecutor = _reactInstance->getBufferedRuntimeExecutor();
timerManager->setRuntimeExecutor(bufferedRuntimeExecutor);

RCTBridgeProxy *bridgeProxy = RCTTurboModuleInteropEnabled() && RCTTurboModuleInteropBridgeProxyEnabled()
? [[RCTBridgeProxy alloc]
initWithViewRegistry:_bridgeModuleDecorator.viewRegistry_DEPRECATED
moduleRegistry:_bridgeModuleDecorator.moduleRegistry
bundleManager:_bridgeModuleDecorator.bundleManager
callableJSModules:_bridgeModuleDecorator.callableJSModules
dispatchToJSThread:^(dispatch_block_t block) {
__strong __typeof(self) strongSelf = weakSelf;
if (strongSelf && strongSelf->_valid) {
strongSelf->_reactInstance->getBufferedRuntimeExecutor()([=](jsi::Runtime &runtime) { block(); });
}
}]
: nil;

// Set up TurboModules
_turboModuleManager =
[[RCTTurboModuleManager alloc] initWithBridge:nil
delegate:self
jsInvoker:std::make_shared<BridgelessJSCallInvoker>(bufferedRuntimeExecutor)];

if (RCTTurboModuleInteropEnabled() && RCTTurboModuleInteropBridgeProxyEnabled()) {
RCTBridgeProxy *bridgeProxy = [[RCTBridgeProxy alloc]
initWithViewRegistry:_bridgeModuleDecorator.viewRegistry_DEPRECATED
moduleRegistry:_bridgeModuleDecorator.moduleRegistry
bundleManager:_bridgeModuleDecorator.bundleManager
callableJSModules:_bridgeModuleDecorator.callableJSModules
dispatchToJSThread:^(dispatch_block_t block) {
__strong __typeof(self) strongSelf = weakSelf;
if (strongSelf && strongSelf->_valid) {
strongSelf->_reactInstance->getBufferedRuntimeExecutor()([=](jsi::Runtime &runtime) { block(); });
}
}];
[_turboModuleManager setBridgeProxy:bridgeProxy];
}
_turboModuleManager = [[RCTTurboModuleManager alloc]
initWithBridgeProxy:bridgeProxy
bridgeModuleDecorator:_bridgeModuleDecorator
delegate:self
jsInvoker:std::make_shared<BridgelessJSCallInvoker>(bufferedRuntimeExecutor)];

// Initialize RCTModuleRegistry so that TurboModules can require other TurboModules.
[_bridgeModuleDecorator.moduleRegistry setTurboModuleRegistry:_turboModuleManager];
Expand Down Expand Up @@ -346,8 +346,6 @@ - (void)_attachBridgelessAPIsToModule:(id<RCTTurboModule>)module
}
#endif
}

[_bridgeModuleDecorator attachInteropAPIsToModule:(id<RCTBridgeModule>)module];
}

- (void)_loadJSBundle:(NSURL *)sourceURL
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#import <memory>

#import <React/RCTBridgeModuleDecorator.h>
#import <React/RCTBridgeProxy.h>
#import <React/RCTDefines.h>
#import <React/RCTTurboModuleRegistry.h>
Expand Down Expand Up @@ -59,16 +60,18 @@ RCT_EXTERN void RCTTurboModuleSetBindingMode(facebook::react::TurboModuleBinding
delegate:(id<RCTTurboModuleManagerDelegate>)delegate
jsInvoker:(std::shared_ptr<facebook::react::CallInvoker>)jsInvoker;

- (instancetype)initWithBridgeProxy:(RCTBridgeProxy *)bridgeProxy
bridgeModuleDecorator:(RCTBridgeModuleDecorator *)bridgeModuleDecorator
delegate:(id<RCTTurboModuleManagerDelegate>)delegate
jsInvoker:(std::shared_ptr<facebook::react::CallInvoker>)jsInvoker;

- (void)installJSBindings:(facebook::jsi::Runtime &)runtime;

/**
* @deprecated: use installJSBindings instead
*/
- (void)installJSBindingWithRuntimeExecutor:(facebook::react::RuntimeExecutor &)runtimeExecutor;

// TODO: Should we move this into the initializer?
- (void)setBridgeProxy:(RCTBridgeProxy *)bridgeProxy;

- (void)invalidate;

@end
Original file line number Diff line number Diff line change
Expand Up @@ -211,16 +211,21 @@ @implementation RCTTurboModuleManager {
NSDictionary<NSString *, Class> *_legacyEagerlyRegisteredModuleClasses;

RCTBridgeProxy *_bridgeProxy;
RCTBridgeModuleDecorator *_bridgeModuleDecorator;
}

- (instancetype)initWithBridge:(RCTBridge *)bridge
bridgeProxy:(RCTBridgeProxy *)bridgeProxy
bridgeModuleDecorator:(RCTBridgeModuleDecorator *)bridgeModuleDecorator
delegate:(id<RCTTurboModuleManagerDelegate>)delegate
jsInvoker:(std::shared_ptr<CallInvoker>)jsInvoker
{
if (self = [super init]) {
_jsInvoker = std::move(jsInvoker);
_delegate = delegate;
_bridge = bridge;
_bridgeProxy = bridgeProxy;
_bridgeModuleDecorator = bridgeModuleDecorator;
_invalidating = false;

if (RCTTurboModuleInteropEnabled()) {
Expand Down Expand Up @@ -256,9 +261,27 @@ - (instancetype)initWithBridge:(RCTBridge *)bridge
return self;
}

- (void)setBridgeProxy:(RCTBridgeProxy *)bridgeProxy
- (instancetype)initWithBridge:(RCTBridge *)bridge
delegate:(id<RCTTurboModuleManagerDelegate>)delegate
jsInvoker:(std::shared_ptr<CallInvoker>)jsInvoker
{
_bridgeProxy = bridgeProxy;
return [self initWithBridge:bridge
bridgeProxy:nil
bridgeModuleDecorator:[bridge bridgeModuleDecorator]
delegate:delegate
jsInvoker:jsInvoker];
}

- (instancetype)initWithBridgeProxy:(RCTBridgeProxy *)bridgeProxy
bridgeModuleDecorator:(RCTBridgeModuleDecorator *)bridgeModuleDecorator
delegate:(id<RCTTurboModuleManagerDelegate>)delegate
jsInvoker:(std::shared_ptr<CallInvoker>)jsInvoker
{
return [self initWithBridge:nil
bridgeProxy:bridgeProxy
bridgeModuleDecorator:bridgeModuleDecorator
delegate:delegate
jsInvoker:jsInvoker];
}

- (void)notifyAboutTurboModuleSetup:(const char *)name
Expand Down Expand Up @@ -720,8 +743,8 @@ - (BOOL)_shouldCreateObjCModule:(Class)moduleClass
/**
* Decorate NativeModules with bridgeless-compatible APIs that call into the bridge.
*/
if (_bridge) {
[_bridge attachBridgeAPIsToObjCModule:module];
if (_bridgeModuleDecorator) {
[_bridgeModuleDecorator attachInteropAPIsToModule:module];
}

/**
Expand Down

0 comments on commit 5f84d73

Please sign in to comment.