Register split segment paths with RAMBundleRegistry

Differential Revision: D6284466

fbshipit-source-id: c80cf929af38f92f06cca5b366c58785ae992d83
This commit is contained in:
Alex Dvornikov 2017-11-09 11:55:37 -08:00 коммит произвёл Facebook Github Bot
Родитель 820cfa1f3b
Коммит cff0d8e0e5
16 изменённых файлов: 62 добавлений и 13 удалений

Просмотреть файл

@ -1152,7 +1152,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithBundleURL:(__unused NSURL *)bundleUR
? [[self.delegate jsSegmentsDirectory].path stringByAppendingString:@"/"] ? [[self.delegate jsSegmentsDirectory].path stringByAppendingString:@"/"]
: nil; : nil;
auto registry = jsSegmentsDirectory != nil auto registry = jsSegmentsDirectory != nil
? RAMBundleRegistry::multipleBundlesRegistry(std::move(ramBundle), JSIndexedRAMBundle::buildFactory(jsSegmentsDirectory.UTF8String)) ? RAMBundleRegistry::multipleBundlesRegistry(std::move(ramBundle), JSIndexedRAMBundle::buildFactory())
: RAMBundleRegistry::singleBundleRegistry(std::move(ramBundle)); : RAMBundleRegistry::singleBundleRegistry(std::move(ramBundle));
self->_reactInstance->loadRAMBundle(std::move(registry), std::move(scriptStr), self->_reactInstance->loadRAMBundle(std::move(registry), std::move(scriptStr),
sourceUrlStr.UTF8String, !async); sourceUrlStr.UTF8String, !async);

Просмотреть файл

