mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-01-12 22:50:10 +08:00
Introduce TurboModuleManagerDelegate
Summary:
`TurboModuleManagerDelegate` is an abstract base class with the following API:
```
public TurboModule getModule(String name, ReactApplicationContext reactApplicationContext);
public CxxModuleWrapper getLegacyCxxModule(String name, ReactApplicationContext reactApplicationContext);
```
```
std::shared_ptr<TurboModule> getTurboModule(std::string name, jni::global_ref<JTurboModule> turboModule, std::shared_ptr<JSCallInvoker> jsInvoker) override;
std::shared_ptr<TurboModule> getTurboModule(std::string name, std::shared_ptr<JSCallInvoker> jsInvoker) override;
```
On the C++ side, when asked to provide a TurboModule with name `name`:
1. First, is this a CxxModule? If so:
1. Create the CxxModule and return
2. Otherwise:
1. Somehow get a Java instance of the TurboModule
2. If this Java object represents a CxxModule, like `FbReactLibSodiumModule`:
1. Grab the C++ part of this object, and wrap it in a `TurboCxxModule.cpp` and return.
3. Otherwise:
1. Wrap the Java object in a C++ HostObject and return.
This pseudocode demonstrates how we'd use `TurboModuleManagerDelegate` to implement `__turboModuleProxy`.
```
__turboModuleProxy(name, jsCallInvoker):
let cxxModule = TurboModuleManagerDelegate::getTurboModule(name, jsCallInvoker)
if (!cxxModule) {
return cxxModule;
}
// JNI Call that forwards to TurboModuleManagerDelegate.getLegacyCxxModule
let javaCxxModule : CxxModuleWrapper = TurboModuleManager.getLegacyCxxModule(name)
if (!javaCxxModule) {
return std::shared_ptr<react::TurboCxxModule>(javaCxxModule.getModule())
}
// JNI Call that forwards to TurboModuleManagerDelegate.getModule
let javaModule : TurboModule = TurboModuleManager.getModule(name)
if (!javaCxxModule) {
return TurboModuleManagerDelegate::getTurboModule(name, javaModule, jsCallInvoker)
}
return null
```
Reviewed By: mdvacca
Differential Revision: D15111335
fbshipit-source-id: c7b0aeda0e4565e3a2729e7f9604775782b6f893
This commit is contained in:
committed by
Facebook Github Bot
parent
ef4955fefe
commit
cba205b82c
@@ -27,41 +27,37 @@ public class TurboModuleManager implements JSIModule {
|
||||
}
|
||||
|
||||
private final ReactApplicationContext mReactApplicationContext;
|
||||
private final TurboModuleManagerDelegate mTurbomoduleManagerDelegate;
|
||||
|
||||
@DoNotStrip
|
||||
@SuppressWarnings("unused")
|
||||
private final HybridData mHybridData;
|
||||
private final ModuleProvider mModuleProvider;
|
||||
|
||||
public TurboModuleManager(
|
||||
ReactApplicationContext reactApplicationContext, JavaScriptContextHolder jsContext, ModuleProvider moduleProvider) {
|
||||
ReactApplicationContext reactApplicationContext, JavaScriptContextHolder jsContext, TurboModuleManagerDelegate tmmDelegate) {
|
||||
mReactApplicationContext = reactApplicationContext;
|
||||
JSCallInvokerHolderImpl instanceHolder =
|
||||
(JSCallInvokerHolderImpl) mReactApplicationContext
|
||||
.getCatalystInstance()
|
||||
.getJSCallInvokerHolder();
|
||||
mHybridData = initHybrid(jsContext.get(), instanceHolder);
|
||||
mModuleProvider = moduleProvider;
|
||||
mHybridData = initHybrid(jsContext.get(), instanceHolder, tmmDelegate);
|
||||
mTurbomoduleManagerDelegate = tmmDelegate;
|
||||
}
|
||||
|
||||
@DoNotStrip
|
||||
@SuppressWarnings("unused")
|
||||
protected TurboModule getJavaModule(String name) {
|
||||
return mModuleProvider.getModule(name, mReactApplicationContext);
|
||||
private TurboModule getJavaModule(String name) {
|
||||
return mTurbomoduleManagerDelegate.getModule(name);
|
||||
}
|
||||
|
||||
protected native HybridData initHybrid(long jsContext, JSCallInvokerHolderImpl jsQueue);
|
||||
private native HybridData initHybrid(long jsContext, JSCallInvokerHolderImpl jsQueue, TurboModuleManagerDelegate tmmDelegate);
|
||||
|
||||
protected native void installJSIBindings();
|
||||
private native void installJSIBindings();
|
||||
|
||||
public void installBindings() {
|
||||
installJSIBindings();
|
||||
}
|
||||
|
||||
protected ReactApplicationContext getReactApplicationContext() {
|
||||
return mReactApplicationContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {}
|
||||
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.facebook.react.turbomodule.core;
|
||||
|
||||
import com.facebook.jni.HybridData;
|
||||
import com.facebook.react.bridge.CxxModuleWrapper;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.turbomodule.core.interfaces.TurboModule;
|
||||
import com.facebook.soloader.SoLoader;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public abstract class TurboModuleManagerDelegate {
|
||||
static {
|
||||
SoLoader.loadLibrary("turbomodulejsijni");
|
||||
}
|
||||
|
||||
private final HybridData mHybridData;
|
||||
private final ReactApplicationContext mReactApplicationContext;
|
||||
|
||||
protected abstract HybridData initHybrid();
|
||||
|
||||
protected TurboModuleManagerDelegate(ReactApplicationContext rac) {
|
||||
mHybridData = initHybrid();
|
||||
mReactApplicationContext = rac;
|
||||
}
|
||||
|
||||
protected ReactApplicationContext getReactApplicationContext() {
|
||||
return mReactApplicationContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and return a TurboModule Java object with name `moduleName`.
|
||||
* If `moduleName` isn't a TurboModule, return null.
|
||||
*/
|
||||
@Nullable
|
||||
public abstract TurboModule getModule(String moduleName);
|
||||
|
||||
/**
|
||||
* Create an return a CxxModuleWrapper NativeModule with name `moduleName`.
|
||||
* If `moduleName` isn't a CxxModule, return null.
|
||||
*/
|
||||
@Nullable
|
||||
public abstract CxxModuleWrapper getLegacyCxxModule(String moduleName);
|
||||
}
|
||||
@@ -2,24 +2,14 @@ load("@fbsource//tools/build_defs/oss:rn_defs.bzl", "ANDROID", "FBJNI_TARGET", "
|
||||
|
||||
rn_xplat_cxx_library(
|
||||
name = "jni",
|
||||
platforms = ANDROID,
|
||||
preferred_linkage = "static",
|
||||
visibility = [
|
||||
"PUBLIC",
|
||||
],
|
||||
exported_deps = [
|
||||
":turbomodulemanager",
|
||||
],
|
||||
)
|
||||
|
||||
rn_xplat_cxx_library(
|
||||
name = "turbomodulemanager",
|
||||
srcs = [
|
||||
"OnLoad.cpp",
|
||||
"TurboModuleManager.cpp",
|
||||
],
|
||||
header_namespace = "",
|
||||
exported_headers = {
|
||||
"jsireact/TurboModuleManager.h": "TurboModuleManager.h",
|
||||
"jsireact/TurboModuleManagerDelegate.h": "TurboModuleManagerDelegate.h",
|
||||
},
|
||||
compiler_flags = [
|
||||
"-fexceptions",
|
||||
@@ -28,23 +18,20 @@ rn_xplat_cxx_library(
|
||||
"-Wall",
|
||||
],
|
||||
platforms = ANDROID,
|
||||
preferred_linkage = "static",
|
||||
preprocessor_flags = [
|
||||
"-DLOG_TAG=\"ReactNative\"",
|
||||
"-DWITH_FBSYSTRACE=1",
|
||||
],
|
||||
soname = "libturbomodulejsijni.$(ext)",
|
||||
visibility = [
|
||||
"PUBLIC",
|
||||
],
|
||||
deps = [
|
||||
react_native_target("jni/react/jni:jni"),
|
||||
"fbsource//xplat/jsi:JSIDynamic",
|
||||
"fbsource//xplat/jsi:jsi",
|
||||
":jscallinvokerholder",
|
||||
],
|
||||
exported_deps = [
|
||||
"fbsource//xplat/jsi:jsi",
|
||||
react_native_xplat_target("cxxreact:bridge"),
|
||||
":jscallinvokerholder",
|
||||
react_native_xplat_target("turbomodule/core:core"),
|
||||
],
|
||||
)
|
||||
@@ -76,9 +63,6 @@ rn_xplat_cxx_library(
|
||||
visibility = [
|
||||
"PUBLIC",
|
||||
],
|
||||
deps = [
|
||||
react_native_xplat_target("cxxreact:bridge"),
|
||||
],
|
||||
exported_deps = [
|
||||
react_native_xplat_target("jscallinvoker:jscallinvoker"),
|
||||
],
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||
|
||||
#include <fb/fbjni.h>
|
||||
#include <fb/xplat_init.h>
|
||||
|
||||
#include "TurboModuleManager.h"
|
||||
|
||||
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {
|
||||
return facebook::xplat::initialize(vm, [] {
|
||||
// TODO: dvacca ramanpreet unify this with the way "ComponentDescriptorFactory" is defined in Fabric
|
||||
facebook::react::TurboModuleManager::registerNatives();
|
||||
});
|
||||
}
|
||||
@@ -11,7 +11,6 @@
|
||||
#include <fb/fbjni.h>
|
||||
#include <jsi/jsi.h>
|
||||
|
||||
#include <cxxreact/Instance.h>
|
||||
#include <jsireact/TurboModuleBinding.h>
|
||||
|
||||
#include <react/jni/JMessageQueueThread.h>
|
||||
@@ -21,26 +20,27 @@
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
static JTurboModuleProviderFunctionType moduleProvider_ = nullptr;
|
||||
|
||||
TurboModuleManager::TurboModuleManager(
|
||||
jni::alias_ref<TurboModuleManager::javaobject> jThis,
|
||||
jsi::Runtime* rt,
|
||||
std::shared_ptr<JSCallInvoker> jsCallInvoker
|
||||
std::shared_ptr<JSCallInvoker> jsCallInvoker,
|
||||
jni::alias_ref<TurboModuleManagerDelegate::javaobject> tmmDelegate
|
||||
):
|
||||
javaPart_(jni::make_global(jThis)),
|
||||
runtime_(rt),
|
||||
jsCallInvoker_(jsCallInvoker)
|
||||
jsCallInvoker_(jsCallInvoker),
|
||||
turboModuleManagerDelegate_(jni::make_global(tmmDelegate))
|
||||
{}
|
||||
|
||||
jni::local_ref<TurboModuleManager::jhybriddata> TurboModuleManager::initHybrid(
|
||||
jni::alias_ref<jhybridobject> jThis,
|
||||
jlong jsContext,
|
||||
jni::alias_ref<JSCallInvokerHolder::javaobject> jsCallInvokerHolder
|
||||
jni::alias_ref<JSCallInvokerHolder::javaobject> jsCallInvokerHolder,
|
||||
jni::alias_ref<TurboModuleManagerDelegate::javaobject> tmmDelegate
|
||||
) {
|
||||
auto jsCallInvoker = jsCallInvokerHolder->cthis()->getJSCallInvoker();
|
||||
|
||||
return makeCxxInstance(jThis, (jsi::Runtime *) jsContext, jsCallInvoker);
|
||||
return makeCxxInstance(jThis, (jsi::Runtime *) jsContext, jsCallInvoker, tmmDelegate);
|
||||
}
|
||||
|
||||
void TurboModuleManager::registerNatives() {
|
||||
@@ -57,18 +57,17 @@ void TurboModuleManager::installJSIBindings() {
|
||||
TurboModuleBinding::install(*runtime_, std::make_shared<TurboModuleBinding>(
|
||||
[this](const std::string &name) {
|
||||
const auto moduleInstance = getJavaModule(name);
|
||||
return moduleProvider_(name, moduleInstance, jsCallInvoker_);
|
||||
return turboModuleManagerDelegate_->cthis()->getTurboModule(name, moduleInstance, jsCallInvoker_);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
jni::global_ref<JTurboModule> TurboModuleManager::getJavaModule(std::string name) {
|
||||
static auto method = javaClassStatic()->getMethod<jni::alias_ref<JTurboModule>(const std::string&)>("getJavaModule");
|
||||
return make_global(method(javaPart_.get(), name));
|
||||
}
|
||||
|
||||
void TurboModuleManager::setModuleProvider(JTurboModuleProviderFunctionType fn) {
|
||||
moduleProvider_ = fn;
|
||||
auto module = jni::make_global(method(javaPart_.get(), name));
|
||||
|
||||
return module;
|
||||
}
|
||||
|
||||
} // namespace react
|
||||
|
||||
@@ -14,35 +14,35 @@
|
||||
#include <jsireact/JavaTurboModule.h>
|
||||
#include <react/jni/JMessageQueueThread.h>
|
||||
#include <jsireact/JSCallInvokerHolder.h>
|
||||
#include <jsireact/TurboModuleManagerDelegate.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
using JTurboModuleProviderFunctionType = std::function<std::shared_ptr<TurboModule>(
|
||||
const std::string &name, jni::global_ref<JTurboModule> moduleInstance, std::shared_ptr<JSCallInvoker> jsInvoker)>;
|
||||
|
||||
class TurboModuleManager : public jni::HybridClass<TurboModuleManager> {
|
||||
public:
|
||||
static auto constexpr kJavaDescriptor = "Lcom/facebook/react/turbomodule/core/TurboModuleManager;";
|
||||
static jni::local_ref<jhybriddata> initHybrid(
|
||||
jni::alias_ref<jhybridobject> jThis,
|
||||
jlong jsContext,
|
||||
jni::alias_ref<JSCallInvokerHolder::javaobject> jsCallInvokerHolder
|
||||
jni::alias_ref<JSCallInvokerHolder::javaobject> jsCallInvokerHolder,
|
||||
jni::alias_ref<TurboModuleManagerDelegate::javaobject> tmmDelegate
|
||||
);
|
||||
static void registerNatives();
|
||||
static void setModuleProvider(JTurboModuleProviderFunctionType moduleProvider);
|
||||
private:
|
||||
friend HybridBase;
|
||||
jni::global_ref<TurboModuleManager::javaobject> javaPart_;
|
||||
jsi::Runtime* runtime_;
|
||||
std::shared_ptr<JSCallInvoker> jsCallInvoker_;
|
||||
jni::global_ref<TurboModuleManagerDelegate::javaobject> turboModuleManagerDelegate_;
|
||||
|
||||
jni::global_ref<JTurboModule> getJavaModule(std::string name);
|
||||
void installJSIBindings();
|
||||
explicit TurboModuleManager(
|
||||
jni::alias_ref<TurboModuleManager::jhybridobject> jThis,
|
||||
jsi::Runtime *rt,
|
||||
std::shared_ptr<JSCallInvoker> jsCallInvoker
|
||||
std::shared_ptr<JSCallInvoker> jsCallInvoker,
|
||||
jni::alias_ref<TurboModuleManagerDelegate::javaobject> tmmDelegate
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <fb/fbjni.h>
|
||||
#include <jsireact/JavaTurboModule.h>
|
||||
#include <jsireact/JSCallInvoker.h>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
class TurboModuleManagerDelegate : public jni::HybridClass<TurboModuleManagerDelegate> {
|
||||
public:
|
||||
static auto constexpr kJavaDescriptor = "Lcom/facebook/react/turbomodule/core/TurboModuleManagerDelegate;";
|
||||
|
||||
virtual std::shared_ptr<TurboModule> getTurboModule(std::string name, jni::global_ref<JTurboModule> turboModule, std::shared_ptr<JSCallInvoker> jsInvoker) = 0;
|
||||
virtual std::shared_ptr<TurboModule> getTurboModule(std::string name, std::shared_ptr<JSCallInvoker> jsInvoker) = 0;
|
||||
|
||||
private:
|
||||
friend HybridBase;
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
@@ -1,4 +1,4 @@
|
||||
load("//tools/build_defs/oss:rn_defs.bzl", "ANDROID", "APPLE", "FBJNI_TARGET", "react_native_xplat_target", "rn_xplat_cxx_library", "subdir_glob")
|
||||
load("//tools/build_defs/oss:rn_defs.bzl", "ANDROID", "APPLE", "react_native_xplat_target", "rn_xplat_cxx_library", "subdir_glob")
|
||||
|
||||
rn_xplat_cxx_library(
|
||||
name = "jscallinvoker",
|
||||
@@ -18,9 +18,6 @@ rn_xplat_cxx_library(
|
||||
"-std=c++14",
|
||||
"-Wall",
|
||||
],
|
||||
fbandroid_deps = [
|
||||
FBJNI_TARGET,
|
||||
],
|
||||
platforms = (ANDROID, APPLE),
|
||||
preferred_linkage = "static",
|
||||
preprocessor_flags = [
|
||||
|
||||
Reference in New Issue
Block a user