From 6a1f48e06d8f42bfd3433a225d03c01651efd09c Mon Sep 17 00:00:00 2001 From: Kevin Gozali Date: Wed, 29 Aug 2018 15:36:24 -0700 Subject: [PATCH] TM iOS: rollout strategy 1 - added RCTEnableJSINativeModule(BOOL) Summary: To be able to test out new approach for NativeModules, introduce a simple runtime flag to enable the new system (doesn't exist yet). In addition, each module should declare a static `+ (BOOL)allowJSIBinding` in the objc class to be considered for the new approach. Doing so skips the processing of the module during bridge startup. Note: this doesn't do anything special for `- (NSArray *)extraModulesForBridge:(RCTBridge *)bridge` impl yet. Differential Revision: D9554296 fbshipit-source-id: 3508db6589e9f72367f62aa7ca15fce3d3adda72 --- React/Base/RCTBridge.h | 7 +++++++ React/Base/RCTBridge.m | 10 ++++++++++ React/Base/RCTBridgeModule.h | 6 ++++++ React/CxxBridge/RCTCxxBridge.mm | 3 +++ 4 files changed, 26 insertions(+) diff --git a/React/Base/RCTBridge.h b/React/Base/RCTBridge.h index 5222a15b5..8591bb7ad 100644 --- a/React/Base/RCTBridge.h +++ b/React/Base/RCTBridge.h @@ -93,6 +93,13 @@ typedef NSArray> *(^RCTBridgeModuleListProvider)(void); */ RCT_EXTERN NSString *RCTBridgeModuleNameForClass(Class bridgeModuleClass); +/** + * Experimental. + * Check/set if JSI-bound NativeModule is enabled. By default it's off. + */ +RCT_EXTERN BOOL RCTJSINativeModuleEnabled(void); +RCT_EXTERN void RCTEnableJSINativeModule(BOOL enabled); + /** * Async batched bridge used to communicate with the JavaScript application. */ diff --git a/React/Base/RCTBridge.m b/React/Base/RCTBridge.m index ade50c05d..d8ced5f46 100644 --- a/React/Base/RCTBridge.m +++ b/React/Base/RCTBridge.m @@ -93,6 +93,16 @@ NSString *RCTBridgeModuleNameForClass(Class cls) return name; } +static BOOL jsiNativeModuleEnabled = NO; +BOOL RCTJSINativeModuleEnabled(void) +{ + return jsiNativeModuleEnabled; +} + +void RCTEnableJSINativeModule(BOOL enabled) { + jsiNativeModuleEnabled = enabled; +} + #if RCT_DEBUG void RCTVerifyAllModulesExported(NSArray *extraModules) { diff --git a/React/Base/RCTBridgeModule.h b/React/Base/RCTBridgeModule.h index 1da937e8d..b7726a061 100644 --- a/React/Base/RCTBridgeModule.h +++ b/React/Base/RCTBridgeModule.h @@ -289,6 +289,12 @@ RCT_EXTERN void RCTRegisterModule(Class); \ */ + (BOOL)requiresMainQueueSetup; +/** + * Experimental. + * If YES, this module will be set up via JSI binding instead. + */ ++ (BOOL)allowJSIBinding; + /** * Injects methods into JS. Entries in this array are used in addition to any * methods defined using the macros above. This method is called only once, diff --git a/React/CxxBridge/RCTCxxBridge.mm b/React/CxxBridge/RCTCxxBridge.mm index 2c089b007..22777864a 100644 --- a/React/CxxBridge/RCTCxxBridge.mm +++ b/React/CxxBridge/RCTCxxBridge.mm @@ -549,6 +549,9 @@ struct RCTInstanceCallback : public InstanceCallback { NSArray *moduleClassesCopy = [moduleClasses copy]; NSMutableArray *moduleDataByID = [NSMutableArray arrayWithCapacity:moduleClassesCopy.count]; for (Class moduleClass in moduleClassesCopy) { + if (RCTJSINativeModuleEnabled() && [moduleClass respondsToSelector:@selector(allowJSIBinding)] && [moduleClass allowJSIBinding]) { + continue; + } NSString *moduleName = RCTBridgeModuleNameForClass(moduleClass); // Check for module name collisions