react-native/React/CxxBridge/RCTObjcExecutor.mm

154 lines
4.6 KiB
Plaintext
Raw Normal View History

/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "RCTObjcExecutor.h"
#import <React/RCTCxxUtils.h>
#import <React/RCTFollyConvert.h>
#import <React/RCTJavaScriptExecutor.h>
#import <React/RCTLog.h>
#import <React/RCTProfile.h>
#import <React/RCTUtils.h>
#import <cxxreact/JSBigString.h>
#import <cxxreact/JSExecutor.h>
#import <cxxreact/MessageQueueThread.h>
#import <cxxreact/ModuleRegistry.h>
#import <cxxreact/RAMBundleRegistry.h>
#import <folly/json.h>
namespace facebook {
namespace react {
namespace {
class JSEException : public std::runtime_error {
public:
JSEException(NSError *error)
: runtime_error([[error description] UTF8String]) {}
};
class RCTObjcExecutor : public JSExecutor {
public:
RCTObjcExecutor(id<RCTJavaScriptExecutor> jse,
RCTJavaScriptCompleteBlock errorBlock,
std::shared_ptr<MessageQueueThread> jsThread,
std::shared_ptr<ExecutorDelegate> delegate)
: m_jse(jse)
, m_errorBlock(errorBlock)
, m_delegate(std::move(delegate))
RCTObjcExecutor: fix initializer-list initialization order build warning. Summary: Fixes: #18384 Previously line 42 had a warning of: `Field 'm_jsThread' will be initialized after field 'm_delegate'` This appears to be because the private member fields are declared in a different order than the initializer-list was told to initialize things. I chose to re-order the initializer list because that fixes the warning by matching the code structure to what the compiler was telling us it was going to do. An alternate fix would be to change the order of the member variables declared in the `private:` section to match the coded order in the initializer list. This might be the right move if the initializer list had the correct intent, but this would be a breaking change from a behavior perspective, so I'd need somebody with more knowledge to suggest this is the right move. A. Examine line to see the warning is gone. B. Get a C++ guru to figure out the intent of this file and see if this actually exposed a bug that recommends we go with the alternate fix suggested above. [IOS][MINOR][React/CxxBridge/] - Build warning fix <!-- Help reviewers and the release process by writing your own release notes **INTERNAL and MINOR tagged notes will not be included in the next version's final release notes.** CATEGORY [----------] TYPE [ CLI ] [-------------] LOCATION [ DOCS ] [ BREAKING ] [-------------] [ GENERAL ] [ BUGFIX ] [-{Component}-] [ INTERNAL ] [ ENHANCEMENT ] [ {File} ] [ IOS ] [ FEATURE ] [ {Directory} ] |-----------| [ ANDROID ] [ MINOR ] [ {Framework} ] - | {Message} | [----------] [-------------] [-------------] |-----------| [CATEGORY] [TYPE] [LOCATION] - MESSAGE EXAMPLES: [IOS] [BREAKING] [FlatList] - Change a thing that breaks other things [ANDROID] [BUGFIX] [TextInput] - Did a thing to TextInput [CLI] [FEATURE] [local-cli/info/info.js] - CLI easier to do things with [DOCS] [BUGFIX] [GettingStarted.md] - Accidentally a thing/word [GENERAL] [ENHANCEMENT] [Yoga] - Added new yoga thing/position [INTERNAL] [FEATURE] [./scripts] - Added thing to script that nobody will see --> Closes https://github.com/facebook/react-native/pull/18385 Differential Revision: D7328272 Pulled By: mhorowitz fbshipit-source-id: 59d7ace6222c4609ac7d023f97e522e85e02a9db
2018-03-19 22:10:14 +00:00
, m_jsThread(std::move(jsThread))
{
m_jsCallback = ^(id json, NSError *error) {
if (error) {
// Do not use "m_errorBlock" here as the bridge might be in the middle
// of invalidation as a result of error handling and "this" can be
// already deallocated.
errorBlock(error);
return;
}
m_jsThread->runOnQueue([this, json]{
m_delegate->callNativeModules(*this, convertIdToFollyDynamic(json), true);
});
};
// Synchronously initialize the executor
[jse setUp];
folly::dynamic nativeModuleConfig = folly::dynamic::array;
auto moduleRegistry = m_delegate->getModuleRegistry();
for (const auto &name : moduleRegistry->moduleNames()) {
auto config = moduleRegistry->getConfig(name);
nativeModuleConfig.push_back(config ? config->config : nullptr);
}
folly::dynamic config =
folly::dynamic::object("remoteModuleConfig", std::move(nativeModuleConfig));
setGlobalVariable(
"__fbBatchedBridgeConfig",
std::make_unique<JSBigStdString>(folly::toJson(config)));
}
void loadApplicationScript(
std::unique_ptr<const JSBigString> script,
std::string sourceURL) override {
RCTProfileBeginFlowEvent();
[m_jse executeApplicationScript:[NSData dataWithBytes:script->c_str() length:script->size()]
sourceURL:[[NSURL alloc]
initWithString:@(sourceURL.c_str())]
onComplete:^(NSError *error) {
RCTProfileEndFlowEvent();
if (error) {
m_errorBlock(error);
return;
}
[m_jse flushedQueue:m_jsCallback];
}];
}
void setBundleRegistry(std::unique_ptr<RAMBundleRegistry>) override {
RCTAssert(NO, @"RAM bundles are not supported in RCTObjcExecutor");
}
void registerBundle(uint32_t bundleId, const std::string &bundlePath) override {
RCTAssert(NO, @"RAM bundles are not supported in RCTObjcExecutor");
}
void callFunction(const std::string &module, const std::string &method,
const folly::dynamic &arguments) override {
[m_jse callFunctionOnModule:@(module.c_str())
method:@(method.c_str())
arguments:convertFollyDynamicToId(arguments)
callback:m_jsCallback];
}
void invokeCallback(double callbackId, const folly::dynamic &arguments) override {
[m_jse invokeCallbackID:@(callbackId)
arguments:convertFollyDynamicToId(arguments)
callback:m_jsCallback];
}
virtual void setGlobalVariable(
std::string propName,
std::unique_ptr<const JSBigString> jsonValue) override {
[m_jse injectJSONText:@(jsonValue->c_str())
asGlobalObjectNamed:@(propName.c_str())
callback:m_errorBlock];
}
virtual std::string getDescription() override {
return [NSStringFromClass([m_jse class]) UTF8String];
}
private:
id<RCTJavaScriptExecutor> m_jse;
RCTJavaScriptCompleteBlock m_errorBlock;
std::shared_ptr<ExecutorDelegate> m_delegate;
std::shared_ptr<MessageQueueThread> m_jsThread;
RCTJavaScriptCallback m_jsCallback;
};
}
RCTObjcExecutorFactory::RCTObjcExecutorFactory(
id<RCTJavaScriptExecutor> jse, RCTJavaScriptCompleteBlock errorBlock)
: m_jse(jse)
, m_errorBlock(errorBlock) {}
std::unique_ptr<JSExecutor> RCTObjcExecutorFactory::createJSExecutor(
std::shared_ptr<ExecutorDelegate> delegate,
std::shared_ptr<MessageQueueThread> jsQueue) {
return std::unique_ptr<JSExecutor>(
new RCTObjcExecutor(m_jse, m_errorBlock, jsQueue, delegate));
}
}
}