From ce270220e45abfeabebaaf68643269907bd2605a Mon Sep 17 00:00:00 2001 From: Pieter De Baets Date: Fri, 17 Mar 2017 06:55:44 -0700 Subject: [PATCH] Extract module registry creation to helper Reviewed By: mhorowitz Differential Revision: D4721817 fbshipit-source-id: 2fa17ca5317a57d429aa75d6c1865932af27e02f --- React/CxxBridge/RCTCxxBridge.mm | 57 ++----------------- React/CxxModule/DispatchMessageQueueThread.h | 40 +++++++++++++ React/CxxModule/RCTCxxUtils.h | 10 ++++ React/CxxModule/RCTCxxUtils.mm | 35 +++++++++++- .../RCTNativeModule.h | 0 .../RCTNativeModule.mm | 0 6 files changed, 86 insertions(+), 56 deletions(-) create mode 100644 React/CxxModule/DispatchMessageQueueThread.h rename React/{CxxBridge => CxxModule}/RCTNativeModule.h (100%) rename React/{CxxBridge => CxxModule}/RCTNativeModule.mm (100%) diff --git a/React/CxxBridge/RCTCxxBridge.mm b/React/CxxBridge/RCTCxxBridge.mm index a98b0e2a9..e48906af7 100644 --- a/React/CxxBridge/RCTCxxBridge.mm +++ b/React/CxxBridge/RCTCxxBridge.mm @@ -42,7 +42,6 @@ #import "NSDataBigString.h" #import "RCTMessageThread.h" -#import "RCTNativeModule.h" #import "RCTObjcExecutor.h" #ifdef WITH_FBSYSTRACE @@ -95,35 +94,6 @@ static bool isRAMBundle(NSData *script) { static std::atomic_bool cxxBridgeEnabled(false); -namespace { - -// RCTNativeModule arranges for native methods to be invoked on a queue which -// is not the JS thread. C++ modules don't use RCTNativeModule, so this little -// adapter does the work. - -class DispatchMessageQueueThread : public MessageQueueThread { -public: - DispatchMessageQueueThread(RCTModuleData *moduleData) - : moduleData_(moduleData) {} - - void runOnQueue(std::function&& func) override { - dispatch_async(moduleData_.methodQueue, [func=std::move(func)] { - func(); - }); - } - void runOnQueueSync(std::function&& func) override { - LOG(FATAL) << "Unsupported operation"; - } - void quitSynchronous() override { - LOG(FATAL) << "Unsupported operation"; - } - -private: - RCTModuleData *moduleData_; -}; - -} - @interface RCTCxxBridge () @property (nonatomic, weak, readonly) RCTBridge *parentBridge; @@ -484,35 +454,16 @@ struct RCTInstanceCallback : public InstanceCallback { return _moduleDataByName[RCTBridgeModuleNameForClass(moduleClass)].hasInstance; } -- (std::shared_ptr)_createModuleRegistry +- (std::shared_ptr)_buildModuleRegistry { if (!self.valid) { return {}; } [_performanceLogger markStartForTag:RCTPLNativeModulePrepareConfig]; - RCT_PROFILE_BEGIN_EVENT(RCTProfileTagAlways, @"-[RCTCxxBridge createModuleRegistry]", nil); + RCT_PROFILE_BEGIN_EVENT(RCTProfileTagAlways, @"-[RCTCxxBridge buildModuleRegistry]", nil); - std::vector> modules; - for (RCTModuleData *moduleData in _moduleDataByID) { - if ([moduleData.moduleClass isSubclassOfClass:[RCTCxxModule class]]) { - // If a module does not support automatic instantiation, and - // wasn't provided as an extra module, it may not have an - // instance. If so, skip it. - if (![moduleData hasInstance]) { - continue; - } - modules.emplace_back(std::make_unique( - _reactInstance, - [moduleData.name UTF8String], - [moduleData] { return [(RCTCxxModule *)(moduleData.instance) createModule]; }, - std::make_shared(moduleData))); - } else { - modules.emplace_back(std::make_unique(self, moduleData)); - } - } - - auto registry = std::make_shared(std::move(modules)); + auto registry = buildModuleRegistry(_moduleDataByID, self, _reactInstance); [_performanceLogger markStopForTag:RCTPLNativeModulePrepareConfig]; RCT_PROFILE_END_EVENT(RCTProfileTagAlways, @""); @@ -538,7 +489,7 @@ struct RCTInstanceCallback : public InstanceCallback { std::unique_ptr(new RCTInstanceCallback(self)), executorFactory, _jsMessageThread, - std::move([self _createModuleRegistry])); + std::move([self _buildModuleRegistry])); #if RCT_PROFILE if (RCTProfileIsProfiling()) { diff --git a/React/CxxModule/DispatchMessageQueueThread.h b/React/CxxModule/DispatchMessageQueueThread.h new file mode 100644 index 000000000..c1fb9fb0b --- /dev/null +++ b/React/CxxModule/DispatchMessageQueueThread.h @@ -0,0 +1,40 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#include + +namespace facebook { +namespace react { + +// RCTNativeModule arranges for native methods to be invoked on a queue which +// is not the JS thread. C++ modules don't use RCTNativeModule, so this little +// adapter does the work. + +class DispatchMessageQueueThread : public MessageQueueThread { +public: + DispatchMessageQueueThread(RCTModuleData *moduleData) + : moduleData_(moduleData) {} + + void runOnQueue(std::function&& func) override { + dispatch_async(moduleData_.methodQueue, [func=std::move(func)] { + func(); + }); + } + void runOnQueueSync(std::function&& func) override { + LOG(FATAL) << "Unsupported operation"; + } + void quitSynchronous() override { + LOG(FATAL) << "Unsupported operation"; + } + +private: + RCTModuleData *moduleData_; +}; + +} } diff --git a/React/CxxModule/RCTCxxUtils.h b/React/CxxModule/RCTCxxUtils.h index 2278cf42d..e84032682 100644 --- a/React/CxxModule/RCTCxxUtils.h +++ b/React/CxxModule/RCTCxxUtils.h @@ -7,12 +7,18 @@ * of patent rights can be found in the PATENTS file in the same directory. */ +#include + #import #include #include +#include #include #include +@class RCTBridge; +@class RCTModuleData; + @interface RCTConvert (folly) + (folly::dynamic)folly_dynamic:(id)json; @@ -22,6 +28,10 @@ namespace facebook { namespace react { +class Instance; + +std::shared_ptr buildModuleRegistry(NSArray *modules, RCTBridge *bridge, const std::shared_ptr &instance); + JSContext *contextForGlobalContextRef(JSGlobalContextRef contextRef); /* diff --git a/React/CxxModule/RCTCxxUtils.mm b/React/CxxModule/RCTCxxUtils.mm index 3283f8203..740f5960a 100644 --- a/React/CxxModule/RCTCxxUtils.mm +++ b/React/CxxModule/RCTCxxUtils.mm @@ -10,10 +10,15 @@ #import "RCTCxxUtils.h" #import +#import #import - +#include #include +#import "DispatchMessageQueueThread.h" +#import "RCTCxxModule.h" +#import "RCTNativeModule.h" + using namespace facebook::react; @implementation RCTConvert (folly) @@ -36,6 +41,30 @@ using namespace facebook::react; namespace facebook { namespace react { +std::shared_ptr buildModuleRegistry(NSArray *modules, RCTBridge *bridge, const std::shared_ptr &instance) +{ + std::vector> nativeModules; + for (RCTModuleData *moduleData in modules) { + if ([moduleData.moduleClass isSubclassOfClass:[RCTCxxModule class]]) { + // If a module does not support automatic instantiation, and + // wasn't provided as an extra module, it may not have an + // instance. If so, skip it. + if (![moduleData hasInstance]) { + continue; + } + nativeModules.emplace_back(std::make_unique( + instance, + [moduleData.name UTF8String], + [moduleData] { return [(RCTCxxModule *)(moduleData.instance) createModule]; }, + std::make_shared(moduleData))); + } else { + nativeModules.emplace_back(std::make_unique(bridge, moduleData)); + } + } + + return std::make_shared(std::move(nativeModules)); +} + JSContext *contextForGlobalContextRef(JSGlobalContextRef contextRef) { static std::mutex s_mutex; @@ -61,7 +90,7 @@ JSContext *contextForGlobalContextRef(JSGlobalContextRef contextRef) return ctx; } -static NSError *errorWithException(const std::exception& e) +static NSError *errorWithException(const std::exception &e) { NSString *msg = @(e.what()); NSMutableDictionary *errorInfo = [NSMutableDictionary dictionary]; @@ -75,7 +104,7 @@ static NSError *errorWithException(const std::exception& e) NSError *nestedError; try { std::rethrow_if_nested(e); - } catch(const std::exception& e) { + } catch(const std::exception &e) { nestedError = errorWithException(e); } catch(...) {} diff --git a/React/CxxBridge/RCTNativeModule.h b/React/CxxModule/RCTNativeModule.h similarity index 100% rename from React/CxxBridge/RCTNativeModule.h rename to React/CxxModule/RCTNativeModule.h diff --git a/React/CxxBridge/RCTNativeModule.mm b/React/CxxModule/RCTNativeModule.mm similarity index 100% rename from React/CxxBridge/RCTNativeModule.mm rename to React/CxxModule/RCTNativeModule.mm