Skip to content

Commit

Permalink
add ios support
Browse files Browse the repository at this point in the history
  • Loading branch information
Kudo committed May 8, 2024
1 parent f472d53 commit 968bd95
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -154,9 +154,20 @@ class JSI_EXPORT ObjCTurboModule : public TurboModule {

} // namespace facebook::react

@class RCTTurboModuleBindingsInstaller;

@protocol RCTTurboModule <NSObject>

- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
(const facebook::react::ObjCTurboModule::InitParams &)params;

@optional

/**
* Implements this function if a TurboModule needs to install its own JSI bindings.
*/
- (RCTTurboModuleBindingsInstaller *)createBindingsInstaller;

@end

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

#import <Foundation/Foundation.h>

#ifdef __cplusplus
#import <ReactCommon/TurboModule.h>
#endif

NS_ASSUME_NONNULL_BEGIN

/**
* This class is a holder for a RCTTurboModule to get the facebook::react::TurboModule::BindingsInstaller.
*/
@interface RCTTurboModuleBindingsInstaller : NSObject

- (instancetype)init NS_UNAVAILABLE;

#ifdef __cplusplus
- (instancetype)initWithBindingsInstaller:(facebook::react::TurboModule::BindingsInstaller)bindingsInstaller
NS_DESIGNATED_INITIALIZER;

- (facebook::react::TurboModule::BindingsInstaller)get;
#endif

@end

NS_ASSUME_NONNULL_END
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

#import "RCTTurboModuleBindingsInstaller.h"

@implementation RCTTurboModuleBindingsInstaller {
facebook::react::TurboModule::BindingsInstaller _bindingsInstaller;
}

- (instancetype)initWithBindingsInstaller:(facebook::react::TurboModule::BindingsInstaller)bindingsInstaller
{
if (self = [super init]) {
_bindingsInstaller = bindingsInstaller;
}

return self;
}

- (facebook::react::TurboModule::BindingsInstaller)get
{
return _bindingsInstaller;
}

@end
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#import <React/RCTRuntimeExecutorModule.h>
#import <React/RCTUtils.h>
#import <ReactCommon/CxxTurboModuleUtils.h>
#import <ReactCommon/RCTTurboModuleBindingsInstaller.h>
#import <ReactCommon/TurboCxxModule.h>
#import <ReactCommon/TurboModulePerfLogger.h>
#import <ReactCommon/TurboModuleUtils.h>
Expand Down Expand Up @@ -187,6 +188,7 @@ static Class getFallbackClassFromName(const char *name)

@implementation RCTTurboModuleManager {
std::shared_ptr<CallInvoker> _jsInvoker;
facebook::jsi::Runtime *_runtime;
__weak id<RCTTurboModuleManagerDelegate> _delegate;
__weak RCTBridge *_bridge;

Expand Down Expand Up @@ -705,6 +707,14 @@ - (BOOL)_shouldCreateObjCModule:(Class)moduleClass
[(id<RCTCallInvokerModule>)module setCallInvoker:callInvoker];
}

if ([module respondsToSelector:@selector(createBindingsInstaller)]) {
RCTTurboModuleBindingsInstaller *installer =
(RCTTurboModuleBindingsInstaller *)[module performSelector:@selector(createBindingsInstaller)];
if (installer != nil && _runtime) {
installer.get(*_runtime);
}
}

/**
* Some modules need their own queues, but don't provide any, so we need to create it for them.
* These modules typically have the following:
Expand Down Expand Up @@ -914,6 +924,8 @@ - (BOOL)_requiresMainQueueSetup:(Class)moduleClass

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

/**
* We keep TurboModuleManager alive until the JS VM is deleted.
* It is perfectly valid to only use/create TurboModules from JS.
Expand Down Expand Up @@ -1026,12 +1038,14 @@ - (void)bridgeDidInvalidateModules:(NSNotification *)notification
}

[self _invalidateModules];
_runtime = nullptr;
}

- (void)invalidate
{
[self _enterInvalidatingState];
[self _invalidateModules];
_runtime = nullptr;
}

- (void)_enterInvalidatingState
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/

#import <Foundation/Foundation.h>
#import <ReactCommon/RCTTurboModuleBindingsInstaller.h>

#import "RCTNativeSampleTurboModuleSpec.h"

Expand All @@ -15,4 +16,6 @@
*/
@interface RCTSampleTurboModule : NSObject <NativeSampleTurboModuleSpec>

- (RCTTurboModuleBindingsInstaller *)createBindingsInstaller;

@end
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,13 @@ - (dispatch_queue_t)methodQueue
return std::make_shared<NativeSampleTurboModuleSpecJSI>(params);
}

- (RCTTurboModuleBindingsInstaller *)createBindingsInstaller;
{
return [[RCTTurboModuleBindingsInstaller alloc] initWithBindingsInstaller:[](facebook::jsi::Runtime &runtime) {
runtime.global().setProperty(runtime, "__SampleTurboModuleJSIBindings", "Hello JSI!");
}];
}

// Backward compatible invalidation
- (void)invalidate
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import styles from './TurboModuleExampleCommon';
import * as React from 'react';
import {
FlatList,
Platform,
RootTagContext,
Text,
TouchableOpacity,
Expand Down Expand Up @@ -198,10 +197,7 @@ class SampleTurboModuleExample extends React.Component<{||}, State> {
'Cannot load this example because TurboModule is not configured.',
);
}
if (
global.__SampleTurboModuleJSIBindings == null &&
Platform.OS === 'android' // TODO: Add iOS support
) {
if (global.__SampleTurboModuleJSIBindings == null) {
throw new Error(
'The JSI bindings for SampleTurboModule are not installed.',
);
Expand Down

0 comments on commit 968bd95

Please sign in to comment.