mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Implement method dispatch using TurboModuleSchema
Summary: This is the final diff in the JS TurboModule codegen stack for Android. It implements method dispatch using the TurboModuleSchema object. Changelog: [Internal] Reviewed By: fkgozali Differential Revision: D22837486 fbshipit-source-id: f91b03f064941457d4b8c5e37e011468559dee71
This commit is contained in:
committed by
Facebook GitHub Bot
parent
165dcccc58
commit
610dcf488b
+10
-1
@@ -14,6 +14,7 @@
|
||||
#include <ReactCommon/TurboCxxModule.h>
|
||||
#include <ReactCommon/TurboModuleBinding.h>
|
||||
#include <ReactCommon/TurboModulePerfLogger.h>
|
||||
#include <ReactCommon/TurboModuleSchema.h>
|
||||
#include <react/jni/JMessageQueueThread.h>
|
||||
|
||||
#include "TurboModuleManager.h"
|
||||
@@ -76,7 +77,8 @@ void TurboModuleManager::installJSIBindings() {
|
||||
jsCallInvoker_ = std::weak_ptr<CallInvoker>(jsCallInvoker_),
|
||||
nativeCallInvoker_ = std::weak_ptr<CallInvoker>(nativeCallInvoker_),
|
||||
delegate_ = jni::make_weak(delegate_),
|
||||
javaPart_ = jni::make_weak(javaPart_)](
|
||||
javaPart_ = jni::make_weak(javaPart_),
|
||||
runtime_ = runtime_](
|
||||
const std::string &name,
|
||||
const jsi::Value *schema) -> std::shared_ptr<TurboModule> {
|
||||
auto turboModuleCache = turboModuleCache_.lock();
|
||||
@@ -139,6 +141,13 @@ void TurboModuleManager::installJSIBindings() {
|
||||
.jsInvoker = jsCallInvoker,
|
||||
.nativeInvoker = nativeCallInvoker};
|
||||
|
||||
if (schema->isObject() && !schema->isNull()) {
|
||||
auto turboModule = std::make_shared<JavaTurboModule>(
|
||||
params, TurboModuleSchema::parse(*runtime_, name, *schema));
|
||||
TurboModulePerfLogger::moduleJSRequireEndingEnd(moduleName);
|
||||
return turboModule;
|
||||
}
|
||||
|
||||
auto turboModule = delegate->cthis()->getTurboModule(name, params);
|
||||
turboModuleCache->insert({name, turboModule});
|
||||
TurboModulePerfLogger::moduleJSRequireEndingEnd(moduleName);
|
||||
|
||||
@@ -56,6 +56,68 @@ void JavaTurboModule::enablePromiseAsyncDispatch(bool enable) {
|
||||
isPromiseAsyncDispatchEnabled_ = enable;
|
||||
}
|
||||
|
||||
JavaTurboModule::JavaTurboModule(
|
||||
const InitParams ¶ms,
|
||||
TurboModuleSchema &&schema)
|
||||
: TurboModule(params.moduleName, params.jsInvoker),
|
||||
instance_(jni::make_global(params.instance)),
|
||||
nativeInvoker_(params.nativeInvoker),
|
||||
turboModuleSchema_(std::move(schema)) {}
|
||||
|
||||
jsi::Value JavaTurboModule::get(
|
||||
jsi::Runtime &runtime,
|
||||
const jsi::PropNameID &propName) {
|
||||
if (!turboModuleSchema_) {
|
||||
return TurboModule::get(runtime, propName);
|
||||
}
|
||||
|
||||
std::string methodName = propName.utf8(runtime);
|
||||
if (!turboModuleSchema_->hasMethod(methodName)) {
|
||||
return jsi::Value::undefined();
|
||||
}
|
||||
|
||||
using MethodImplStatus = TurboModuleSchema::Method::ImplStatus;
|
||||
TurboModuleSchema::Method &method = turboModuleSchema_->getMethod(methodName);
|
||||
|
||||
if (method.isOptional) {
|
||||
if (method.implStatus == MethodImplStatus::Unknown) {
|
||||
auto instance = instance_.get();
|
||||
JNIEnv *env = jni::Environment::current();
|
||||
jclass cls = env->GetObjectClass(instance);
|
||||
jmethodID methodID = env->GetMethodID(
|
||||
cls, methodName.c_str(), method.jniSignature.c_str());
|
||||
|
||||
// If the method signature doesn't match, show a redbox here instead of
|
||||
// crashing later.
|
||||
FACEBOOK_JNI_THROW_PENDING_EXCEPTION();
|
||||
method.implStatus = methodID != nullptr ? MethodImplStatus::Implemented
|
||||
: MethodImplStatus::Unimplemented;
|
||||
}
|
||||
|
||||
if (method.implStatus == MethodImplStatus::Unimplemented) {
|
||||
return jsi::Value::undefined();
|
||||
}
|
||||
}
|
||||
|
||||
return jsi::Function::createFromHostFunction(
|
||||
runtime,
|
||||
propName,
|
||||
method.jsParamCount,
|
||||
[this, method](
|
||||
facebook::jsi::Runtime &runtime,
|
||||
const facebook::jsi::Value &thisVal,
|
||||
const facebook::jsi::Value *args,
|
||||
size_t count) {
|
||||
return invokeJavaMethod(
|
||||
runtime,
|
||||
method.jsReturnType,
|
||||
method.name,
|
||||
method.jniSignature,
|
||||
args,
|
||||
count);
|
||||
});
|
||||
}
|
||||
|
||||
namespace {
|
||||
jni::local_ref<JCxxCallbackImpl::JavaPart> createJavaCallbackFromJSIFunction(
|
||||
jsi::Function &&function,
|
||||
|
||||
@@ -13,9 +13,12 @@
|
||||
#include <ReactCommon/TurboModule.h>
|
||||
#include <ReactCommon/TurboModuleUtils.h>
|
||||
#include <fbjni/fbjni.h>
|
||||
#include <folly/Optional.h>
|
||||
#include <jsi/jsi.h>
|
||||
#include <react/jni/JCallback.h>
|
||||
|
||||
#include "TurboModuleSchema.h"
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
@@ -41,7 +44,9 @@ class JSI_EXPORT JavaTurboModule : public TurboModule {
|
||||
};
|
||||
|
||||
JavaTurboModule(const InitParams ¶ms);
|
||||
JavaTurboModule(const InitParams ¶ms, TurboModuleSchema &&schema);
|
||||
virtual ~JavaTurboModule();
|
||||
|
||||
jsi::Value invokeJavaMethod(
|
||||
jsi::Runtime &runtime,
|
||||
TurboModuleMethodValueKind valueKind,
|
||||
@@ -51,10 +56,13 @@ class JSI_EXPORT JavaTurboModule : public TurboModule {
|
||||
size_t argCount);
|
||||
|
||||
static void enablePromiseAsyncDispatch(bool enable);
|
||||
jsi::Value get(jsi::Runtime &runtime, const jsi::PropNameID &propName)
|
||||
override;
|
||||
|
||||
private:
|
||||
jni::global_ref<JTurboModule> instance_;
|
||||
std::shared_ptr<CallInvoker> nativeInvoker_;
|
||||
folly::Optional<TurboModuleSchema> turboModuleSchema_;
|
||||
|
||||
/**
|
||||
* Experiments
|
||||
|
||||
+8
-3
@@ -44,6 +44,7 @@ std::ostream &operator<<(std::ostream &os, const TurboModuleSchema &schema) {
|
||||
<< std::endl;
|
||||
os << " .isOptional = " << (method.isOptional ? "true" : "false")
|
||||
<< std::endl;
|
||||
os << " .jsParamCount = " << method.jsParamCount << "," << std::endl;
|
||||
os << " }," << std::endl;
|
||||
}
|
||||
|
||||
@@ -96,9 +97,9 @@ bool TurboModuleSchema::hasMethod(const std::string &methodName) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
const TurboModuleSchema::Method &TurboModuleSchema::getMethod(
|
||||
const std::string &methodName) const {
|
||||
for (const Method &method : methods_) {
|
||||
TurboModuleSchema::Method &TurboModuleSchema::getMethod(
|
||||
const std::string &methodName) {
|
||||
for (Method &method : methods_) {
|
||||
if (method.name == methodName) {
|
||||
return method;
|
||||
}
|
||||
@@ -377,6 +378,8 @@ TurboModuleSchema::Method parseMethod(
|
||||
.name = methodName,
|
||||
.jniSignature = "()Ljava/util/Map;",
|
||||
.isOptional = !isMethodRequired,
|
||||
.jsParamCount = 0,
|
||||
.implStatus = TurboModuleSchema::Method::ImplStatus::Unknown,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -460,6 +463,8 @@ TurboModuleSchema::Method parseMethod(
|
||||
.name = methodName,
|
||||
.jniSignature = jniSignature,
|
||||
.isOptional = !isMethodRequired,
|
||||
.jsParamCount = numFunctionTypeAnnotationParams,
|
||||
.implStatus = TurboModuleSchema::Method::ImplStatus::Unknown,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
+16
-2
@@ -18,10 +18,24 @@ namespace react {
|
||||
class TurboModuleSchema {
|
||||
public:
|
||||
struct Method {
|
||||
/**
|
||||
* Optional methods might not be implemented on the Java NativeModule class.
|
||||
* - Unknown: We must check if the method exists using JNI
|
||||
* - Implemented: Using JNI, we verified that the method exists
|
||||
* - Unimplemented: Using JNI, we verified that the method doesn't exist
|
||||
*/
|
||||
enum class ImplStatus {
|
||||
Unknown,
|
||||
Implemented,
|
||||
Unimplemented,
|
||||
};
|
||||
|
||||
const TurboModuleMethodValueKind jsReturnType;
|
||||
const std::string name;
|
||||
const std::string jniSignature;
|
||||
const bool isOptional;
|
||||
const size_t jsParamCount;
|
||||
ImplStatus implStatus;
|
||||
};
|
||||
|
||||
class ParseException : public jsi::JSIException {
|
||||
@@ -31,7 +45,7 @@ class TurboModuleSchema {
|
||||
|
||||
private:
|
||||
const std::string moduleName_;
|
||||
const std::vector<Method> methods_;
|
||||
std::vector<Method> methods_;
|
||||
|
||||
TurboModuleSchema(
|
||||
const std::string &moduleName,
|
||||
@@ -40,7 +54,7 @@ class TurboModuleSchema {
|
||||
public:
|
||||
TurboModuleSchema() = delete;
|
||||
bool hasMethod(const std::string &methodName) const;
|
||||
const Method &getMethod(const std::string &methodName) const;
|
||||
Method &getMethod(const std::string &methodName);
|
||||
|
||||
static TurboModuleSchema parse(
|
||||
jsi::Runtime &runtime,
|
||||
|
||||
Reference in New Issue
Block a user