Add codegen for C++ TurboModule automatic type conversions

Summary:
This adds the *option* for C++ TurboModules to use a `*CxxSpec<T>` base class that extends the existing (and unchanged) corresponding `*CxxSpecJSI` base class with code-generated methods that use `bridging::calFromJs` to safely convert types between JSI and C++. If a type conversion cannot be made, then it will fail to compile.

Changelog:
[General][Added] - Automatic type conversions for C++ TurboModules

Reviewed By: christophpurrer

Differential Revision: D34780512

fbshipit-source-id: 58b34533c40652db8e3aea43804ceb73bcbe97a5
This commit is contained in:
Scott Kyle 2022-03-11 12:47:51 -08:00 коммит произвёл Facebook GitHub Bot
Родитель 6697b7bb90
Коммит 31f0796237
3 изменённых файлов: 633 добавлений и 53 удалений

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

@ -52,4 +52,14 @@ T callFromJs(
}
}
template <typename R, typename... Args>
constexpr size_t getParameterCount(R (*)(Args...)) {
return sizeof...(Args);
}
template <typename C, typename R, typename... Args>
constexpr size_t getParameterCount(R (C::*)(Args...)) {
return sizeof...(Args);
}
} // namespace facebook::react::bridging

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

@ -15,6 +15,7 @@ import type {
SchemaType,
NativeModuleTypeAnnotation,
NativeModuleFunctionTypeAnnotation,
NativeModulePropertyShape,
} from '../../CodegenSchema';
import type {AliasResolver} from './Utils';
@ -27,21 +28,58 @@ type FilesOutput = Map<string, string>;
const ModuleClassDeclarationTemplate = ({
hasteModuleName,
moduleProperties,
}: $ReadOnly<{hasteModuleName: string, moduleProperties: string}>) => {
}: $ReadOnly<{hasteModuleName: string, moduleProperties: string[]}>) => {
return `class JSI_EXPORT ${hasteModuleName}CxxSpecJSI : public TurboModule {
protected:
${hasteModuleName}CxxSpecJSI(std::shared_ptr<CallInvoker> jsInvoker);
public:
${indent(moduleProperties, 2)}
${indent(moduleProperties.join('\n'), 2)}
};`;
};
const ModuleSpecClassDeclarationTemplate = ({
hasteModuleName,
moduleName,
moduleProperties,
}: $ReadOnly<{
hasteModuleName: string,
moduleName: string,
moduleProperties: string[],
}>) => {
return `template <typename T>
class JSI_EXPORT ${hasteModuleName}CxxSpec : public TurboModule {
public:
jsi::Value get(jsi::Runtime &rt, const jsi::PropNameID &propName) override {
return delegate_.get(rt, propName);
}
protected:
${hasteModuleName}CxxSpec(std::shared_ptr<CallInvoker> jsInvoker)
: TurboModule("${moduleName}", jsInvoker),
delegate_(static_cast<T*>(this), jsInvoker) {}
private:
class Delegate : public ${hasteModuleName}CxxSpecJSI {
public:
Delegate(T *instance, std::shared_ptr<CallInvoker> jsInvoker) :
${hasteModuleName}CxxSpecJSI(std::move(jsInvoker)), instance_(instance) {}
${indent(moduleProperties.join('\n'), 4)}
private:
T *instance_;
};
Delegate delegate_;
};`;
};
const FileTemplate = ({
modules,
}: $ReadOnly<{
modules: string,
modules: string[],
}>) => {
return `/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
@ -55,11 +93,12 @@ const FileTemplate = ({
#pragma once
#include <ReactCommon/TurboModule.h>
#include <react/bridging/Bridging.h>
namespace facebook {
namespace react {
${modules}
${modules.join('\n\n')}
} // namespace react
} // namespace facebook
@ -118,8 +157,52 @@ function translatePrimitiveJSTypeToCpp(
}
}
const propertyTemplate =
'virtual ::_RETURN_VALUE_:: ::_PROPERTY_NAME_::(jsi::Runtime &rt::_ARGS_::) = 0;';
function translatePropertyToCpp(
prop: NativeModulePropertyShape,
resolveAlias: AliasResolver,
abstract: boolean = false,
) {
const [propTypeAnnotation] =
unwrapNullable<NativeModuleFunctionTypeAnnotation>(prop.typeAnnotation);
const params = propTypeAnnotation.params.map(
param => `std::move(${param.name})`,
);
const paramTypes = propTypeAnnotation.params.map(param => {
const translatedParam = translatePrimitiveJSTypeToCpp(
param.typeAnnotation,
typeName =>
`Unsupported type for param "${param.name}" in ${prop.name}. Found: ${typeName}`,
resolveAlias,
);
return `${translatedParam} ${param.name}`;
});
const returnType = translatePrimitiveJSTypeToCpp(
propTypeAnnotation.returnTypeAnnotation,
typeName => `Unsupported return type for ${prop.name}. Found: ${typeName}`,
resolveAlias,
);
// The first param will always be the runtime reference.
paramTypes.unshift('jsi::Runtime &rt');
const method = `${returnType} ${prop.name}(${paramTypes.join(', ')})`;
if (abstract) {
return `virtual ${method} = 0;`;
}
return `${method} override {
static_assert(
bridging::getParameterCount(&T::${prop.name}) == ${paramTypes.length},
"Expected ${prop.name}(...) to have ${paramTypes.length} parameters");
return bridging::callFromJs<${returnType}>(
rt, &T::${prop.name}, jsInvoker_, ${['instance_', ...params].join(', ')});
}`;
}
module.exports = {
generate(
@ -130,55 +213,30 @@ module.exports = {
): FilesOutput {
const nativeModules = getModules(schema);
const modules = Object.keys(nativeModules)
.map(hasteModuleName => {
const {
aliases,
spec: {properties},
} = nativeModules[hasteModuleName];
const resolveAlias = createAliasResolver(aliases);
const modules = Object.keys(nativeModules).flatMap(hasteModuleName => {
const {
aliases,
spec: {properties},
moduleNames: [moduleName],
} = nativeModules[hasteModuleName];
const resolveAlias = createAliasResolver(aliases);
const traversedProperties = properties
.map(prop => {
const [propTypeAnnotation] =
unwrapNullable<NativeModuleFunctionTypeAnnotation>(
prop.typeAnnotation,
);
const traversedArgs = propTypeAnnotation.params
.map(param => {
const translatedParam = translatePrimitiveJSTypeToCpp(
param.typeAnnotation,
typeName =>
`Unsupported type for param "${param.name}" in ${prop.name}. Found: ${typeName}`,
resolveAlias,
);
return `${translatedParam} ${param.name}`;
})
.join(', ');
return propertyTemplate
.replace('::_PROPERTY_NAME_::', prop.name)
.replace(
'::_RETURN_VALUE_::',
translatePrimitiveJSTypeToCpp(
propTypeAnnotation.returnTypeAnnotation,
typeName =>
`Unsupported return type for ${prop.name}. Found: ${typeName}`,
resolveAlias,
),
)
.replace(
'::_ARGS_::',
traversedArgs === '' ? '' : ', ' + traversedArgs,
);
})
.join('\n');
return ModuleClassDeclarationTemplate({
return [
ModuleClassDeclarationTemplate({
hasteModuleName,
moduleProperties: traversedProperties,
});
})
.join('\n');
moduleProperties: properties.map(prop =>
translatePropertyToCpp(prop, resolveAlias, true),
),
}),
ModuleSpecClassDeclarationTemplate({
hasteModuleName,
moduleName,
moduleProperties: properties.map(prop =>
translatePropertyToCpp(prop, resolveAlias),
),
}),
];
});
const fileName = `${libraryName}JSI.h`;
const replacedTemplate = FileTemplate({modules});

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

@ -14,6 +14,7 @@ Map {
#pragma once
#include <ReactCommon/TurboModule.h>
#include <react/bridging/Bridging.h>
namespace facebook {
namespace react {
@ -27,6 +28,33 @@ public:
};
template <typename T>
class JSI_EXPORT NativeSampleTurboModuleCxxSpec : public TurboModule {
public:
jsi::Value get(jsi::Runtime &rt, const jsi::PropNameID &propName) override {
return delegate_.get(rt, propName);
}
protected:
NativeSampleTurboModuleCxxSpec(std::shared_ptr<CallInvoker> jsInvoker)
: TurboModule(\\"SampleTurboModule\\", jsInvoker),
delegate_(static_cast<T*>(this), jsInvoker) {}
private:
class Delegate : public NativeSampleTurboModuleCxxSpecJSI {
public:
Delegate(T *instance, std::shared_ptr<CallInvoker> jsInvoker) :
NativeSampleTurboModuleCxxSpecJSI(std::move(jsInvoker)), instance_(instance) {}
private:
T *instance_;
};
Delegate delegate_;
};
} // namespace react
} // namespace facebook
",
@ -47,6 +75,7 @@ Map {
#pragma once
#include <ReactCommon/TurboModule.h>
#include <react/bridging/Bridging.h>
namespace facebook {
namespace react {
@ -63,6 +92,64 @@ public:
};
template <typename T>
class JSI_EXPORT NativeSampleTurboModuleCxxSpec : public TurboModule {
public:
jsi::Value get(jsi::Runtime &rt, const jsi::PropNameID &propName) override {
return delegate_.get(rt, propName);
}
protected:
NativeSampleTurboModuleCxxSpec(std::shared_ptr<CallInvoker> jsInvoker)
: TurboModule(\\"SampleTurboModule\\", jsInvoker),
delegate_(static_cast<T*>(this), jsInvoker) {}
private:
class Delegate : public NativeSampleTurboModuleCxxSpecJSI {
public:
Delegate(T *instance, std::shared_ptr<CallInvoker> jsInvoker) :
NativeSampleTurboModuleCxxSpecJSI(std::move(jsInvoker)), instance_(instance) {}
jsi::Object difficult(jsi::Runtime &rt, jsi::Object A) override {
static_assert(
bridging::getParameterCount(&T::difficult) == 2,
\\"Expected difficult(...) to have 2 parameters\\");
return bridging::callFromJs<jsi::Object>(
rt, &T::difficult, jsInvoker_, instance_, std::move(A));
}
void optionals(jsi::Runtime &rt, jsi::Object A) override {
static_assert(
bridging::getParameterCount(&T::optionals) == 2,
\\"Expected optionals(...) to have 2 parameters\\");
return bridging::callFromJs<void>(
rt, &T::optionals, jsInvoker_, instance_, std::move(A));
}
void optionalMethod(jsi::Runtime &rt, jsi::Object options, jsi::Function callback, jsi::Array extras) override {
static_assert(
bridging::getParameterCount(&T::optionalMethod) == 4,
\\"Expected optionalMethod(...) to have 4 parameters\\");
return bridging::callFromJs<void>(
rt, &T::optionalMethod, jsInvoker_, instance_, std::move(options), std::move(callback), std::move(extras));
}
void getArrays(jsi::Runtime &rt, jsi::Object options) override {
static_assert(
bridging::getParameterCount(&T::getArrays) == 2,
\\"Expected getArrays(...) to have 2 parameters\\");
return bridging::callFromJs<void>(
rt, &T::getArrays, jsInvoker_, instance_, std::move(options));
}
private:
T *instance_;
};
Delegate delegate_;
};
} // namespace react
} // namespace facebook
",
@ -83,6 +170,7 @@ Map {
#pragma once
#include <ReactCommon/TurboModule.h>
#include <react/bridging/Bridging.h>
namespace facebook {
namespace react {
@ -96,6 +184,33 @@ public:
};
template <typename T>
class JSI_EXPORT NativeSampleTurboModuleCxxSpec : public TurboModule {
public:
jsi::Value get(jsi::Runtime &rt, const jsi::PropNameID &propName) override {
return delegate_.get(rt, propName);
}
protected:
NativeSampleTurboModuleCxxSpec(std::shared_ptr<CallInvoker> jsInvoker)
: TurboModule(\\"SampleTurboModule\\", jsInvoker),
delegate_(static_cast<T*>(this), jsInvoker) {}
private:
class Delegate : public NativeSampleTurboModuleCxxSpecJSI {
public:
Delegate(T *instance, std::shared_ptr<CallInvoker> jsInvoker) :
NativeSampleTurboModuleCxxSpecJSI(std::move(jsInvoker)), instance_(instance) {}
private:
T *instance_;
};
Delegate delegate_;
};
} // namespace react
} // namespace facebook
",
@ -116,6 +231,7 @@ Map {
#pragma once
#include <ReactCommon/TurboModule.h>
#include <react/bridging/Bridging.h>
namespace facebook {
namespace react {
@ -130,6 +246,48 @@ public:
};
template <typename T>
class JSI_EXPORT AliasTurboModuleCxxSpec : public TurboModule {
public:
jsi::Value get(jsi::Runtime &rt, const jsi::PropNameID &propName) override {
return delegate_.get(rt, propName);
}
protected:
AliasTurboModuleCxxSpec(std::shared_ptr<CallInvoker> jsInvoker)
: TurboModule(\\"AliasTurboModule\\", jsInvoker),
delegate_(static_cast<T*>(this), jsInvoker) {}
private:
class Delegate : public AliasTurboModuleCxxSpecJSI {
public:
Delegate(T *instance, std::shared_ptr<CallInvoker> jsInvoker) :
AliasTurboModuleCxxSpecJSI(std::move(jsInvoker)), instance_(instance) {}
jsi::Object getConstants(jsi::Runtime &rt) override {
static_assert(
bridging::getParameterCount(&T::getConstants) == 1,
\\"Expected getConstants(...) to have 1 parameters\\");
return bridging::callFromJs<jsi::Object>(
rt, &T::getConstants, jsInvoker_, instance_);
}
void cropImage(jsi::Runtime &rt, jsi::Object cropData) override {
static_assert(
bridging::getParameterCount(&T::cropImage) == 2,
\\"Expected cropImage(...) to have 2 parameters\\");
return bridging::callFromJs<void>(
rt, &T::cropImage, jsInvoker_, instance_, std::move(cropData));
}
private:
T *instance_;
};
Delegate delegate_;
};
} // namespace react
} // namespace facebook
",
@ -150,6 +308,7 @@ Map {
#pragma once
#include <ReactCommon/TurboModule.h>
#include <react/bridging/Bridging.h>
namespace facebook {
namespace react {
@ -165,6 +324,65 @@ public:
virtual jsi::Value deletePhotos(jsi::Runtime &rt, jsi::Array assets) = 0;
};
template <typename T>
class JSI_EXPORT NativeCameraRollManagerCxxSpec : public TurboModule {
public:
jsi::Value get(jsi::Runtime &rt, const jsi::PropNameID &propName) override {
return delegate_.get(rt, propName);
}
protected:
NativeCameraRollManagerCxxSpec(std::shared_ptr<CallInvoker> jsInvoker)
: TurboModule(\\"CameraRollManager\\", jsInvoker),
delegate_(static_cast<T*>(this), jsInvoker) {}
private:
class Delegate : public NativeCameraRollManagerCxxSpecJSI {
public:
Delegate(T *instance, std::shared_ptr<CallInvoker> jsInvoker) :
NativeCameraRollManagerCxxSpecJSI(std::move(jsInvoker)), instance_(instance) {}
jsi::Object getConstants(jsi::Runtime &rt) override {
static_assert(
bridging::getParameterCount(&T::getConstants) == 1,
\\"Expected getConstants(...) to have 1 parameters\\");
return bridging::callFromJs<jsi::Object>(
rt, &T::getConstants, jsInvoker_, instance_);
}
jsi::Value getPhotos(jsi::Runtime &rt, jsi::Object params) override {
static_assert(
bridging::getParameterCount(&T::getPhotos) == 2,
\\"Expected getPhotos(...) to have 2 parameters\\");
return bridging::callFromJs<jsi::Value>(
rt, &T::getPhotos, jsInvoker_, instance_, std::move(params));
}
jsi::Value saveToCameraRoll(jsi::Runtime &rt, jsi::String uri, jsi::String type) override {
static_assert(
bridging::getParameterCount(&T::saveToCameraRoll) == 3,
\\"Expected saveToCameraRoll(...) to have 3 parameters\\");
return bridging::callFromJs<jsi::Value>(
rt, &T::saveToCameraRoll, jsInvoker_, instance_, std::move(uri), std::move(type));
}
jsi::Value deletePhotos(jsi::Runtime &rt, jsi::Array assets) override {
static_assert(
bridging::getParameterCount(&T::deletePhotos) == 2,
\\"Expected deletePhotos(...) to have 2 parameters\\");
return bridging::callFromJs<jsi::Value>(
rt, &T::deletePhotos, jsInvoker_, instance_, std::move(assets));
}
private:
T *instance_;
};
Delegate delegate_;
};
class JSI_EXPORT NativeImagePickerIOSCxxSpecJSI : public TurboModule {
protected:
NativeImagePickerIOSCxxSpecJSI(std::shared_ptr<CallInvoker> jsInvoker);
@ -173,6 +391,41 @@ public:
virtual void openCameraDialog(jsi::Runtime &rt, jsi::Object config, jsi::Function successCallback, jsi::Function cancelCallback) = 0;
};
template <typename T>
class JSI_EXPORT NativeImagePickerIOSCxxSpec : public TurboModule {
public:
jsi::Value get(jsi::Runtime &rt, const jsi::PropNameID &propName) override {
return delegate_.get(rt, propName);
}
protected:
NativeImagePickerIOSCxxSpec(std::shared_ptr<CallInvoker> jsInvoker)
: TurboModule(\\"ImagePickerIOS\\", jsInvoker),
delegate_(static_cast<T*>(this), jsInvoker) {}
private:
class Delegate : public NativeImagePickerIOSCxxSpecJSI {
public:
Delegate(T *instance, std::shared_ptr<CallInvoker> jsInvoker) :
NativeImagePickerIOSCxxSpecJSI(std::move(jsInvoker)), instance_(instance) {}
void openCameraDialog(jsi::Runtime &rt, jsi::Object config, jsi::Function successCallback, jsi::Function cancelCallback) override {
static_assert(
bridging::getParameterCount(&T::openCameraDialog) == 4,
\\"Expected openCameraDialog(...) to have 4 parameters\\");
return bridging::callFromJs<void>(
rt, &T::openCameraDialog, jsInvoker_, instance_, std::move(config), std::move(successCallback), std::move(cancelCallback));
}
private:
T *instance_;
};
Delegate delegate_;
};
class JSI_EXPORT NativeExceptionsManagerCxxSpecJSI : public TurboModule {
protected:
NativeExceptionsManagerCxxSpecJSI(std::shared_ptr<CallInvoker> jsInvoker);
@ -186,6 +439,72 @@ public:
};
template <typename T>
class JSI_EXPORT NativeExceptionsManagerCxxSpec : public TurboModule {
public:
jsi::Value get(jsi::Runtime &rt, const jsi::PropNameID &propName) override {
return delegate_.get(rt, propName);
}
protected:
NativeExceptionsManagerCxxSpec(std::shared_ptr<CallInvoker> jsInvoker)
: TurboModule(\\"ExceptionsManager\\", jsInvoker),
delegate_(static_cast<T*>(this), jsInvoker) {}
private:
class Delegate : public NativeExceptionsManagerCxxSpecJSI {
public:
Delegate(T *instance, std::shared_ptr<CallInvoker> jsInvoker) :
NativeExceptionsManagerCxxSpecJSI(std::move(jsInvoker)), instance_(instance) {}
void reportFatalException(jsi::Runtime &rt, jsi::String message, jsi::Array stack, double exceptionId) override {
static_assert(
bridging::getParameterCount(&T::reportFatalException) == 4,
\\"Expected reportFatalException(...) to have 4 parameters\\");
return bridging::callFromJs<void>(
rt, &T::reportFatalException, jsInvoker_, instance_, std::move(message), std::move(stack), std::move(exceptionId));
}
void reportSoftException(jsi::Runtime &rt, jsi::String message, jsi::Array stack, double exceptionId) override {
static_assert(
bridging::getParameterCount(&T::reportSoftException) == 4,
\\"Expected reportSoftException(...) to have 4 parameters\\");
return bridging::callFromJs<void>(
rt, &T::reportSoftException, jsInvoker_, instance_, std::move(message), std::move(stack), std::move(exceptionId));
}
void reportException(jsi::Runtime &rt, jsi::Object data) override {
static_assert(
bridging::getParameterCount(&T::reportException) == 2,
\\"Expected reportException(...) to have 2 parameters\\");
return bridging::callFromJs<void>(
rt, &T::reportException, jsInvoker_, instance_, std::move(data));
}
void updateExceptionMessage(jsi::Runtime &rt, jsi::String message, jsi::Array stack, double exceptionId) override {
static_assert(
bridging::getParameterCount(&T::updateExceptionMessage) == 4,
\\"Expected updateExceptionMessage(...) to have 4 parameters\\");
return bridging::callFromJs<void>(
rt, &T::updateExceptionMessage, jsInvoker_, instance_, std::move(message), std::move(stack), std::move(exceptionId));
}
void dismissRedbox(jsi::Runtime &rt) override {
static_assert(
bridging::getParameterCount(&T::dismissRedbox) == 1,
\\"Expected dismissRedbox(...) to have 1 parameters\\");
return bridging::callFromJs<void>(
rt, &T::dismissRedbox, jsInvoker_, instance_);
}
private:
T *instance_;
};
Delegate delegate_;
};
} // namespace react
} // namespace facebook
",
@ -206,6 +525,7 @@ Map {
#pragma once
#include <ReactCommon/TurboModule.h>
#include <react/bridging/Bridging.h>
namespace facebook {
namespace react {
@ -229,6 +549,120 @@ public:
};
template <typename T>
class JSI_EXPORT NativeSampleTurboModuleCxxSpec : public TurboModule {
public:
jsi::Value get(jsi::Runtime &rt, const jsi::PropNameID &propName) override {
return delegate_.get(rt, propName);
}
protected:
NativeSampleTurboModuleCxxSpec(std::shared_ptr<CallInvoker> jsInvoker)
: TurboModule(\\"SampleTurboModule\\", jsInvoker),
delegate_(static_cast<T*>(this), jsInvoker) {}
private:
class Delegate : public NativeSampleTurboModuleCxxSpecJSI {
public:
Delegate(T *instance, std::shared_ptr<CallInvoker> jsInvoker) :
NativeSampleTurboModuleCxxSpecJSI(std::move(jsInvoker)), instance_(instance) {}
jsi::Object getConstants(jsi::Runtime &rt) override {
static_assert(
bridging::getParameterCount(&T::getConstants) == 1,
\\"Expected getConstants(...) to have 1 parameters\\");
return bridging::callFromJs<jsi::Object>(
rt, &T::getConstants, jsInvoker_, instance_);
}
void voidFunc(jsi::Runtime &rt) override {
static_assert(
bridging::getParameterCount(&T::voidFunc) == 1,
\\"Expected voidFunc(...) to have 1 parameters\\");
return bridging::callFromJs<void>(
rt, &T::voidFunc, jsInvoker_, instance_);
}
bool getBool(jsi::Runtime &rt, bool arg) override {
static_assert(
bridging::getParameterCount(&T::getBool) == 2,
\\"Expected getBool(...) to have 2 parameters\\");
return bridging::callFromJs<bool>(
rt, &T::getBool, jsInvoker_, instance_, std::move(arg));
}
double getNumber(jsi::Runtime &rt, double arg) override {
static_assert(
bridging::getParameterCount(&T::getNumber) == 2,
\\"Expected getNumber(...) to have 2 parameters\\");
return bridging::callFromJs<double>(
rt, &T::getNumber, jsInvoker_, instance_, std::move(arg));
}
jsi::String getString(jsi::Runtime &rt, jsi::String arg) override {
static_assert(
bridging::getParameterCount(&T::getString) == 2,
\\"Expected getString(...) to have 2 parameters\\");
return bridging::callFromJs<jsi::String>(
rt, &T::getString, jsInvoker_, instance_, std::move(arg));
}
jsi::Array getArray(jsi::Runtime &rt, jsi::Array arg) override {
static_assert(
bridging::getParameterCount(&T::getArray) == 2,
\\"Expected getArray(...) to have 2 parameters\\");
return bridging::callFromJs<jsi::Array>(
rt, &T::getArray, jsInvoker_, instance_, std::move(arg));
}
jsi::Object getObject(jsi::Runtime &rt, jsi::Object arg) override {
static_assert(
bridging::getParameterCount(&T::getObject) == 2,
\\"Expected getObject(...) to have 2 parameters\\");
return bridging::callFromJs<jsi::Object>(
rt, &T::getObject, jsInvoker_, instance_, std::move(arg));
}
double getRootTag(jsi::Runtime &rt, double arg) override {
static_assert(
bridging::getParameterCount(&T::getRootTag) == 2,
\\"Expected getRootTag(...) to have 2 parameters\\");
return bridging::callFromJs<double>(
rt, &T::getRootTag, jsInvoker_, instance_, std::move(arg));
}
jsi::Object getValue(jsi::Runtime &rt, double x, jsi::String y, jsi::Object z) override {
static_assert(
bridging::getParameterCount(&T::getValue) == 4,
\\"Expected getValue(...) to have 4 parameters\\");
return bridging::callFromJs<jsi::Object>(
rt, &T::getValue, jsInvoker_, instance_, std::move(x), std::move(y), std::move(z));
}
void getValueWithCallback(jsi::Runtime &rt, jsi::Function callback) override {
static_assert(
bridging::getParameterCount(&T::getValueWithCallback) == 2,
\\"Expected getValueWithCallback(...) to have 2 parameters\\");
return bridging::callFromJs<void>(
rt, &T::getValueWithCallback, jsInvoker_, instance_, std::move(callback));
}
jsi::Value getValueWithPromise(jsi::Runtime &rt, bool error) override {
static_assert(
bridging::getParameterCount(&T::getValueWithPromise) == 2,
\\"Expected getValueWithPromise(...) to have 2 parameters\\");
return bridging::callFromJs<jsi::Value>(
rt, &T::getValueWithPromise, jsInvoker_, instance_, std::move(error));
}
private:
T *instance_;
};
Delegate delegate_;
};
} // namespace react
} // namespace facebook
",
@ -249,6 +683,7 @@ Map {
#pragma once
#include <ReactCommon/TurboModule.h>
#include <react/bridging/Bridging.h>
namespace facebook {
namespace react {
@ -261,6 +696,41 @@ public:
virtual void voidFunc(jsi::Runtime &rt) = 0;
};
template <typename T>
class JSI_EXPORT NativeSampleTurboModuleCxxSpec : public TurboModule {
public:
jsi::Value get(jsi::Runtime &rt, const jsi::PropNameID &propName) override {
return delegate_.get(rt, propName);
}
protected:
NativeSampleTurboModuleCxxSpec(std::shared_ptr<CallInvoker> jsInvoker)
: TurboModule(\\"SampleTurboModule\\", jsInvoker),
delegate_(static_cast<T*>(this), jsInvoker) {}
private:
class Delegate : public NativeSampleTurboModuleCxxSpecJSI {
public:
Delegate(T *instance, std::shared_ptr<CallInvoker> jsInvoker) :
NativeSampleTurboModuleCxxSpecJSI(std::move(jsInvoker)), instance_(instance) {}
void voidFunc(jsi::Runtime &rt) override {
static_assert(
bridging::getParameterCount(&T::voidFunc) == 1,
\\"Expected voidFunc(...) to have 1 parameters\\");
return bridging::callFromJs<void>(
rt, &T::voidFunc, jsInvoker_, instance_);
}
private:
T *instance_;
};
Delegate delegate_;
};
class JSI_EXPORT NativeSampleTurboModule2CxxSpecJSI : public TurboModule {
protected:
NativeSampleTurboModule2CxxSpecJSI(std::shared_ptr<CallInvoker> jsInvoker);
@ -271,6 +741,48 @@ public:
};
template <typename T>
class JSI_EXPORT NativeSampleTurboModule2CxxSpec : public TurboModule {
public:
jsi::Value get(jsi::Runtime &rt, const jsi::PropNameID &propName) override {
return delegate_.get(rt, propName);
}
protected:
NativeSampleTurboModule2CxxSpec(std::shared_ptr<CallInvoker> jsInvoker)
: TurboModule(\\"SampleTurboModule2\\", jsInvoker),
delegate_(static_cast<T*>(this), jsInvoker) {}
private:
class Delegate : public NativeSampleTurboModule2CxxSpecJSI {
public:
Delegate(T *instance, std::shared_ptr<CallInvoker> jsInvoker) :
NativeSampleTurboModule2CxxSpecJSI(std::move(jsInvoker)), instance_(instance) {}
jsi::Object getConstants(jsi::Runtime &rt) override {
static_assert(
bridging::getParameterCount(&T::getConstants) == 1,
\\"Expected getConstants(...) to have 1 parameters\\");
return bridging::callFromJs<jsi::Object>(
rt, &T::getConstants, jsInvoker_, instance_);
}
void voidFunc(jsi::Runtime &rt) override {
static_assert(
bridging::getParameterCount(&T::voidFunc) == 1,
\\"Expected voidFunc(...) to have 1 parameters\\");
return bridging::callFromJs<void>(
rt, &T::voidFunc, jsInvoker_, instance_);
}
private:
T *instance_;
};
Delegate delegate_;
};
} // namespace react
} // namespace facebook
",