From 8e2b13bb6f8ee9739570cc616e3e39aeb4e39018 Mon Sep 17 00:00:00 2001 From: Andrew Coates <30809111+acoates-ms@users.noreply.github.com> Date: Fri, 14 Oct 2022 11:18:56 -0700 Subject: [PATCH 01/17] Example of using Meta's c++ JSI codegen --- .../codegen/src/index.ts | 36 +- .../codegen/NativeMyJsiModuleSpec.g.h | 101 + .../codegen/SampleAppJSI-generated.cpp | 110 + packages/sample-apps/codegen/SampleAppJSI.h | 267 + packages/sample-apps/index.windows.js | 4 + packages/sample-apps/src/NativeMyJsiModule.js | 32 + .../sample-apps/windows/SampleAppCPP/App.cpp | 4 +- .../windows/SampleAppCS/packages.lock.json | 3 +- .../windows/SampleLibraryCPP/MyJsiModule.cpp | 87 + .../windows/SampleLibraryCPP/MyJsiModule.h | 32 + .../SampleLibraryCPP/ReactPackageProvider.cpp | 5 +- .../SampleLibraryCPP/SampleLibraryCPP.vcxproj | 14 +- .../components/rnwcore/ComponentDescriptors.h | 6 +- .../components/rnwcore/EventEmitters.cpp | 6 +- .../react/components/rnwcore/EventEmitters.h | 37 +- .../react/components/rnwcore/Props.cpp | 6 +- .../codegen/react/components/rnwcore/Props.h | 37 +- .../react/components/rnwcore/ShadowNodes.cpp | 6 +- .../react/components/rnwcore/ShadowNodes.h | 25 +- vnext/codegen/rnwcoreJSI-generated.cpp | 1774 ++++++ vnext/codegen/rnwcoreJSI.h | 5030 +++++++++++++++++ 21 files changed, 7546 insertions(+), 76 deletions(-) create mode 100644 packages/sample-apps/codegen/NativeMyJsiModuleSpec.g.h create mode 100644 packages/sample-apps/codegen/SampleAppJSI-generated.cpp create mode 100644 packages/sample-apps/codegen/SampleAppJSI.h create mode 100644 packages/sample-apps/src/NativeMyJsiModule.js create mode 100644 packages/sample-apps/windows/SampleLibraryCPP/MyJsiModule.cpp create mode 100644 packages/sample-apps/windows/SampleLibraryCPP/MyJsiModule.h create mode 100644 vnext/codegen/rnwcoreJSI-generated.cpp create mode 100644 vnext/codegen/rnwcoreJSI.h diff --git a/packages/@react-native-windows/codegen/src/index.ts b/packages/@react-native-windows/codegen/src/index.ts index 8778e6e1825..1478ec2517e 100644 --- a/packages/@react-native-windows/codegen/src/index.ts +++ b/packages/@react-native-windows/codegen/src/index.ts @@ -208,26 +208,38 @@ export function generate( methodonly, }); + const generateJsiModuleH = require(path.resolve(rncodegenPath, 'lib/generators/modules/GenerateModuleH')).generate; + const generateJsiModuleCpp = require(path.resolve(rncodegenPath, 'lib/generators/modules/GenerateModuleCpp')).generate; const generatorPropsH = - require('react-native-tscodegen/lib/rncodegen/src/generators/components/GeneratePropsH').generate; + require(path.resolve(rncodegenPath, 'lib/generators/components/GeneratePropsH')).generate; const generatorPropsCPP = - require('react-native-tscodegen/lib/rncodegen/src/generators/components/GeneratePropsCPP').generate; + require(path.resolve(rncodegenPath, 'lib/generators/components/GeneratePropsCPP')).generate; const generatorShadowNodeH = - require('react-native-tscodegen/lib/rncodegen/src/generators/components/GenerateShadowNodeH').generate; + require(path.resolve(rncodegenPath, 'lib/generators/components/GenerateShadowNodeH')).generate; const generatorShadowNodeCPP = - require('react-native-tscodegen/lib/rncodegen/src/generators/components/GenerateShadowNodeCPP').generate; + require(path.resolve(rncodegenPath, 'lib/generators/components/GenerateShadowNodeCPP')).generate; const generatorComponentDescriptorH = - require('react-native-tscodegen/lib/rncodegen/src/generators/components/GenerateComponentDescriptorH').generate; + require(path.resolve(rncodegenPath, 'lib/generators/components/GenerateComponentDescriptorH')).generate; const generatorEventEmitterH = - require('react-native-tscodegen/lib/rncodegen/src/generators/components/GenerateEventEmitterH').generate; + require(path.resolve(rncodegenPath, 'lib/generators/components/GenerateEventEmitterH')).generate; const generatorEventEmitterCPP = - require('react-native-tscodegen/lib/rncodegen/src/generators/components/GenerateEventEmitterCpp').generate; + require(path.resolve(rncodegenPath, 'lib/generators/components/GenerateEventEmitterCpp')).generate; - normalizeFileMap( - generateNM2(libraryName, schema, moduleSpecName), - outputDirectory, - generatedFiles, - ); + const moduleGenerators = [ + generateNM2, + generateJsiModuleH, + generateJsiModuleCpp, + ]; + + + moduleGenerators.forEach(generator => { + const generated: Map = generator( + libraryName, + schema, + moduleSpecName, + ); + normalizeFileMap(generated, outputDirectory, generatedFiles); + }); if (ts) { normalizeFileMap( diff --git a/packages/sample-apps/codegen/NativeMyJsiModuleSpec.g.h b/packages/sample-apps/codegen/NativeMyJsiModuleSpec.g.h new file mode 100644 index 00000000000..7ab0ac102e7 --- /dev/null +++ b/packages/sample-apps/codegen/NativeMyJsiModuleSpec.g.h @@ -0,0 +1,101 @@ + +/* + * This file is auto-generated from a NativeModule spec file in js. + * + * This is a C++ Spec class that should be used with MakeTurboModuleProvider to register native modules + * in a way that also verifies at compile time that the native module matches the interface required + * by the TurboModule JS spec. + */ +#pragma once + +#include "NativeModules.h" +#include + +namespace SampleLibraryCodegen { + +REACT_STRUCT(MyJsiModuleSpec_Constants) +struct MyJsiModuleSpec_Constants { + REACT_FIELD(const1) + bool const1; + REACT_FIELD(const2) + double const2; + REACT_FIELD(const3) + std::string const3; +}; + +struct MyJsiModuleSpec : winrt::Microsoft::ReactNative::TurboModuleSpec { + static constexpr auto constants = std::tuple{ + TypedConstant{0}, + }; + static constexpr auto methods = std::tuple{ + Method{0, L"voidFunc"}, + SyncMethod{1, L"getBool"}, + SyncMethod{2, L"getNumber"}, + SyncMethod{3, L"getString"}, + SyncMethod<::React::JSValueArray(::React::JSValueArray) noexcept>{4, L"getArray"}, + SyncMethod<::React::JSValue(::React::JSValue) noexcept>{5, L"getObject"}, + SyncMethod<::React::JSValue(double, std::string, ::React::JSValue) noexcept>{6, L"getValue"}, + Method) noexcept>{7, L"getValueWithCallback"}, + Method) noexcept>{8, L"getValueWithPromise"}, + }; + + template + static constexpr void ValidateModule() noexcept { + constexpr auto constantCheckResults = CheckConstants(); + constexpr auto methodCheckResults = CheckMethods(); + + REACT_SHOW_CONSTANT_SPEC_ERRORS( + 0, + "MyJsiModuleSpec_Constants", + " REACT_GET_CONSTANTS(GetConstants) MyJsiModuleSpec_Constants GetConstants() noexcept {/*implementation*/}\n" + " REACT_GET_CONSTANTS(GetConstants) static MyJsiModuleSpec_Constants GetConstants() noexcept {/*implementation*/}\n"); + + REACT_SHOW_METHOD_SPEC_ERRORS( + 0, + "voidFunc", + " REACT_METHOD(voidFunc) void voidFunc() noexcept { /* implementation */ }\n" + " REACT_METHOD(voidFunc) static void voidFunc() noexcept { /* implementation */ }\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 1, + "getBool", + " REACT_SYNC_METHOD(getBool) bool getBool(bool arg) noexcept { /* implementation */ }\n" + " REACT_SYNC_METHOD(getBool) static bool getBool(bool arg) noexcept { /* implementation */ }\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 2, + "getNumber", + " REACT_SYNC_METHOD(getNumber) double getNumber(double arg) noexcept { /* implementation */ }\n" + " REACT_SYNC_METHOD(getNumber) static double getNumber(double arg) noexcept { /* implementation */ }\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 3, + "getString", + " REACT_SYNC_METHOD(getString) std::string getString(std::string arg) noexcept { /* implementation */ }\n" + " REACT_SYNC_METHOD(getString) static std::string getString(std::string arg) noexcept { /* implementation */ }\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 4, + "getArray", + " REACT_SYNC_METHOD(getArray) ::React::JSValueArray getArray(::React::JSValueArray && arg) noexcept { /* implementation */ }\n" + " REACT_SYNC_METHOD(getArray) static ::React::JSValueArray getArray(::React::JSValueArray && arg) noexcept { /* implementation */ }\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 5, + "getObject", + " REACT_SYNC_METHOD(getObject) ::React::JSValue getObject(::React::JSValue && arg) noexcept { /* implementation */ }\n" + " REACT_SYNC_METHOD(getObject) static ::React::JSValue getObject(::React::JSValue && arg) noexcept { /* implementation */ }\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 6, + "getValue", + " REACT_SYNC_METHOD(getValue) ::React::JSValue getValue(double x, std::string y, ::React::JSValue && z) noexcept { /* implementation */ }\n" + " REACT_SYNC_METHOD(getValue) static ::React::JSValue getValue(double x, std::string y, ::React::JSValue && z) noexcept { /* implementation */ }\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 7, + "getValueWithCallback", + " REACT_METHOD(getValueWithCallback) void getValueWithCallback(std::function const & callback) noexcept { /* implementation */ }\n" + " REACT_METHOD(getValueWithCallback) static void getValueWithCallback(std::function const & callback) noexcept { /* implementation */ }\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 8, + "getValueWithPromise", + " REACT_METHOD(getValueWithPromise) void getValueWithPromise(bool error, ::React::ReactPromise<::React::JSValue> &&result) noexcept { /* implementation */ }\n" + " REACT_METHOD(getValueWithPromise) static void getValueWithPromise(bool error, ::React::ReactPromise<::React::JSValue> &&result) noexcept { /* implementation */ }\n"); + } +}; + +} // namespace SampleLibraryCodegen diff --git a/packages/sample-apps/codegen/SampleAppJSI-generated.cpp b/packages/sample-apps/codegen/SampleAppJSI-generated.cpp new file mode 100644 index 00000000000..28d74229155 --- /dev/null +++ b/packages/sample-apps/codegen/SampleAppJSI-generated.cpp @@ -0,0 +1,110 @@ +/** + * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). + * + * Do not edit this file as changes may cause incorrect behavior and will be lost + * once the code is regenerated. + * + * @generated by codegen project: GenerateModuleH.js + */ + +#include "SampleAppJSI.h" + +namespace facebook { +namespace react { + +static jsi::Value __hostFunction_NativeMyJsiModuleCxxSpecJSI_getConstants(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->getConstants(rt); +} +static jsi::Value __hostFunction_NativeMyJsiModuleCxxSpecJSI_voidFunc(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + static_cast(&turboModule)->voidFunc(rt); + return jsi::Value::undefined(); +} +static jsi::Value __hostFunction_NativeMyJsiModuleCxxSpecJSI_getBool(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->getBool(rt, args[0].asBool()); +} +static jsi::Value __hostFunction_NativeMyJsiModuleCxxSpecJSI_getNumber(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->getNumber(rt, args[0].asNumber()); +} +static jsi::Value __hostFunction_NativeMyJsiModuleCxxSpecJSI_getString(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->getString(rt, args[0].asString(rt)); +} +static jsi::Value __hostFunction_NativeMyJsiModuleCxxSpecJSI_getArray(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->getArray(rt, args[0].asObject(rt).asArray(rt)); +} +static jsi::Value __hostFunction_NativeMyJsiModuleCxxSpecJSI_getObject(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->getObject(rt, args[0].asObject(rt)); +} +static jsi::Value __hostFunction_NativeMyJsiModuleCxxSpecJSI_getValue(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->getValue(rt, args[0].asNumber(), args[1].asString(rt), args[2].asObject(rt)); +} +static jsi::Value __hostFunction_NativeMyJsiModuleCxxSpecJSI_getValueWithCallback(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + static_cast(&turboModule)->getValueWithCallback(rt, args[0].asObject(rt).asFunction(rt)); + return jsi::Value::undefined(); +} +static jsi::Value __hostFunction_NativeMyJsiModuleCxxSpecJSI_getValueWithPromise(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->getValueWithPromise(rt, args[0].asBool()); +} + +NativeMyJsiModuleCxxSpecJSI::NativeMyJsiModuleCxxSpecJSI(std::shared_ptr jsInvoker) + : TurboModule("MyJsiModule", jsInvoker) { + methodMap_["getConstants"] = MethodMetadata {0, __hostFunction_NativeMyJsiModuleCxxSpecJSI_getConstants}; + methodMap_["voidFunc"] = MethodMetadata {0, __hostFunction_NativeMyJsiModuleCxxSpecJSI_voidFunc}; + methodMap_["getBool"] = MethodMetadata {1, __hostFunction_NativeMyJsiModuleCxxSpecJSI_getBool}; + methodMap_["getNumber"] = MethodMetadata {1, __hostFunction_NativeMyJsiModuleCxxSpecJSI_getNumber}; + methodMap_["getString"] = MethodMetadata {1, __hostFunction_NativeMyJsiModuleCxxSpecJSI_getString}; + methodMap_["getArray"] = MethodMetadata {1, __hostFunction_NativeMyJsiModuleCxxSpecJSI_getArray}; + methodMap_["getObject"] = MethodMetadata {1, __hostFunction_NativeMyJsiModuleCxxSpecJSI_getObject}; + methodMap_["getValue"] = MethodMetadata {3, __hostFunction_NativeMyJsiModuleCxxSpecJSI_getValue}; + methodMap_["getValueWithCallback"] = MethodMetadata {1, __hostFunction_NativeMyJsiModuleCxxSpecJSI_getValueWithCallback}; + methodMap_["getValueWithPromise"] = MethodMetadata {1, __hostFunction_NativeMyJsiModuleCxxSpecJSI_getValueWithPromise}; +} +static jsi::Value __hostFunction_NativeMyModuleCxxSpecJSI_getConstants(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->getConstants(rt); +} +static jsi::Value __hostFunction_NativeMyModuleCxxSpecJSI_voidFunc(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + static_cast(&turboModule)->voidFunc(rt); + return jsi::Value::undefined(); +} +static jsi::Value __hostFunction_NativeMyModuleCxxSpecJSI_getBool(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->getBool(rt, args[0].asBool()); +} +static jsi::Value __hostFunction_NativeMyModuleCxxSpecJSI_getNumber(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->getNumber(rt, args[0].asNumber()); +} +static jsi::Value __hostFunction_NativeMyModuleCxxSpecJSI_getString(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->getString(rt, args[0].asString(rt)); +} +static jsi::Value __hostFunction_NativeMyModuleCxxSpecJSI_getArray(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->getArray(rt, args[0].asObject(rt).asArray(rt)); +} +static jsi::Value __hostFunction_NativeMyModuleCxxSpecJSI_getObject(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->getObject(rt, args[0].asObject(rt)); +} +static jsi::Value __hostFunction_NativeMyModuleCxxSpecJSI_getValue(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->getValue(rt, args[0].asNumber(), args[1].asString(rt), args[2].asObject(rt)); +} +static jsi::Value __hostFunction_NativeMyModuleCxxSpecJSI_getValueWithCallback(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + static_cast(&turboModule)->getValueWithCallback(rt, args[0].asObject(rt).asFunction(rt)); + return jsi::Value::undefined(); +} +static jsi::Value __hostFunction_NativeMyModuleCxxSpecJSI_getValueWithPromise(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->getValueWithPromise(rt, args[0].asBool()); +} + +NativeMyModuleCxxSpecJSI::NativeMyModuleCxxSpecJSI(std::shared_ptr jsInvoker) + : TurboModule("MyModule", jsInvoker) { + methodMap_["getConstants"] = MethodMetadata {0, __hostFunction_NativeMyModuleCxxSpecJSI_getConstants}; + methodMap_["voidFunc"] = MethodMetadata {0, __hostFunction_NativeMyModuleCxxSpecJSI_voidFunc}; + methodMap_["getBool"] = MethodMetadata {1, __hostFunction_NativeMyModuleCxxSpecJSI_getBool}; + methodMap_["getNumber"] = MethodMetadata {1, __hostFunction_NativeMyModuleCxxSpecJSI_getNumber}; + methodMap_["getString"] = MethodMetadata {1, __hostFunction_NativeMyModuleCxxSpecJSI_getString}; + methodMap_["getArray"] = MethodMetadata {1, __hostFunction_NativeMyModuleCxxSpecJSI_getArray}; + methodMap_["getObject"] = MethodMetadata {1, __hostFunction_NativeMyModuleCxxSpecJSI_getObject}; + methodMap_["getValue"] = MethodMetadata {3, __hostFunction_NativeMyModuleCxxSpecJSI_getValue}; + methodMap_["getValueWithCallback"] = MethodMetadata {1, __hostFunction_NativeMyModuleCxxSpecJSI_getValueWithCallback}; + methodMap_["getValueWithPromise"] = MethodMetadata {1, __hostFunction_NativeMyModuleCxxSpecJSI_getValueWithPromise}; +} + + +} // namespace react +} // namespace facebook diff --git a/packages/sample-apps/codegen/SampleAppJSI.h b/packages/sample-apps/codegen/SampleAppJSI.h new file mode 100644 index 00000000000..cf55010eb42 --- /dev/null +++ b/packages/sample-apps/codegen/SampleAppJSI.h @@ -0,0 +1,267 @@ +/** + * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). + * + * Do not edit this file as changes may cause incorrect behavior and will be lost + * once the code is regenerated. + * + * @generated by codegen project: GenerateModuleH.js + */ + +#pragma once + +#include +#include + +namespace facebook { +namespace react { + +class JSI_EXPORT NativeMyJsiModuleCxxSpecJSI : public TurboModule { +protected: + NativeMyJsiModuleCxxSpecJSI(std::shared_ptr jsInvoker); + +public: + virtual jsi::Object getConstants(jsi::Runtime &rt) = 0; + virtual void voidFunc(jsi::Runtime &rt) = 0; + virtual bool getBool(jsi::Runtime &rt, bool arg) = 0; + virtual double getNumber(jsi::Runtime &rt, double arg) = 0; + virtual jsi::String getString(jsi::Runtime &rt, jsi::String arg) = 0; + virtual jsi::Array getArray(jsi::Runtime &rt, jsi::Array arg) = 0; + virtual jsi::Object getObject(jsi::Runtime &rt, jsi::Object arg) = 0; + virtual jsi::Object getValue(jsi::Runtime &rt, double x, jsi::String y, jsi::Object z) = 0; + virtual void getValueWithCallback(jsi::Runtime &rt, jsi::Function callback) = 0; + virtual jsi::Value getValueWithPromise(jsi::Runtime &rt, bool error) = 0; + +}; + +template +class JSI_EXPORT NativeMyJsiModuleCxxSpec : public TurboModule { +public: + jsi::Value get(jsi::Runtime &rt, const jsi::PropNameID &propName) override { + return delegate_.get(rt, propName); + } + +protected: + NativeMyJsiModuleCxxSpec(std::shared_ptr jsInvoker) + : TurboModule("MyJsiModule", jsInvoker), + delegate_(static_cast(this), jsInvoker) {} + +private: + class Delegate : public NativeMyJsiModuleCxxSpecJSI { + public: + Delegate(T *instance, std::shared_ptr jsInvoker) : + NativeMyJsiModuleCxxSpecJSI(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( + 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( + 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( + 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( + 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( + 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( + 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( + rt, &T::getObject, 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( + 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( + 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( + rt, &T::getValueWithPromise, jsInvoker_, instance_, std::move(error)); + } + + private: + T *instance_; + }; + + Delegate delegate_; +}; + +class JSI_EXPORT NativeMyModuleCxxSpecJSI : public TurboModule { +protected: + NativeMyModuleCxxSpecJSI(std::shared_ptr jsInvoker); + +public: + virtual jsi::Object getConstants(jsi::Runtime &rt) = 0; + virtual void voidFunc(jsi::Runtime &rt) = 0; + virtual bool getBool(jsi::Runtime &rt, bool arg) = 0; + virtual double getNumber(jsi::Runtime &rt, double arg) = 0; + virtual jsi::String getString(jsi::Runtime &rt, jsi::String arg) = 0; + virtual jsi::Array getArray(jsi::Runtime &rt, jsi::Array arg) = 0; + virtual jsi::Object getObject(jsi::Runtime &rt, jsi::Object arg) = 0; + virtual jsi::Object getValue(jsi::Runtime &rt, double x, jsi::String y, jsi::Object z) = 0; + virtual void getValueWithCallback(jsi::Runtime &rt, jsi::Function callback) = 0; + virtual jsi::Value getValueWithPromise(jsi::Runtime &rt, bool error) = 0; + +}; + +template +class JSI_EXPORT NativeMyModuleCxxSpec : public TurboModule { +public: + jsi::Value get(jsi::Runtime &rt, const jsi::PropNameID &propName) override { + return delegate_.get(rt, propName); + } + +protected: + NativeMyModuleCxxSpec(std::shared_ptr jsInvoker) + : TurboModule("MyModule", jsInvoker), + delegate_(static_cast(this), jsInvoker) {} + +private: + class Delegate : public NativeMyModuleCxxSpecJSI { + public: + Delegate(T *instance, std::shared_ptr jsInvoker) : + NativeMyModuleCxxSpecJSI(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( + 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( + 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( + 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( + 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( + 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( + 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( + rt, &T::getObject, 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( + 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( + 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( + rt, &T::getValueWithPromise, jsInvoker_, instance_, std::move(error)); + } + + private: + T *instance_; + }; + + Delegate delegate_; +}; + +} // namespace react +} // namespace facebook diff --git a/packages/sample-apps/index.windows.js b/packages/sample-apps/index.windows.js index 8574a2e21e5..31efb5ed470 100644 --- a/packages/sample-apps/index.windows.js +++ b/packages/sample-apps/index.windows.js @@ -22,6 +22,8 @@ import {MyComp} from './myComp'; import {default as MyModule} from './src/NativeMyModule'; +import {default as MyJsiModule} from './src/NativeMyJsiModule'; + const SampleModuleCS = TurboModuleRegistry.get('SampleModuleCS'); const SampleModuleCpp = TurboModuleRegistry.get('SampleModuleCpp'); @@ -359,6 +361,8 @@ class SampleApp extends Component {