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 committed by Facebook Github Bot
parent 820cfa1f3b
commit cff0d8e0e5
16 changed files with 62 additions and 13 deletions

View File

@ -1152,7 +1152,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithBundleURL:(__unused NSURL *)bundleUR
? [[self.delegate jsSegmentsDirectory].path stringByAppendingString:@"/"]
: 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));
self->_reactInstance->loadRAMBundle(std::move(registry), std::move(scriptStr),
sourceUrlStr.UTF8String, !async);

View File

@ -95,6 +95,10 @@ public:
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())

View File

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

View File

@ -90,6 +90,12 @@ void ProxyExecutor::setBundleRegistry(std::unique_ptr<RAMBundleRegistry>) {
"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) {
auto call = folly::dynamic::array(moduleId, methodId, std::move(arguments));

View File

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

View File

@ -156,6 +156,10 @@ void Instance::callJSCallback(uint64_t callbackId, folly::dynamic &&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 {
return *moduleRegistry_;
}

View File

@ -59,6 +59,9 @@ public:
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.
template <typename T>
Value callFunctionSync(const std::string &module, const std::string &method,

View File

@ -458,6 +458,12 @@ namespace facebook {
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) {
SystraceSection s("JSCExecutor::bindBridge");
std::call_once(m_bindFlag, [this] {

View File

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

View File

@ -53,6 +53,11 @@ public:
*/
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,
* method ID and optional additional arguments in JS. The executor is responsible

View File

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

View File

@ -17,7 +17,7 @@ namespace react {
class RN_EXPORT JSIndexedRAMBundle : public JSModulesUnbundle {
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.
JSIndexedRAMBundle(const char *sourceURL);

View File

@ -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,
std::unique_ptr<const JSBigString> jsonValue) {
runOnExecutorQueue([propName=std::move(propName), jsonValue=folly::makeMoveWrapper(std::move(jsonValue))]

View File

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

View File

@ -16,21 +16,30 @@ std::unique_ptr<RAMBundleRegistry> RAMBundleRegistry::singleBundleRegistry(std::
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));
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));
}
void RAMBundleRegistry::registerBundle(uint32_t bundleId, std::string bundlePath) {
m_bundlePaths.emplace(bundleId, bundlePath);
}
JSModulesUnbundle::Module RAMBundleRegistry::getModule(uint32_t bundleId, uint32_t moduleId) {
if (m_bundles.find(bundleId) == m_bundles.end()) {
if (!m_factory) {
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);

View File

@ -21,21 +21,24 @@ namespace react {
class RN_EXPORT RAMBundleRegistry : noncopyable {
public:
using unique_ram_bundle = std::unique_ptr<JSModulesUnbundle>;
using bundle_path = std::string;
constexpr static uint32_t MAIN_BUNDLE_ID = 0;
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& operator=(RAMBundleRegistry&&) = default;
void registerBundle(uint32_t bundleId, bundle_path bundlePath);
JSModulesUnbundle::Module getModule(uint32_t bundleId, uint32_t moduleId);
virtual ~RAMBundleRegistry() {};
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;
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;
};