react-native code-gen > C++ TurboModules struct support (#35265)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/35265

This adds a templating layer for C++ TurboModules to automatically generate struct templates from TurboModule specs.

You have to define concrete types for those templates to use them in your C++ TurboModule.

E.g. for the JS flow type:
```
export type ObjectStruct = {|
  a: number,
  b: string,
  c?: ?string,
|};
```
code-gen will now generate the following template code:
```
#pragma mark - NativeCxxModuleExampleCxxBaseObjectStruct

template <typename P0, typename P1, typename P2>
struct NativeCxxModuleExampleCxxBaseObjectStruct {
  P0 a;
  P1 b;
  P2 c;
  bool operator==(const NativeCxxModuleExampleCxxBaseObjectStruct &other) const {
    return a == other.a && b == other.b && c == other.c;
  }
};

template <typename P0, typename P1, typename P2>
struct NativeCxxModuleExampleCxxBaseObjectStructBridging {
  static NativeCxxModuleExampleCxxBaseObjectStruct<P0, P1, P2> fromJs(
      jsi::Runtime &rt,
      const jsi::Object &value,
      const std::shared_ptr<CallInvoker> &jsInvoker) {
    NativeCxxModuleExampleCxxBaseObjectStruct<P0, P1, P2> result{
      bridging::fromJs<P0>(rt, value.getProperty(rt, "a"), jsInvoker),
      bridging::fromJs<P1>(rt, value.getProperty(rt, "b"), jsInvoker),
      bridging::fromJs<P2>(rt, value.getProperty(rt, "c"), jsInvoker)};
    return result;
  }

  static jsi::Object toJs(
      jsi::Runtime &rt,
      const NativeCxxModuleExampleCxxBaseObjectStruct<P0, P1, P2> &value) {
    auto result = facebook::jsi::Object(rt);
    result.setProperty(rt, "a", bridging::toJs(rt, value.a));
    result.setProperty(rt, "b", bridging::toJs(rt, value.b));
    if (value.c) {
      result.setProperty(rt, "c", bridging::toJs(rt, value.c.value()));
    }
    return result;
  }
};
```
and you can use it in our C++ TurboModule for example as:
```
using ObjectStruct = NativeCxxModuleExampleCxxBaseObjectStruct<
    int32_t,
    std::string,
    std::optional<std::string>>;

template <>
struct Bridging<ObjectStruct>
    : NativeCxxModuleExampleCxxBaseObjectStructBridging<
          int32_t,
          std::string,
          std::optional<std::string>> {};
```
or as
```
using ObjectStruct = NativeCxxModuleExampleCxxBaseObjectStruct<
    float,
    folly::StringPiece,
    std::optional<std::string>>;

template <>
struct Bridging<ObjectStruct>
    : NativeCxxModuleExampleCxxBaseObjectStructBridging<
          float,
          folly::StringPiece,
          std::optional<std::string>> {};
```
Or as
...

Changelog: [Internal]

Reviewed By: rshest

Differential Revision: D41133761

fbshipit-source-id: fdf36e51073cb46c5234f6121842c79a884899c7
This commit is contained in:
Christoph Purrer
2022-11-09 13:23:05 -08:00
committed by Lorenzo Sciandra
parent adcdb366da
commit 08430bf214
9 changed files with 493 additions and 223 deletions
@@ -13,10 +13,34 @@
#include <optional>
#include <string>
#include <vector>
#include "NativePerformanceObserver_RawPerformanceEntry.h"
namespace facebook::react {
#pragma mark - Structs
using RawPerformanceEntry = NativePerformanceObserverCxxBaseRawPerformanceEntry<
std::string,
int32_t,
double,
double,
// For "event" entries only:
std::optional<double>,
std::optional<double>,
std::optional<double>>;
template <>
struct Bridging<RawPerformanceEntry>
: NativePerformanceObserverCxxBaseRawPerformanceEntryBridging<
std::string,
int32_t,
double,
double,
std::optional<double>,
std::optional<double>,
std::optional<double>> {};
#pragma mark - implementation
class NativePerformanceObserver
: public NativePerformanceObserverCxxSpec<NativePerformanceObserver>,
std::enable_shared_from_this<NativePerformanceObserver> {
@@ -18,7 +18,7 @@ export const RawPerformanceEntryTypeValues = {
export type RawPerformanceEntryType = number;
export type RawPerformanceEntry = $ReadOnly<{
export type RawPerformanceEntry = {|
name: string,
entryType: RawPerformanceEntryType,
startTime: number,
@@ -27,7 +27,7 @@ export type RawPerformanceEntry = $ReadOnly<{
processingStart?: number,
processingEnd?: number,
interactionId?: number,
}>;
|};
export interface Spec extends TurboModule {
+startReporting: (entryType: string) => void;
@@ -1,76 +0,0 @@
/*
* Copyright (c) Meta Platforms, Inc. and 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 <react/bridging/Bridging.h>
#include <optional>
#include <string>
namespace facebook::react {
struct RawPerformanceEntry {
std::string name;
int32_t entryType;
double startTime;
double duration;
// For "event" entries only:
std::optional<double> processingStart;
std::optional<double> processingEnd;
std::optional<double> interactionId;
};
template <>
struct Bridging<RawPerformanceEntry> {
static RawPerformanceEntry fromJs(
jsi::Runtime &rt,
const jsi::Object &value,
const std::shared_ptr<CallInvoker> &jsInvoker) {
RawPerformanceEntry result{
bridging::fromJs<std::string>(
rt, value.getProperty(rt, "name"), jsInvoker),
bridging::fromJs<int32_t>(
rt, value.getProperty(rt, "entryType"), jsInvoker),
bridging::fromJs<double>(
rt, value.getProperty(rt, "startTime"), jsInvoker),
bridging::fromJs<double>(
rt, value.getProperty(rt, "duration"), jsInvoker),
bridging::fromJs<std::optional<double>>(
rt, value.getProperty(rt, "processingStart"), jsInvoker),
bridging::fromJs<std::optional<double>>(
rt, value.getProperty(rt, "processingEnd"), jsInvoker),
bridging::fromJs<std::optional<double>>(
rt, value.getProperty(rt, "interactionId"), jsInvoker),
};
return result;
}
static jsi::Object toJs(jsi::Runtime &rt, const RawPerformanceEntry &value) {
auto result = facebook::jsi::Object(rt);
result.setProperty(rt, "name", bridging::toJs(rt, value.name));
result.setProperty(rt, "entryType", bridging::toJs(rt, value.entryType));
result.setProperty(rt, "startTime", bridging::toJs(rt, value.startTime));
result.setProperty(rt, "duration", bridging::toJs(rt, value.duration));
if (value.processingStart) {
result.setProperty(
rt,
"processingStart",
bridging::toJs(rt, value.processingStart.value()));
}
if (value.processingEnd) {
result.setProperty(
rt, "processingEnd", bridging::toJs(rt, value.processingEnd.value()));
}
if (value.interactionId) {
result.setProperty(
rt, "interactionId", bridging::toJs(rt, value.interactionId.value()));
}
return result;
}
};
} // namespace facebook::react
@@ -16,6 +16,7 @@ import type {
NativeModuleTypeAnnotation,
NativeModuleFunctionTypeAnnotation,
NativeModulePropertyShape,
NativeModuleAliasMap,
} from '../../CodegenSchema';
import type {AliasResolver} from './Utils';
@@ -28,8 +29,13 @@ type FilesOutput = Map<string, string>;
const ModuleClassDeclarationTemplate = ({
hasteModuleName,
moduleProperties,
}: $ReadOnly<{hasteModuleName: string, moduleProperties: string[]}>) => {
return `class JSI_EXPORT ${hasteModuleName}CxxSpecJSI : public TurboModule {
structs,
}: $ReadOnly<{
hasteModuleName: string,
moduleProperties: string[],
structs: string,
}>) => {
return `${structs}class JSI_EXPORT ${hasteModuleName}CxxSpecJSI : public TurboModule {
protected:
${hasteModuleName}CxxSpecJSI(std::shared_ptr<CallInvoker> jsInvoker);
@@ -186,6 +192,76 @@ function translatePrimitiveJSTypeToCpp(
}
}
function createStructs(
moduleName: string,
aliasMap: NativeModuleAliasMap,
resolveAlias: AliasResolver,
): string {
return Object.keys(aliasMap)
.map(alias => {
const value = aliasMap[alias];
if (value.properties.length === 0) {
return '';
}
const structName = `${moduleName}Base${alias}`;
const templateParameterWithTypename = value.properties
.map((v, i) => 'typename P' + i)
.join(', ');
const templateParameter = value.properties
.map((v, i) => 'P' + i)
.join(', ');
return `#pragma mark - ${structName}
template <${templateParameterWithTypename}>
struct ${structName} {
${value.properties.map((v, i) => ' P' + i + ' ' + v.name).join(';\n')};
bool operator==(const ${structName} &other) const {
return ${value.properties
.map(v => `${v.name} == other.${v.name}`)
.join(' && ')};
}
};
template <${templateParameterWithTypename}>
struct ${structName}Bridging {
static ${structName}<${templateParameter}> fromJs(
jsi::Runtime &rt,
const jsi::Object &value,
const std::shared_ptr<CallInvoker> &jsInvoker) {
${structName}<${templateParameter}> result{
${value.properties
.map(
(v, i) =>
` bridging::fromJs<P${i}>(rt, value.getProperty(rt, "${v.name}"), jsInvoker)`,
)
.join(',\n')}};
return result;
}
static jsi::Object toJs(
jsi::Runtime &rt,
const ${structName}<${templateParameter}> &value) {
auto result = facebook::jsi::Object(rt);
${value.properties
.map((v, i) => {
if (v.optional) {
return ` if (value.${v.name}) {
result.setProperty(rt, "${v.name}", bridging::toJs(rt, value.${v.name}.value()));
}`;
} else {
return ` result.setProperty(rt, "${v.name}", bridging::toJs(rt, value.${v.name}));`;
}
})
.join('\n')}
return result;
}
};
`;
})
.join('\n');
}
function translatePropertyToCpp(
prop: NativeModulePropertyShape,
resolveAlias: AliasResolver,
@@ -251,6 +327,7 @@ module.exports = {
moduleNames: [moduleName],
} = nativeModules[hasteModuleName];
const resolveAlias = createAliasResolver(aliases);
const structs = createStructs(moduleName, aliases, resolveAlias);
return [
ModuleClassDeclarationTemplate({
@@ -258,6 +335,7 @@ module.exports = {
moduleProperties: properties.map(prop =>
translatePropertyToCpp(prop, resolveAlias, true),
),
structs,
}),
ModuleSpecClassDeclarationTemplate({
hasteModuleName,
@@ -202,6 +202,36 @@ Map {
namespace facebook {
namespace react {
#pragma mark - SampleTurboModuleCxxBaseObjectAlias
template <typename P0>
struct SampleTurboModuleCxxBaseObjectAlias {
P0 x;
bool operator==(const SampleTurboModuleCxxBaseObjectAlias &other) const {
return x == other.x;
}
};
template <typename P0>
struct SampleTurboModuleCxxBaseObjectAliasBridging {
static SampleTurboModuleCxxBaseObjectAlias<P0> fromJs(
jsi::Runtime &rt,
const jsi::Object &value,
const std::shared_ptr<CallInvoker> &jsInvoker) {
SampleTurboModuleCxxBaseObjectAlias<P0> result{
bridging::fromJs<P0>(rt, value.getProperty(rt, \\"x\\"), jsInvoker)};
return result;
}
static jsi::Object toJs(
jsi::Runtime &rt,
const SampleTurboModuleCxxBaseObjectAlias<P0> &value) {
auto result = facebook::jsi::Object(rt);
result.setProperty(rt, \\"x\\", bridging::toJs(rt, value.x));
return result;
}
};
class JSI_EXPORT NativeSampleTurboModuleCxxSpecJSI : public TurboModule {
protected:
NativeSampleTurboModuleCxxSpecJSI(std::shared_ptr<CallInvoker> jsInvoker);
@@ -358,6 +388,54 @@ Map {
namespace facebook {
namespace react {
#pragma mark - AliasTurboModuleBaseOptions
template <typename P0, typename P1, typename P2, typename P3, typename P4>
struct AliasTurboModuleBaseOptions {
P0 offset;
P1 size;
P2 displaySize;
P3 resizeMode;
P4 allowExternalStorage;
bool operator==(const AliasTurboModuleBaseOptions &other) const {
return offset == other.offset && size == other.size && displaySize == other.displaySize && resizeMode == other.resizeMode && allowExternalStorage == other.allowExternalStorage;
}
};
template <typename P0, typename P1, typename P2, typename P3, typename P4>
struct AliasTurboModuleBaseOptionsBridging {
static AliasTurboModuleBaseOptions<P0, P1, P2, P3, P4> fromJs(
jsi::Runtime &rt,
const jsi::Object &value,
const std::shared_ptr<CallInvoker> &jsInvoker) {
AliasTurboModuleBaseOptions<P0, P1, P2, P3, P4> result{
bridging::fromJs<P0>(rt, value.getProperty(rt, \\"offset\\"), jsInvoker),
bridging::fromJs<P1>(rt, value.getProperty(rt, \\"size\\"), jsInvoker),
bridging::fromJs<P2>(rt, value.getProperty(rt, \\"displaySize\\"), jsInvoker),
bridging::fromJs<P3>(rt, value.getProperty(rt, \\"resizeMode\\"), jsInvoker),
bridging::fromJs<P4>(rt, value.getProperty(rt, \\"allowExternalStorage\\"), jsInvoker)};
return result;
}
static jsi::Object toJs(
jsi::Runtime &rt,
const AliasTurboModuleBaseOptions<P0, P1, P2, P3, P4> &value) {
auto result = facebook::jsi::Object(rt);
result.setProperty(rt, \\"offset\\", bridging::toJs(rt, value.offset));
result.setProperty(rt, \\"size\\", bridging::toJs(rt, value.size));
if (value.displaySize) {
result.setProperty(rt, \\"displaySize\\", bridging::toJs(rt, value.displaySize.value()));
}
if (value.resizeMode) {
result.setProperty(rt, \\"resizeMode\\", bridging::toJs(rt, value.resizeMode.value()));
}
if (value.allowExternalStorage) {
result.setProperty(rt, \\"allowExternalStorage\\", bridging::toJs(rt, value.allowExternalStorage.value()));
}
return result;
}
};
class JSI_EXPORT AliasTurboModuleCxxSpecJSI : public TurboModule {
protected:
AliasTurboModuleCxxSpecJSI(std::shared_ptr<CallInvoker> jsInvoker);
@@ -435,6 +513,179 @@ Map {
namespace facebook {
namespace react {
#pragma mark - CameraRollManagerBasePhotoIdentifierImage
template <typename P0, typename P1, typename P2, typename P3, typename P4, typename P5>
struct CameraRollManagerBasePhotoIdentifierImage {
P0 uri;
P1 playableDuration;
P2 width;
P3 height;
P4 isStored;
P5 filename;
bool operator==(const CameraRollManagerBasePhotoIdentifierImage &other) const {
return uri == other.uri && playableDuration == other.playableDuration && width == other.width && height == other.height && isStored == other.isStored && filename == other.filename;
}
};
template <typename P0, typename P1, typename P2, typename P3, typename P4, typename P5>
struct CameraRollManagerBasePhotoIdentifierImageBridging {
static CameraRollManagerBasePhotoIdentifierImage<P0, P1, P2, P3, P4, P5> fromJs(
jsi::Runtime &rt,
const jsi::Object &value,
const std::shared_ptr<CallInvoker> &jsInvoker) {
CameraRollManagerBasePhotoIdentifierImage<P0, P1, P2, P3, P4, P5> result{
bridging::fromJs<P0>(rt, value.getProperty(rt, \\"uri\\"), jsInvoker),
bridging::fromJs<P1>(rt, value.getProperty(rt, \\"playableDuration\\"), jsInvoker),
bridging::fromJs<P2>(rt, value.getProperty(rt, \\"width\\"), jsInvoker),
bridging::fromJs<P3>(rt, value.getProperty(rt, \\"height\\"), jsInvoker),
bridging::fromJs<P4>(rt, value.getProperty(rt, \\"isStored\\"), jsInvoker),
bridging::fromJs<P5>(rt, value.getProperty(rt, \\"filename\\"), jsInvoker)};
return result;
}
static jsi::Object toJs(
jsi::Runtime &rt,
const CameraRollManagerBasePhotoIdentifierImage<P0, P1, P2, P3, P4, P5> &value) {
auto result = facebook::jsi::Object(rt);
result.setProperty(rt, \\"uri\\", bridging::toJs(rt, value.uri));
result.setProperty(rt, \\"playableDuration\\", bridging::toJs(rt, value.playableDuration));
result.setProperty(rt, \\"width\\", bridging::toJs(rt, value.width));
result.setProperty(rt, \\"height\\", bridging::toJs(rt, value.height));
if (value.isStored) {
result.setProperty(rt, \\"isStored\\", bridging::toJs(rt, value.isStored.value()));
}
result.setProperty(rt, \\"filename\\", bridging::toJs(rt, value.filename));
return result;
}
};
#pragma mark - CameraRollManagerBasePhotoIdentifier
template <typename P0>
struct CameraRollManagerBasePhotoIdentifier {
P0 node;
bool operator==(const CameraRollManagerBasePhotoIdentifier &other) const {
return node == other.node;
}
};
template <typename P0>
struct CameraRollManagerBasePhotoIdentifierBridging {
static CameraRollManagerBasePhotoIdentifier<P0> fromJs(
jsi::Runtime &rt,
const jsi::Object &value,
const std::shared_ptr<CallInvoker> &jsInvoker) {
CameraRollManagerBasePhotoIdentifier<P0> result{
bridging::fromJs<P0>(rt, value.getProperty(rt, \\"node\\"), jsInvoker)};
return result;
}
static jsi::Object toJs(
jsi::Runtime &rt,
const CameraRollManagerBasePhotoIdentifier<P0> &value) {
auto result = facebook::jsi::Object(rt);
result.setProperty(rt, \\"node\\", bridging::toJs(rt, value.node));
return result;
}
};
#pragma mark - CameraRollManagerBasePhotoIdentifiersPage
template <typename P0, typename P1>
struct CameraRollManagerBasePhotoIdentifiersPage {
P0 edges;
P1 page_info;
bool operator==(const CameraRollManagerBasePhotoIdentifiersPage &other) const {
return edges == other.edges && page_info == other.page_info;
}
};
template <typename P0, typename P1>
struct CameraRollManagerBasePhotoIdentifiersPageBridging {
static CameraRollManagerBasePhotoIdentifiersPage<P0, P1> fromJs(
jsi::Runtime &rt,
const jsi::Object &value,
const std::shared_ptr<CallInvoker> &jsInvoker) {
CameraRollManagerBasePhotoIdentifiersPage<P0, P1> result{
bridging::fromJs<P0>(rt, value.getProperty(rt, \\"edges\\"), jsInvoker),
bridging::fromJs<P1>(rt, value.getProperty(rt, \\"page_info\\"), jsInvoker)};
return result;
}
static jsi::Object toJs(
jsi::Runtime &rt,
const CameraRollManagerBasePhotoIdentifiersPage<P0, P1> &value) {
auto result = facebook::jsi::Object(rt);
result.setProperty(rt, \\"edges\\", bridging::toJs(rt, value.edges));
result.setProperty(rt, \\"page_info\\", bridging::toJs(rt, value.page_info));
return result;
}
};
#pragma mark - CameraRollManagerBaseGetPhotosParams
template <typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>
struct CameraRollManagerBaseGetPhotosParams {
P0 first;
P1 after;
P2 groupName;
P3 groupTypes;
P4 assetType;
P5 maxSize;
P6 mimeTypes;
bool operator==(const CameraRollManagerBaseGetPhotosParams &other) const {
return first == other.first && after == other.after && groupName == other.groupName && groupTypes == other.groupTypes && assetType == other.assetType && maxSize == other.maxSize && mimeTypes == other.mimeTypes;
}
};
template <typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>
struct CameraRollManagerBaseGetPhotosParamsBridging {
static CameraRollManagerBaseGetPhotosParams<P0, P1, P2, P3, P4, P5, P6> fromJs(
jsi::Runtime &rt,
const jsi::Object &value,
const std::shared_ptr<CallInvoker> &jsInvoker) {
CameraRollManagerBaseGetPhotosParams<P0, P1, P2, P3, P4, P5, P6> result{
bridging::fromJs<P0>(rt, value.getProperty(rt, \\"first\\"), jsInvoker),
bridging::fromJs<P1>(rt, value.getProperty(rt, \\"after\\"), jsInvoker),
bridging::fromJs<P2>(rt, value.getProperty(rt, \\"groupName\\"), jsInvoker),
bridging::fromJs<P3>(rt, value.getProperty(rt, \\"groupTypes\\"), jsInvoker),
bridging::fromJs<P4>(rt, value.getProperty(rt, \\"assetType\\"), jsInvoker),
bridging::fromJs<P5>(rt, value.getProperty(rt, \\"maxSize\\"), jsInvoker),
bridging::fromJs<P6>(rt, value.getProperty(rt, \\"mimeTypes\\"), jsInvoker)};
return result;
}
static jsi::Object toJs(
jsi::Runtime &rt,
const CameraRollManagerBaseGetPhotosParams<P0, P1, P2, P3, P4, P5, P6> &value) {
auto result = facebook::jsi::Object(rt);
result.setProperty(rt, \\"first\\", bridging::toJs(rt, value.first));
if (value.after) {
result.setProperty(rt, \\"after\\", bridging::toJs(rt, value.after.value()));
}
if (value.groupName) {
result.setProperty(rt, \\"groupName\\", bridging::toJs(rt, value.groupName.value()));
}
if (value.groupTypes) {
result.setProperty(rt, \\"groupTypes\\", bridging::toJs(rt, value.groupTypes.value()));
}
if (value.assetType) {
result.setProperty(rt, \\"assetType\\", bridging::toJs(rt, value.assetType.value()));
}
if (value.maxSize) {
result.setProperty(rt, \\"maxSize\\", bridging::toJs(rt, value.maxSize.value()));
}
if (value.mimeTypes) {
result.setProperty(rt, \\"mimeTypes\\", bridging::toJs(rt, value.mimeTypes.value()));
}
return result;
}
};
class JSI_EXPORT NativeCameraRollManagerCxxSpecJSI : public TurboModule {
protected:
NativeCameraRollManagerCxxSpecJSI(std::shared_ptr<CallInvoker> jsInvoker);
@@ -505,6 +756,108 @@ private:
Delegate delegate_;
};
#pragma mark - ExceptionsManagerBaseStackFrame
template <typename P0, typename P1, typename P2, typename P3, typename P4>
struct ExceptionsManagerBaseStackFrame {
P0 column;
P1 file;
P2 lineNumber;
P3 methodName;
P4 collapse;
bool operator==(const ExceptionsManagerBaseStackFrame &other) const {
return column == other.column && file == other.file && lineNumber == other.lineNumber && methodName == other.methodName && collapse == other.collapse;
}
};
template <typename P0, typename P1, typename P2, typename P3, typename P4>
struct ExceptionsManagerBaseStackFrameBridging {
static ExceptionsManagerBaseStackFrame<P0, P1, P2, P3, P4> fromJs(
jsi::Runtime &rt,
const jsi::Object &value,
const std::shared_ptr<CallInvoker> &jsInvoker) {
ExceptionsManagerBaseStackFrame<P0, P1, P2, P3, P4> result{
bridging::fromJs<P0>(rt, value.getProperty(rt, \\"column\\"), jsInvoker),
bridging::fromJs<P1>(rt, value.getProperty(rt, \\"file\\"), jsInvoker),
bridging::fromJs<P2>(rt, value.getProperty(rt, \\"lineNumber\\"), jsInvoker),
bridging::fromJs<P3>(rt, value.getProperty(rt, \\"methodName\\"), jsInvoker),
bridging::fromJs<P4>(rt, value.getProperty(rt, \\"collapse\\"), jsInvoker)};
return result;
}
static jsi::Object toJs(
jsi::Runtime &rt,
const ExceptionsManagerBaseStackFrame<P0, P1, P2, P3, P4> &value) {
auto result = facebook::jsi::Object(rt);
if (value.column) {
result.setProperty(rt, \\"column\\", bridging::toJs(rt, value.column.value()));
}
result.setProperty(rt, \\"file\\", bridging::toJs(rt, value.file));
if (value.lineNumber) {
result.setProperty(rt, \\"lineNumber\\", bridging::toJs(rt, value.lineNumber.value()));
}
result.setProperty(rt, \\"methodName\\", bridging::toJs(rt, value.methodName));
if (value.collapse) {
result.setProperty(rt, \\"collapse\\", bridging::toJs(rt, value.collapse.value()));
}
return result;
}
};
#pragma mark - ExceptionsManagerBaseExceptionData
template <typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>
struct ExceptionsManagerBaseExceptionData {
P0 message;
P1 originalMessage;
P2 name;
P3 componentStack;
P4 stack;
P5 id;
P6 isFatal;
P7 extraData;
bool operator==(const ExceptionsManagerBaseExceptionData &other) const {
return message == other.message && originalMessage == other.originalMessage && name == other.name && componentStack == other.componentStack && stack == other.stack && id == other.id && isFatal == other.isFatal && extraData == other.extraData;
}
};
template <typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>
struct ExceptionsManagerBaseExceptionDataBridging {
static ExceptionsManagerBaseExceptionData<P0, P1, P2, P3, P4, P5, P6, P7> fromJs(
jsi::Runtime &rt,
const jsi::Object &value,
const std::shared_ptr<CallInvoker> &jsInvoker) {
ExceptionsManagerBaseExceptionData<P0, P1, P2, P3, P4, P5, P6, P7> result{
bridging::fromJs<P0>(rt, value.getProperty(rt, \\"message\\"), jsInvoker),
bridging::fromJs<P1>(rt, value.getProperty(rt, \\"originalMessage\\"), jsInvoker),
bridging::fromJs<P2>(rt, value.getProperty(rt, \\"name\\"), jsInvoker),
bridging::fromJs<P3>(rt, value.getProperty(rt, \\"componentStack\\"), jsInvoker),
bridging::fromJs<P4>(rt, value.getProperty(rt, \\"stack\\"), jsInvoker),
bridging::fromJs<P5>(rt, value.getProperty(rt, \\"id\\"), jsInvoker),
bridging::fromJs<P6>(rt, value.getProperty(rt, \\"isFatal\\"), jsInvoker),
bridging::fromJs<P7>(rt, value.getProperty(rt, \\"extraData\\"), jsInvoker)};
return result;
}
static jsi::Object toJs(
jsi::Runtime &rt,
const ExceptionsManagerBaseExceptionData<P0, P1, P2, P3, P4, P5, P6, P7> &value) {
auto result = facebook::jsi::Object(rt);
result.setProperty(rt, \\"message\\", bridging::toJs(rt, value.message));
result.setProperty(rt, \\"originalMessage\\", bridging::toJs(rt, value.originalMessage));
result.setProperty(rt, \\"name\\", bridging::toJs(rt, value.name));
result.setProperty(rt, \\"componentStack\\", bridging::toJs(rt, value.componentStack));
result.setProperty(rt, \\"stack\\", bridging::toJs(rt, value.stack));
result.setProperty(rt, \\"id\\", bridging::toJs(rt, value.id));
result.setProperty(rt, \\"isFatal\\", bridging::toJs(rt, value.isFatal));
if (value.extraData) {
result.setProperty(rt, \\"extraData\\", bridging::toJs(rt, value.extraData.value()));
}
return result;
}
};
class JSI_EXPORT NativeExceptionsManagerCxxSpecJSI : public TurboModule {
protected:
NativeExceptionsManagerCxxSpecJSI(std::shared_ptr<CallInvoker> jsInvoker);
@@ -18,12 +18,42 @@
#include <set>
#include <string>
#include <vector>
#include "NativeCxxModuleExample_ConstantsStruct.h"
#include "NativeCxxModuleExample_ObjectStruct.h"
#include "NativeCxxModuleExample_ValueStruct.h"
namespace facebook::react {
#pragma mark - Structs
using ConstantsStruct =
NativeCxxModuleExampleCxxBaseConstantsStruct<bool, int32_t, std::string>;
template <>
struct Bridging<ConstantsStruct>
: NativeCxxModuleExampleCxxBaseConstantsStructBridging<
bool,
int32_t,
std::string> {};
using ObjectStruct = NativeCxxModuleExampleCxxBaseObjectStruct<
int32_t,
std::string,
std::optional<std::string>>;
template <>
struct Bridging<ObjectStruct>
: NativeCxxModuleExampleCxxBaseObjectStructBridging<
int32_t,
std::string,
std::optional<std::string>> {};
using ValueStruct =
NativeCxxModuleExampleCxxBaseValueStruct<double, std::string, ObjectStruct>;
template <>
struct Bridging<ValueStruct> : NativeCxxModuleExampleCxxBaseValueStructBridging<
double,
std::string,
ObjectStruct> {};
#pragma mark - implementation
class NativeCxxModuleExample
: public NativeCxxModuleExampleCxxSpec<NativeCxxModuleExample> {
public:
@@ -1,37 +0,0 @@
/*
* Copyright (c) Meta Platforms, Inc. and 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 <react/bridging/Bridging.h>
#include <optional>
#include <string>
namespace facebook::react {
struct ConstantsStruct {
bool const1;
int32_t const2;
std::string const3;
bool operator==(const ConstantsStruct &other) const {
return const1 == other.const1 && const2 == other.const2 &&
const3 == other.const3;
}
};
template <>
struct Bridging<ConstantsStruct> {
static jsi::Object toJs(jsi::Runtime &rt, const ConstantsStruct &value) {
auto result = facebook::jsi::Object(rt);
result.setProperty(rt, "const1", bridging::toJs(rt, value.const1));
result.setProperty(rt, "const2", bridging::toJs(rt, value.const2));
result.setProperty(rt, "const3", bridging::toJs(rt, value.const3));
return result;
}
};
} // namespace facebook::react
@@ -1,52 +0,0 @@
/*
* Copyright (c) Meta Platforms, Inc. and 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 <react/bridging/Bridging.h>
#include <optional>
#include <string>
namespace facebook::react {
struct ObjectStruct {
int32_t a;
std::string b;
std::optional<std::string> c;
bool operator==(const ObjectStruct &other) const {
return a == other.a && b == other.b && c == other.c;
}
};
template <>
struct Bridging<ObjectStruct> {
static ObjectStruct fromJs(
jsi::Runtime &rt,
const jsi::Object &value,
const std::shared_ptr<CallInvoker> &jsInvoker) {
ObjectStruct result{
bridging::fromJs<int32_t>(rt, value.getProperty(rt, "a"), jsInvoker),
bridging::fromJs<std::string>(
rt, value.getProperty(rt, "b"), jsInvoker),
bridging::fromJs<std::optional<std::string>>(
rt, value.getProperty(rt, "c"), jsInvoker)};
return result;
}
static jsi::Object toJs(jsi::Runtime &rt, const ObjectStruct &value) {
auto result = facebook::jsi::Object(rt);
result.setProperty(rt, "a", bridging::toJs(rt, value.a));
result.setProperty(rt, "b", bridging::toJs(rt, value.b));
if (value.c) {
result.setProperty(rt, "c", bridging::toJs(rt, value.c.value()));
}
return result;
}
};
} // namespace facebook::react
@@ -1,50 +0,0 @@
/*
* Copyright (c) Meta Platforms, Inc. and 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 <react/bridging/Bridging.h>
#include <optional>
#include <string>
#include "NativeCxxModuleExample_ObjectStruct.h"
namespace facebook::react {
struct ValueStruct {
double x;
std::string y;
ObjectStruct z;
bool operator==(const ValueStruct &other) const {
return x == other.x && y == other.y && z == other.z;
}
};
template <>
struct Bridging<ValueStruct> {
static ValueStruct fromJs(
jsi::Runtime &rt,
const jsi::Object &value,
const std::shared_ptr<CallInvoker> &jsInvoker) {
ValueStruct result{
bridging::fromJs<double>(rt, value.getProperty(rt, "x"), jsInvoker),
bridging::fromJs<std::string>(
rt, value.getProperty(rt, "y"), jsInvoker),
bridging::fromJs<ObjectStruct>(
rt, value.getProperty(rt, "z"), jsInvoker)};
return result;
}
static jsi::Object toJs(jsi::Runtime &rt, const ValueStruct &value) {
auto result = facebook::jsi::Object(rt);
result.setProperty(rt, "x", bridging::toJs(rt, value.x));
result.setProperty(rt, "y", bridging::toJs(rt, value.y));
result.setProperty(rt, "z", bridging::toJs(rt, value.z));
return result;
}
};
} // namespace facebook::react