@ -95,6 +95,10 @@ public:
RCTAssert(NO, @"RAM bundles are not supported in RCTObjcExecutor"); 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, void callFunction(const std::string &module, const std::string &method,
const folly::dynamic &arguments) override { const folly::dynamic &arguments) override {
[m_jse callFunctionOnModule:@(module.c_str()) [m_jse callFunctionOnModule:@(module.c_str())

Просмотреть файл

@ -212,7 +212,7 @@ void CatalystInstanceImpl::jniLoadScriptFromFile(const std::string& fileName,
auto script = bundle->getStartupCode(); auto script = bundle->getStartupCode();
auto registry = jsSegmentsDirectory_.empty() auto registry = jsSegmentsDirectory_.empty()
? RAMBundleRegistry::singleBundleRegistry(std::move(bundle)) ? RAMBundleRegistry::singleBundleRegistry(std::move(bundle))
: RAMBundleRegistry::multipleBundlesRegistry(std::move(bundle), JSIndexedRAMBundle::buildFactory(jsSegmentsDirectory_)); : RAMBundleRegistry::multipleBundlesRegistry(std::move(bundle), JSIndexedRAMBundle::buildFactory());
instance_->loadRAMBundle( instance_->loadRAMBundle(
std::move(registry), std::move(registry),
std::move(script), std::move(script),

Просмотреть файл

@ -90,6 +90,12 @@ void ProxyExecutor::setBundleRegistry(std::unique_ptr<RAMBundleRegistry>) {
"Loading application RAM bundles is not supported for proxy executors"); "Loading application RAM bundles is not supported for proxy executors");
} }
void ProxyExecutor::registerBundle(uint32_t bundleId, const std::string& bundlePath) {
jni::throwNewJavaException(
"java/lang/UnsupportedOperationException",
"Loading application RAM bundles is not supported for proxy executors");
}
void ProxyExecutor::callFunction(const std::string& moduleId, const std::string& methodId, const folly::dynamic& arguments) { void ProxyExecutor::callFunction(const std::string& moduleId, const std::string& methodId, const folly::dynamic& arguments) {
auto call = folly::dynamic::array(moduleId, methodId, std::move(arguments)); auto call = folly::dynamic::array(moduleId, methodId, std::move(arguments));

Просмотреть файл

@ -37,6 +37,8 @@ public:
std::string sourceURL) override; std::string sourceURL) override;
virtual void setBundleRegistry( virtual void setBundleRegistry(
std::unique_ptr<RAMBundleRegistry> bundle) override; std::unique_ptr<RAMBundleRegistry> bundle) override;
virtual void registerBundle(
uint32_t bundleId, const std::string& bundlePath) override;
virtual void callFunction( virtual void callFunction(
const std::string& moduleId, const std::string& moduleId,
const std::string& methodId, const std::string& methodId,

Просмотреть файл

@ -156,6 +156,10 @@ void Instance::callJSCallback(uint64_t callbackId, folly::dynamic &&params) {
nativeToJsBridge_->invokeCallback((double)callbackId, std::move(params)); nativeToJsBridge_->invokeCallback((double)callbackId, std::move(params));
} }
void Instance::registerBundle(uint32_t bundleId, const std::string& bundlePath) {
nativeToJsBridge_->registerBundle(bundleId, bundlePath);
}
const ModuleRegistry &Instance::getModuleRegistry() const { const ModuleRegistry &Instance::getModuleRegistry() const {
return *moduleRegistry_; return *moduleRegistry_;
} }

Просмотреть файл

@ -59,6 +59,9 @@ public:
folly::dynamic &&params); folly::dynamic &&params);
void callJSCallback(uint64_t callbackId, folly::dynamic &&params); void callJSCallback(uint64_t callbackId, folly::dynamic &&params);
// This method is experimental, and may be modified or removed.
void registerBundle(uint32_t bundleId, const std::string& bundlePath);
// This method is experimental, and may be modified or removed. // This method is experimental, and may be modified or removed.
template <typename T> template <typename T>
Value callFunctionSync(const std::string &module, const std::string &method, Value callFunctionSync(const std::string &module, const std::string &method,

Просмотреть файл

@ -458,6 +458,12 @@ namespace facebook {
m_bundleRegistry = std::move(bundleRegistry); m_bundleRegistry = std::move(bundleRegistry);
} }
void JSCExecutor::registerBundle(uint32_t bundleId, const std::string& bundlePath) {
if (m_bundleRegistry) {
m_bundleRegistry->registerBundle(bundleId, bundlePath);
}
}
void JSCExecutor::bindBridge() throw(JSException) { void JSCExecutor::bindBridge() throw(JSException) {
SystraceSection s("JSCExecutor::bindBridge"); SystraceSection s("JSCExecutor::bindBridge");
std::call_once(m_bindFlag, [this] { std::call_once(m_bindFlag, [this] {

Просмотреть файл

@ -66,6 +66,7 @@ public:
std::string sourceURL) override; std::string sourceURL) override;
virtual void setBundleRegistry(std::unique_ptr<RAMBundleRegistry> bundleRegistry) override; virtual void setBundleRegistry(std::unique_ptr<RAMBundleRegistry> bundleRegistry) override;
virtual void registerBundle(uint32_t bundleId, const std::string& bundlePath) override;
virtual void callFunction( virtual void callFunction(
const std::string& moduleId, const std::string& moduleId,

Просмотреть файл

@ -53,6 +53,11 @@ public:
*/ */
virtual void setBundleRegistry(std::unique_ptr<RAMBundleRegistry> bundleRegistry) = 0; virtual void setBundleRegistry(std::unique_ptr<RAMBundleRegistry> bundleRegistry) = 0;
/**
* Register a file path for an additional "RAM" bundle
*/
virtual void registerBundle(uint32_t bundleId, const std::string& bundlePath) = 0;
/** /**
* Executes BatchedBridge.callFunctionReturnFlushedQueue with the module ID, * Executes BatchedBridge.callFunctionReturnFlushedQueue with the module ID,
* method ID and optional additional arguments in JS. The executor is responsible * method ID and optional additional arguments in JS. The executor is responsible

Просмотреть файл

@ -9,10 +9,9 @@
namespace facebook { namespace facebook {
namespace react { namespace react {
std::function<std::unique_ptr<JSModulesUnbundle>(uint32_t)> JSIndexedRAMBundle::buildFactory(const std::string& baseDirectoryPath) { std::function<std::unique_ptr<JSModulesUnbundle>(std::string)> JSIndexedRAMBundle::buildFactory() {
return [baseDirectoryPath](uint32_t index){ return [](const std::string& bundlePath){
std::string bundlePathById = baseDirectoryPath + toString(index) + ".jsbundle"; return folly::make_unique<JSIndexedRAMBundle>(bundlePath.c_str());
return folly::make_unique<JSIndexedRAMBundle>(bundlePathById.c_str());
}; };
} }

Просмотреть файл

@ -17,7 +17,7 @@ namespace react {
class RN_EXPORT JSIndexedRAMBundle : public JSModulesUnbundle { class RN_EXPORT JSIndexedRAMBundle : public JSModulesUnbundle {
public: public:
static std::function<std::unique_ptr<JSModulesUnbundle>(uint32_t)> buildFactory(const std::string& baseDirectoryPath); static std::function<std::unique_ptr<JSModulesUnbundle>(std::string)> buildFactory();
// Throws std::runtime_error on failure. // Throws std::runtime_error on failure.
JSIndexedRAMBundle(const char *sourceURL); JSIndexedRAMBundle(const char *sourceURL);

Просмотреть файл

@ -171,6 +171,12 @@ void NativeToJsBridge::invokeCallback(double callbackId, folly::dynamic&& argume
}); });
} }
void NativeToJsBridge::registerBundle(uint32_t bundleId, const std::string& bundlePath) {
runOnExecutorQueue([bundleId, bundlePath] (JSExecutor* executor) {
executor->registerBundle(bundleId, bundlePath);
});
}
void NativeToJsBridge::setGlobalVariable(std::string propName, void NativeToJsBridge::setGlobalVariable(std::string propName,
std::unique_ptr<const JSBigString> jsonValue) { std::unique_ptr<const JSBigString> jsonValue) {
runOnExecutorQueue([propName=std::move(propName), jsonValue=folly::makeMoveWrapper(std::move(jsonValue))] runOnExecutorQueue([propName=std::move(propName), jsonValue=folly::makeMoveWrapper(std::move(jsonValue))]

Просмотреть файл

@ -98,6 +98,7 @@ public:
std::unique_ptr<const JSBigString> startupCode, std::unique_ptr<const JSBigString> startupCode,
std::string sourceURL); std::string sourceURL);
void registerBundle(uint32_t bundleId, const std::string& bundlePath);
void setGlobalVariable(std::string propName, std::unique_ptr<const JSBigString> jsonValue); void setGlobalVariable(std::string propName, std::unique_ptr<const JSBigString> jsonValue);
void* getJavaScriptContext(); void* getJavaScriptContext();

Просмотреть файл

@ -16,21 +16,30 @@ std::unique_ptr<RAMBundleRegistry> RAMBundleRegistry::singleBundleRegistry(std::
return std::unique_ptr<RAMBundleRegistry>(registry); return std::unique_ptr<RAMBundleRegistry>(registry);
} }
std::unique_ptr<RAMBundleRegistry> RAMBundleRegistry::multipleBundlesRegistry(std::unique_ptr<JSModulesUnbundle> mainBundle, std::function<std::unique_ptr<JSModulesUnbundle>(uint32_t)> factory) { std::unique_ptr<RAMBundleRegistry> RAMBundleRegistry::multipleBundlesRegistry(std::unique_ptr<JSModulesUnbundle> mainBundle, std::function<std::unique_ptr<JSModulesUnbundle>(std::string)> factory) {
RAMBundleRegistry *registry = new RAMBundleRegistry(std::move(mainBundle), std::move(factory)); RAMBundleRegistry *registry = new RAMBundleRegistry(std::move(mainBundle), std::move(factory));
return std::unique_ptr<RAMBundleRegistry>(registry); return std::unique_ptr<RAMBundleRegistry>(registry);
} }
RAMBundleRegistry::RAMBundleRegistry(std::unique_ptr<JSModulesUnbundle> mainBundle, std::function<std::unique_ptr<JSModulesUnbundle>(uint32_t)> factory): m_factory(factory) { RAMBundleRegistry::RAMBundleRegistry(std::unique_ptr<JSModulesUnbundle> mainBundle, std::function<std::unique_ptr<JSModulesUnbundle>(std::string)> factory): m_factory(factory) {
m_bundles.emplace(MAIN_BUNDLE_ID, std::move(mainBundle)); m_bundles.emplace(MAIN_BUNDLE_ID, std::move(mainBundle));
} }
void RAMBundleRegistry::registerBundle(uint32_t bundleId, std::string bundlePath) {
m_bundlePaths.emplace(bundleId, bundlePath);
}
JSModulesUnbundle::Module RAMBundleRegistry::getModule(uint32_t bundleId, uint32_t moduleId) { JSModulesUnbundle::Module RAMBundleRegistry::getModule(uint32_t bundleId, uint32_t moduleId) {
if (m_bundles.find(bundleId) == m_bundles.end()) { if (m_bundles.find(bundleId) == m_bundles.end()) {
if (!m_factory) { if (!m_factory) {
throw std::runtime_error("You need to register factory function in order to support multiple RAM bundles."); throw std::runtime_error("You need to register factory function in order to support multiple RAM bundles.");
} }
m_bundles.emplace(bundleId, m_factory(bundleId));
auto bundlePath = m_bundlePaths.find(bundleId);
if (bundlePath == m_bundlePaths.end()) {
throw std::runtime_error("In order to fetch RAM bundle from the registry, its file path needs to be registered first.");
}
m_bundles.emplace(bundleId, m_factory(bundlePath->second));
} }
return getBundle(bundleId)->getModule(moduleId); return getBundle(bundleId)->getModule(moduleId);

Просмотреть файл

@ -21,21 +21,24 @@ namespace react {
class RN_EXPORT RAMBundleRegistry : noncopyable { class RN_EXPORT RAMBundleRegistry : noncopyable {
public: public:
using unique_ram_bundle = std::unique_ptr<JSModulesUnbundle>; using unique_ram_bundle = std::unique_ptr<JSModulesUnbundle>;
using bundle_path = std::string;
constexpr static uint32_t MAIN_BUNDLE_ID = 0; constexpr static uint32_t MAIN_BUNDLE_ID = 0;
static std::unique_ptr<RAMBundleRegistry> singleBundleRegistry(unique_ram_bundle mainBundle); static std::unique_ptr<RAMBundleRegistry> singleBundleRegistry(unique_ram_bundle mainBundle);
static std::unique_ptr<RAMBundleRegistry> multipleBundlesRegistry(unique_ram_bundle mainBundle, std::function<unique_ram_bundle(uint32_t)> factory); static std::unique_ptr<RAMBundleRegistry> multipleBundlesRegistry(unique_ram_bundle mainBundle, std::function<unique_ram_bundle(bundle_path)> factory);
RAMBundleRegistry(RAMBundleRegistry&&) = default; RAMBundleRegistry(RAMBundleRegistry&&) = default;
RAMBundleRegistry& operator=(RAMBundleRegistry&&) = default; RAMBundleRegistry& operator=(RAMBundleRegistry&&) = default;
void registerBundle(uint32_t bundleId, bundle_path bundlePath);
JSModulesUnbundle::Module getModule(uint32_t bundleId, uint32_t moduleId); JSModulesUnbundle::Module getModule(uint32_t bundleId, uint32_t moduleId);
virtual ~RAMBundleRegistry() {}; virtual ~RAMBundleRegistry() {};
private: private:
explicit RAMBundleRegistry(unique_ram_bundle mainBundle, std::function<unique_ram_bundle(uint32_t)> factory = {}); explicit RAMBundleRegistry(unique_ram_bundle mainBundle, std::function<unique_ram_bundle(bundle_path)> factory = {});
JSModulesUnbundle *getBundle(uint32_t bundleId) const; JSModulesUnbundle *getBundle(uint32_t bundleId) const;
std::function<unique_ram_bundle(uint32_t)> m_factory; std::function<unique_ram_bundle(bundle_path)> m_factory;
std::unordered_map<uint32_t, bundle_path> m_bundlePaths;
std::unordered_map<uint32_t, unique_ram_bundle> m_bundles; std::unordered_map<uint32_t, unique_ram_bundle> m_bundles;
}; };