154 lines
4.6 KiB
Plaintext
154 lines
4.6 KiB
Plaintext
/**
|
|
* 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))
|
|
, 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));
|
|
}
|
|
|
|
}
|
|
}
|