mirror of
https://github.com/status-im/react-native.git
synced 2025-02-25 07:35:25 +00:00
Lazily instantiate native modules
Summary: Instead of sending a list of modules over to JS on startup (and actually blocking script execution) instead provide a proxy object that constructs each of these lazily. Reviewed By: lexs Differential Revision: D3936979 fbshipit-source-id: 71bde822f01eb17a29f56c5e60e95e98e207d74d
This commit is contained in:
parent
606fc11487
commit
9ed9bca0bf
@ -58,6 +58,9 @@ function genModule(config: ?ModuleConfig, moduleID: number): ?{name: string, mod
|
|||||||
return { name: moduleName, module };
|
return { name: moduleName, module };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// export this method as a global so we can call it from native
|
||||||
|
global.__fbGenNativeModule = genModule;
|
||||||
|
|
||||||
function loadModule(name: string, moduleID: number): ?Object {
|
function loadModule(name: string, moduleID: number): ?Object {
|
||||||
invariant(global.nativeRequireModuleConfig,
|
invariant(global.nativeRequireModuleConfig,
|
||||||
'Can\'t lazily create module without nativeRequireModuleConfig');
|
'Can\'t lazily create module without nativeRequireModuleConfig');
|
||||||
@ -115,27 +118,31 @@ function createErrorFromErrorData(errorData: {message: string}): Error {
|
|||||||
return Object.assign(error, extraErrorInfo);
|
return Object.assign(error, extraErrorInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
const bridgeConfig = global.__fbBatchedBridgeConfig;
|
let NativeModules : {[moduleName: string]: Object} = {};
|
||||||
invariant(bridgeConfig, '__fbBatchedBridgeConfig is not set, cannot invoke native modules');
|
if (global.nativeModuleProxy) {
|
||||||
|
NativeModules = global.nativeModuleProxy;
|
||||||
|
} else {
|
||||||
|
const bridgeConfig = global.__fbBatchedBridgeConfig;
|
||||||
|
invariant(bridgeConfig, '__fbBatchedBridgeConfig is not set, cannot invoke native modules');
|
||||||
|
|
||||||
const NativeModules : {[moduleName: string]: Object} = {};
|
(bridgeConfig.remoteModuleConfig || []).forEach((config: ModuleConfig, moduleID: number) => {
|
||||||
(bridgeConfig.remoteModuleConfig || []).forEach((config: ModuleConfig, moduleID: number) => {
|
// Initially this config will only contain the module name when running in JSC. The actual
|
||||||
// Initially this config will only contain the module name when running in JSC. The actual
|
// configuration of the module will be lazily loaded.
|
||||||
// configuration of the module will be lazily loaded.
|
const info = genModule(config, moduleID);
|
||||||
const info = genModule(config, moduleID);
|
if (!info) {
|
||||||
if (!info) {
|
return;
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (info.module) {
|
if (info.module) {
|
||||||
NativeModules[info.name] = info.module;
|
NativeModules[info.name] = info.module;
|
||||||
}
|
}
|
||||||
// If there's no module config, define a lazy getter
|
// If there's no module config, define a lazy getter
|
||||||
else {
|
else {
|
||||||
defineLazyObjectProperty(NativeModules, info.name, {
|
defineLazyObjectProperty(NativeModules, info.name, {
|
||||||
get: () => loadModule(info.name, moduleID)
|
get: () => loadModule(info.name, moduleID)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = NativeModules;
|
module.exports = NativeModules;
|
||||||
|
@ -42,12 +42,13 @@ ProxyExecutor::ProxyExecutor(jni::global_ref<jobject>&& executorInstance,
|
|||||||
, m_delegate(delegate) {
|
, m_delegate(delegate) {
|
||||||
|
|
||||||
folly::dynamic nativeModuleConfig = folly::dynamic::array;
|
folly::dynamic nativeModuleConfig = folly::dynamic::array;
|
||||||
auto moduleRegistry = delegate->getModuleRegistry();
|
|
||||||
|
|
||||||
{
|
{
|
||||||
SystraceSection s("collectNativeModuleDescriptions");
|
SystraceSection s("collectNativeModuleDescriptions");
|
||||||
|
auto moduleRegistry = delegate->getModuleRegistry();
|
||||||
for (const auto& name : moduleRegistry->moduleNames()) {
|
for (const auto& name : moduleRegistry->moduleNames()) {
|
||||||
nativeModuleConfig.push_back(moduleRegistry->getConfig(name));
|
auto config = moduleRegistry->getConfig(name);
|
||||||
|
nativeModuleConfig.push_back(config ? config->config : nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ LOCAL_SRC_FILES := \
|
|||||||
JSCLegacyProfiler.cpp \
|
JSCLegacyProfiler.cpp \
|
||||||
JSCLegacyTracing.cpp \
|
JSCLegacyTracing.cpp \
|
||||||
JSCMemory.cpp \
|
JSCMemory.cpp \
|
||||||
|
JSCNativeModules.cpp \
|
||||||
JSCPerfStats.cpp \
|
JSCPerfStats.cpp \
|
||||||
JSCTracing.cpp \
|
JSCTracing.cpp \
|
||||||
JSCWebWorker.cpp \
|
JSCWebWorker.cpp \
|
||||||
|
@ -116,6 +116,7 @@ CXXREACT_PUBLIC_HEADERS = [
|
|||||||
'Instance.h',
|
'Instance.h',
|
||||||
'JSCExecutor.h',
|
'JSCExecutor.h',
|
||||||
'JSCHelpers.h',
|
'JSCHelpers.h',
|
||||||
|
'JSCNativeModules.h',
|
||||||
'JSCWebWorker.h',
|
'JSCWebWorker.h',
|
||||||
'JSModulesUnbundle.h',
|
'JSModulesUnbundle.h',
|
||||||
'MessageQueueThread.h',
|
'MessageQueueThread.h',
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include "Platform.h"
|
#include "Platform.h"
|
||||||
#include "SystraceSection.h"
|
#include "SystraceSection.h"
|
||||||
#include "Value.h"
|
#include "Value.h"
|
||||||
|
#include "JSCNativeModules.h"
|
||||||
#include "JSCSamplingProfiler.h"
|
#include "JSCSamplingProfiler.h"
|
||||||
#include "JSModulesUnbundle.h"
|
#include "JSModulesUnbundle.h"
|
||||||
#include "ModuleRegistry.h"
|
#include "ModuleRegistry.h"
|
||||||
@ -79,6 +80,28 @@ inline JSObjectCallAsFunctionCallback exceptionWrapMethod() {
|
|||||||
return &funcWrapper::call;
|
return &funcWrapper::call;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<JSValueRef (JSCExecutor::*method)(JSObjectRef object, JSStringRef propertyName)>
|
||||||
|
inline JSObjectGetPropertyCallback exceptionWrapMethod() {
|
||||||
|
struct funcWrapper {
|
||||||
|
static JSValueRef call(
|
||||||
|
JSContextRef ctx,
|
||||||
|
JSObjectRef object,
|
||||||
|
JSStringRef propertyName,
|
||||||
|
JSValueRef *exception) {
|
||||||
|
try {
|
||||||
|
auto globalObj = JSContextGetGlobalObject(ctx);
|
||||||
|
auto executor = static_cast<JSCExecutor*>(JSObjectGetPrivate(globalObj));
|
||||||
|
return (executor->*method)(object, propertyName);
|
||||||
|
} catch (...) {
|
||||||
|
*exception = translatePendingCppExceptionToJSError(ctx, object);
|
||||||
|
return JSValueMakeUndefined(ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return &funcWrapper::call;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
@ -109,28 +132,15 @@ JSCExecutor::JSCExecutor(std::shared_ptr<ExecutorDelegate> delegate,
|
|||||||
m_delegate(delegate),
|
m_delegate(delegate),
|
||||||
m_deviceCacheDir(cacheDir),
|
m_deviceCacheDir(cacheDir),
|
||||||
m_messageQueueThread(messageQueueThread),
|
m_messageQueueThread(messageQueueThread),
|
||||||
|
m_nativeModules(delegate->getModuleRegistry()),
|
||||||
m_jscConfig(jscConfig) {
|
m_jscConfig(jscConfig) {
|
||||||
initOnJSVMThread();
|
initOnJSVMThread();
|
||||||
|
|
||||||
SystraceSection s("setBatchedBridgeConfig");
|
|
||||||
|
|
||||||
folly::dynamic nativeModuleConfig = folly::dynamic::array();
|
|
||||||
|
|
||||||
{
|
{
|
||||||
SystraceSection s("collectNativeModuleNames");
|
SystraceSection s("nativeModuleProxy object");
|
||||||
for (auto& name : delegate->getModuleRegistry()->moduleNames()) {
|
installGlobalProxy(m_context, "nativeModuleProxy",
|
||||||
nativeModuleConfig.push_back(folly::dynamic::array(std::move(name)));
|
exceptionWrapMethod<&JSCExecutor::getNativeModule>());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
folly::dynamic config =
|
|
||||||
folly::dynamic::object
|
|
||||||
("remoteModuleConfig", std::move(nativeModuleConfig));
|
|
||||||
|
|
||||||
SystraceSection t("setGlobalVariable");
|
|
||||||
setGlobalVariable(
|
|
||||||
"__fbBatchedBridgeConfig",
|
|
||||||
folly::make_unique<JSBigStdString>(folly::toJson(config)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JSCExecutor::JSCExecutor(
|
JSCExecutor::JSCExecutor(
|
||||||
@ -146,6 +156,7 @@ JSCExecutor::JSCExecutor(
|
|||||||
m_owner(owner),
|
m_owner(owner),
|
||||||
m_deviceCacheDir(owner->m_deviceCacheDir),
|
m_deviceCacheDir(owner->m_deviceCacheDir),
|
||||||
m_messageQueueThread(messageQueueThread),
|
m_messageQueueThread(messageQueueThread),
|
||||||
|
m_nativeModules(delegate->getModuleRegistry()),
|
||||||
m_jscConfig(jscConfig) {
|
m_jscConfig(jscConfig) {
|
||||||
// We post initOnJSVMThread here so that the owner doesn't have to wait for
|
// We post initOnJSVMThread here so that the owner doesn't have to wait for
|
||||||
// initialization on its own thread
|
// initialization on its own thread
|
||||||
@ -211,7 +222,6 @@ void JSCExecutor::initOnJSVMThread() throw(JSException) {
|
|||||||
// Add a pointer to ourselves so we can retrieve it later in our hooks
|
// Add a pointer to ourselves so we can retrieve it later in our hooks
|
||||||
JSObjectSetPrivate(JSContextGetGlobalObject(m_context), this);
|
JSObjectSetPrivate(JSContextGetGlobalObject(m_context), this);
|
||||||
|
|
||||||
installNativeHook<&JSCExecutor::nativeRequireModuleConfig>("nativeRequireModuleConfig");
|
|
||||||
installNativeHook<&JSCExecutor::nativeFlushQueueImmediate>("nativeFlushQueueImmediate");
|
installNativeHook<&JSCExecutor::nativeFlushQueueImmediate>("nativeFlushQueueImmediate");
|
||||||
installNativeHook<&JSCExecutor::nativeCallSyncHook>("nativeCallSyncHook");
|
installNativeHook<&JSCExecutor::nativeCallSyncHook>("nativeCallSyncHook");
|
||||||
|
|
||||||
@ -264,6 +274,8 @@ void JSCExecutor::terminateOnJSVMThread() {
|
|||||||
terminateOwnedWebWorker(workerId);
|
terminateOwnedWebWorker(workerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_nativeModules.reset();
|
||||||
|
|
||||||
JSGlobalContextRelease(m_context);
|
JSGlobalContextRelease(m_context);
|
||||||
m_context = nullptr;
|
m_context = nullptr;
|
||||||
}
|
}
|
||||||
@ -647,6 +659,14 @@ void JSCExecutor::installNativeHook(const char* name) {
|
|||||||
installGlobalFunction(m_context, name, exceptionWrapMethod<method>());
|
installGlobalFunction(m_context, name, exceptionWrapMethod<method>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JSValueRef JSCExecutor::getNativeModule(JSObjectRef object, JSStringRef propertyName) {
|
||||||
|
if (JSStringIsEqualToUTF8CString(propertyName, "name")) {
|
||||||
|
return Value(m_context, String("NativeModules"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_nativeModules.getModule(m_context, propertyName);
|
||||||
|
}
|
||||||
|
|
||||||
JSValueRef JSCExecutor::nativePostMessage(
|
JSValueRef JSCExecutor::nativePostMessage(
|
||||||
size_t argumentCount,
|
size_t argumentCount,
|
||||||
const JSValueRef arguments[]) {
|
const JSValueRef arguments[]) {
|
||||||
@ -680,18 +700,6 @@ JSValueRef JSCExecutor::nativeRequire(
|
|||||||
return JSValueMakeUndefined(m_context);
|
return JSValueMakeUndefined(m_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
JSValueRef JSCExecutor::nativeRequireModuleConfig(
|
|
||||||
size_t argumentCount,
|
|
||||||
const JSValueRef arguments[]) {
|
|
||||||
if (argumentCount != 1) {
|
|
||||||
throw std::invalid_argument("Got wrong number of args");
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string moduleName = Value(m_context, arguments[0]).toString().str();
|
|
||||||
folly::dynamic config = m_delegate->getModuleRegistry()->getConfig(moduleName);
|
|
||||||
return Value::fromDynamic(m_context, config);
|
|
||||||
}
|
|
||||||
|
|
||||||
JSValueRef JSCExecutor::nativeFlushQueueImmediate(
|
JSValueRef JSCExecutor::nativeFlushQueueImmediate(
|
||||||
size_t argumentCount,
|
size_t argumentCount,
|
||||||
const JSValueRef arguments[]) {
|
const JSValueRef arguments[]) {
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include "ExecutorToken.h"
|
#include "ExecutorToken.h"
|
||||||
#include "JSCHelpers.h"
|
#include "JSCHelpers.h"
|
||||||
#include "Value.h"
|
#include "Value.h"
|
||||||
|
#include "JSCNativeModules.h"
|
||||||
|
|
||||||
namespace facebook {
|
namespace facebook {
|
||||||
namespace react {
|
namespace react {
|
||||||
@ -102,6 +103,7 @@ private:
|
|||||||
std::string m_deviceCacheDir;
|
std::string m_deviceCacheDir;
|
||||||
std::shared_ptr<MessageQueueThread> m_messageQueueThread;
|
std::shared_ptr<MessageQueueThread> m_messageQueueThread;
|
||||||
std::unique_ptr<JSModulesUnbundle> m_unbundle;
|
std::unique_ptr<JSModulesUnbundle> m_unbundle;
|
||||||
|
JSCNativeModules m_nativeModules;
|
||||||
folly::dynamic m_jscConfig;
|
folly::dynamic m_jscConfig;
|
||||||
|
|
||||||
folly::Optional<Object> m_invokeCallbackAndReturnFlushedQueueJS;
|
folly::Optional<Object> m_invokeCallbackAndReturnFlushedQueueJS;
|
||||||
@ -142,10 +144,8 @@ private:
|
|||||||
|
|
||||||
template< JSValueRef (JSCExecutor::*method)(size_t, const JSValueRef[])>
|
template< JSValueRef (JSCExecutor::*method)(size_t, const JSValueRef[])>
|
||||||
void installNativeHook(const char* name);
|
void installNativeHook(const char* name);
|
||||||
|
JSValueRef getNativeModule(JSObjectRef object, JSStringRef propertyName);
|
||||||
|
|
||||||
JSValueRef nativeRequireModuleConfig(
|
|
||||||
size_t argumentCount,
|
|
||||||
const JSValueRef arguments[]);
|
|
||||||
JSValueRef nativeStartWorker(
|
JSValueRef nativeStartWorker(
|
||||||
size_t argumentCount,
|
size_t argumentCount,
|
||||||
const JSValueRef arguments[]);
|
const JSValueRef arguments[]);
|
||||||
|
@ -24,6 +24,25 @@ void installGlobalFunction(
|
|||||||
JSStringRelease(jsName);
|
JSStringRelease(jsName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void installGlobalProxy(
|
||||||
|
JSGlobalContextRef ctx,
|
||||||
|
const char* name,
|
||||||
|
JSObjectGetPropertyCallback callback) {
|
||||||
|
JSClassDefinition proxyClassDefintion = kJSClassDefinitionEmpty;
|
||||||
|
proxyClassDefintion.className = "_FBProxyClass";
|
||||||
|
proxyClassDefintion.getProperty = callback;
|
||||||
|
JSClassRef proxyClass = JSClassCreate(&proxyClassDefintion);
|
||||||
|
|
||||||
|
JSObjectRef proxyObj = JSObjectMake(ctx, proxyClass, nullptr);
|
||||||
|
|
||||||
|
JSObjectRef globalObject = JSContextGetGlobalObject(ctx);
|
||||||
|
JSStringRef jsName = JSStringCreateWithUTF8CString(name);
|
||||||
|
JSObjectSetProperty(ctx, globalObject, jsName, proxyObj, 0, NULL);
|
||||||
|
|
||||||
|
JSStringRelease(jsName);
|
||||||
|
JSClassRelease(proxyClass);
|
||||||
|
}
|
||||||
|
|
||||||
JSValueRef makeJSCException(
|
JSValueRef makeJSCException(
|
||||||
JSContextRef ctx,
|
JSContextRef ctx,
|
||||||
const char* exception_text) {
|
const char* exception_text) {
|
||||||
|
@ -38,6 +38,11 @@ void installGlobalFunction(
|
|||||||
const char* name,
|
const char* name,
|
||||||
JSObjectCallAsFunctionCallback callback);
|
JSObjectCallAsFunctionCallback callback);
|
||||||
|
|
||||||
|
void installGlobalProxy(
|
||||||
|
JSGlobalContextRef ctx,
|
||||||
|
const char* name,
|
||||||
|
JSObjectGetPropertyCallback callback);
|
||||||
|
|
||||||
JSValueRef makeJSCException(
|
JSValueRef makeJSCException(
|
||||||
JSContextRef ctx,
|
JSContextRef ctx,
|
||||||
const char* exception_text);
|
const char* exception_text);
|
||||||
|
63
ReactCommon/cxxreact/JSCNativeModules.cpp
Normal file
63
ReactCommon/cxxreact/JSCNativeModules.cpp
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||||
|
|
||||||
|
#include "JSCNativeModules.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace facebook {
|
||||||
|
namespace react {
|
||||||
|
|
||||||
|
JSCNativeModules::JSCNativeModules(std::shared_ptr<ModuleRegistry> moduleRegistry) :
|
||||||
|
m_moduleRegistry(std::move(moduleRegistry)) {}
|
||||||
|
|
||||||
|
JSValueRef JSCNativeModules::getModule(JSContextRef context, JSStringRef jsName) {
|
||||||
|
std::string moduleName = String::ref(jsName).str();
|
||||||
|
|
||||||
|
const auto it = m_objects.find(moduleName);
|
||||||
|
if (it != m_objects.end()) {
|
||||||
|
return static_cast<JSObjectRef>(it->second);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto module = createModule(moduleName, context);
|
||||||
|
if (!module.hasValue()) {
|
||||||
|
return JSValueMakeUndefined(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Protect since we'll be holding on to this value, even though JS may not
|
||||||
|
module->makeProtected();
|
||||||
|
|
||||||
|
auto result = m_objects.emplace(std::move(moduleName), std::move(*module)).first;
|
||||||
|
return static_cast<JSObjectRef>(result->second);
|
||||||
|
}
|
||||||
|
|
||||||
|
void JSCNativeModules::reset() {
|
||||||
|
m_genNativeModuleJS = nullptr;
|
||||||
|
m_objects.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
folly::Optional<Object> JSCNativeModules::createModule(const std::string& name, JSContextRef context) {
|
||||||
|
if (!m_genNativeModuleJS) {
|
||||||
|
auto global = Object::getGlobalObject(context);
|
||||||
|
m_genNativeModuleJS = global.getProperty("__fbGenNativeModule").asObject();
|
||||||
|
m_genNativeModuleJS->makeProtected();
|
||||||
|
|
||||||
|
// Initialize the module name list, otherwise getModuleConfig won't work
|
||||||
|
// TODO (pieterdb): fix this in ModuleRegistry
|
||||||
|
m_moduleRegistry->moduleNames();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto result = m_moduleRegistry->getConfig(name);
|
||||||
|
if (!result.hasValue()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
Value moduleInfo = m_genNativeModuleJS->callAsFunction({
|
||||||
|
Value::fromDynamic(context, result->config),
|
||||||
|
JSValueMakeNumber(context, result->index)
|
||||||
|
});
|
||||||
|
CHECK(!moduleInfo.isNull()) << "Module returned from genNativeModule is null";
|
||||||
|
|
||||||
|
return moduleInfo.asObject().getProperty("module").asObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
} }
|
35
ReactCommon/cxxreact/JSCNativeModules.h
Normal file
35
ReactCommon/cxxreact/JSCNativeModules.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <folly/Optional.h>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "Value.h"
|
||||||
|
#include "ModuleRegistry.h"
|
||||||
|
|
||||||
|
namespace facebook {
|
||||||
|
namespace react {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds and creates JS representations of the modules in ModuleRegistry
|
||||||
|
*/
|
||||||
|
class JSCNativeModules {
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit JSCNativeModules(std::shared_ptr<ModuleRegistry> moduleRegistry);
|
||||||
|
JSValueRef getModule(JSContextRef context, JSStringRef name);
|
||||||
|
void reset();
|
||||||
|
|
||||||
|
private:
|
||||||
|
folly::Optional<Object> m_genNativeModuleJS;
|
||||||
|
std::shared_ptr<ModuleRegistry> m_moduleRegistry;
|
||||||
|
std::unordered_map<std::string, Object> m_objects;
|
||||||
|
|
||||||
|
folly::Optional<Object> createModule(const std::string& name, JSContextRef context);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -38,17 +38,17 @@ std::vector<std::string> ModuleRegistry::moduleNames() {
|
|||||||
return names;
|
return names;
|
||||||
}
|
}
|
||||||
|
|
||||||
folly::dynamic ModuleRegistry::getConfig(const std::string& name) {
|
folly::Optional<ModuleConfig> ModuleRegistry::getConfig(const std::string& name) {
|
||||||
SystraceSection s("getConfig", "module", name);
|
SystraceSection s("getConfig", "module", name);
|
||||||
auto it = modulesByName_.find(name);
|
auto it = modulesByName_.find(name);
|
||||||
if (it == modulesByName_.end()) {
|
if (it == modulesByName_.end()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
CHECK(it->second < modules_.size());
|
|
||||||
|
|
||||||
|
CHECK(it->second < modules_.size());
|
||||||
NativeModule* module = modules_[it->second].get();
|
NativeModule* module = modules_[it->second].get();
|
||||||
|
|
||||||
// string name, [object constants,] array methodNames (methodId is index), [array promiseMethodIds], [array syncMethodIds]
|
// string name, object constants, array methodNames (methodId is index), [array promiseMethodIds], [array syncMethodIds]
|
||||||
folly::dynamic config = folly::dynamic::array(name);
|
folly::dynamic config = folly::dynamic::array(name);
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -89,7 +89,7 @@ folly::dynamic ModuleRegistry::getConfig(const std::string& name) {
|
|||||||
// no constants or methods
|
// no constants or methods
|
||||||
return nullptr;
|
return nullptr;
|
||||||
} else {
|
} else {
|
||||||
return config;
|
return ModuleConfig({it->second, config});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <folly/dynamic.h>
|
#include <folly/dynamic.h>
|
||||||
|
#include <folly/Optional.h>
|
||||||
|
|
||||||
#include "ExecutorToken.h"
|
#include "ExecutorToken.h"
|
||||||
#include "NativeModule.h"
|
#include "NativeModule.h"
|
||||||
@ -15,6 +16,11 @@ namespace react {
|
|||||||
|
|
||||||
class NativeModule;
|
class NativeModule;
|
||||||
|
|
||||||
|
struct ModuleConfig {
|
||||||
|
size_t index;
|
||||||
|
folly::dynamic config;
|
||||||
|
};
|
||||||
|
|
||||||
class ModuleRegistry {
|
class ModuleRegistry {
|
||||||
public:
|
public:
|
||||||
// not implemented:
|
// not implemented:
|
||||||
@ -26,7 +32,9 @@ class ModuleRegistry {
|
|||||||
|
|
||||||
ModuleRegistry(std::vector<std::unique_ptr<NativeModule>> modules);
|
ModuleRegistry(std::vector<std::unique_ptr<NativeModule>> modules);
|
||||||
std::vector<std::string> moduleNames();
|
std::vector<std::string> moduleNames();
|
||||||
folly::dynamic getConfig(const std::string& name);
|
|
||||||
|
folly::Optional<ModuleConfig> getConfig(const std::string& name);
|
||||||
|
|
||||||
void callNativeMethod(ExecutorToken token, unsigned int moduleId, unsigned int methodId,
|
void callNativeMethod(ExecutorToken token, unsigned int moduleId, unsigned int methodId,
|
||||||
folly::dynamic&& params, int callId);
|
folly::dynamic&& params, int callId);
|
||||||
MethodCallResult callSerializableNativeHook(ExecutorToken token, unsigned int moduleId, unsigned int methodId, folly::dynamic&& args);
|
MethodCallResult callSerializableNativeHook(ExecutorToken token, unsigned int moduleId, unsigned int methodId, folly::dynamic&& args);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user