From 5754b4a123fb51e72cb6df110a588fa956561ac3 Mon Sep 17 00:00:00 2001 From: Christoph Purrer Date: Mon, 4 Dec 2023 04:19:47 -0800 Subject: [PATCH] Add GraphNode example for Cxx TMs (#41766) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/41766 Changelog: [Internal] Adds a simple example showing a recursive node, stored inside a collection in a Cxx TM. Currently we can't auto-generate [the necessary C++ Types](https://reactnative.dev/docs/next/the-new-architecture/cxx-custom-types#struct-generator) - but we can add it later if this scenarios becomes really common. Reviewed By: rshest Differential Revision: D51783974 fbshipit-source-id: 7352db1a354cd7da32febc650f7cc5e10dd16d2d --- .../NativeCxxModuleExample.cpp | 10 +++++ .../NativeCxxModuleExample.h | 38 +++++++++++++++++++ .../NativeCxxModuleExample.js | 6 +++ .../NativeCxxModuleExampleExample.js | 7 ++++ 4 files changed, 61 insertions(+) diff --git a/packages/rn-tester/NativeCxxModuleExample/NativeCxxModuleExample.cpp b/packages/rn-tester/NativeCxxModuleExample/NativeCxxModuleExample.cpp index 78f45f47ef651f..29a547955154ed 100644 --- a/packages/rn-tester/NativeCxxModuleExample/NativeCxxModuleExample.cpp +++ b/packages/rn-tester/NativeCxxModuleExample/NativeCxxModuleExample.cpp @@ -65,6 +65,16 @@ std::string NativeCxxModuleExample::consumeCustomHostObject( return value->a_ + std::to_string(value->b_); } +GraphNode NativeCxxModuleExample::getGraphNode( + jsi::Runtime& rt, + GraphNode arg) { + if (arg.neighbors) { + arg.neighbors->emplace_back(GraphNode{.label = "top"}); + arg.neighbors->emplace_back(GraphNode{.label = "down"}); + } + return arg; +} + NativeCxxModuleExampleCxxEnumFloat NativeCxxModuleExample::getNumEnum( jsi::Runtime& rt, NativeCxxModuleExampleCxxEnumInt arg) { diff --git a/packages/rn-tester/NativeCxxModuleExample/NativeCxxModuleExample.h b/packages/rn-tester/NativeCxxModuleExample/NativeCxxModuleExample.h index ed2e3aaaf91c69..10fe5d50f7cd16 100644 --- a/packages/rn-tester/NativeCxxModuleExample/NativeCxxModuleExample.h +++ b/packages/rn-tester/NativeCxxModuleExample/NativeCxxModuleExample.h @@ -90,6 +90,42 @@ struct CustomHostObjectRef { using CustomHostObject = HostObjectWrapper; +#pragma mark - recursive objects +struct GraphNode { + std::string label; + std::optional> neighbors; +}; + +template <> +struct Bridging { + static GraphNode fromJs( + jsi::Runtime& rt, + const jsi::Object& value, + const std::shared_ptr& jsInvoker) { + GraphNode result{ + bridging::fromJs( + rt, value.getProperty(rt, "label"), jsInvoker), + bridging::fromJs>>( + rt, value.getProperty(rt, "neighbors"), jsInvoker)}; + return result; + } + + static jsi::Object toJs( + jsi::Runtime& rt, + const GraphNode value, + const std::shared_ptr& jsInvoker) { + auto result = facebook::jsi::Object(rt); + result.setProperty(rt, "label", bridging::toJs(rt, value.label, jsInvoker)); + if (value.neighbors) { + result.setProperty( + rt, + "neighbors", + bridging::toJs(rt, value.neighbors.value(), jsInvoker)); + } + return result; + } +}; + #pragma mark - implementation class NativeCxxModuleExample : public NativeCxxModuleExampleCxxSpec { @@ -120,6 +156,8 @@ class NativeCxxModuleExample jsi::Runtime& rt, std::shared_ptr arg); + GraphNode getGraphNode(jsi::Runtime& rt, GraphNode arg); + NativeCxxModuleExampleCxxEnumFloat getNumEnum( jsi::Runtime& rt, NativeCxxModuleExampleCxxEnumInt arg); diff --git a/packages/rn-tester/NativeCxxModuleExample/NativeCxxModuleExample.js b/packages/rn-tester/NativeCxxModuleExample/NativeCxxModuleExample.js index 29936c5ca051fe..0ce33d72b4f16d 100644 --- a/packages/rn-tester/NativeCxxModuleExample/NativeCxxModuleExample.js +++ b/packages/rn-tester/NativeCxxModuleExample/NativeCxxModuleExample.js @@ -56,6 +56,11 @@ export type ValueStruct = {| export type CustomHostObject = {}; +export type GraphNode = { + label: string, + neighbors?: Array, +}; + export interface Spec extends TurboModule { +getArray: (arg: Array) => Array; +getBool: (arg: boolean) => boolean; @@ -63,6 +68,7 @@ export interface Spec extends TurboModule { +getCustomEnum: (arg: EnumInt) => EnumInt; +getCustomHostObject: () => CustomHostObject; +consumeCustomHostObject: (customHostObject: CustomHostObject) => string; + +getGraphNode: (arg: GraphNode) => GraphNode; +getNumEnum: (arg: EnumInt) => EnumFloat; +getStrEnum: (arg: EnumNone) => EnumStr; +getMap: (arg: {[key: string]: ?number}) => {[key: string]: ?number}; diff --git a/packages/rn-tester/js/examples/TurboModule/NativeCxxModuleExampleExample.js b/packages/rn-tester/js/examples/TurboModule/NativeCxxModuleExampleExample.js index 189c3a5fd21475..fe1567344c0425 100644 --- a/packages/rn-tester/js/examples/TurboModule/NativeCxxModuleExampleExample.js +++ b/packages/rn-tester/js/examples/TurboModule/NativeCxxModuleExampleExample.js @@ -42,6 +42,8 @@ type Examples = | 'getBool' | 'getConstants' | 'getCustomEnum' + | 'getCustomHostObject' + | 'getGraphNode' | 'getNumEnum' | 'getStrEnum' | 'getMap' @@ -102,6 +104,11 @@ class NativeCxxModuleExampleExample extends React.Component<{||}, State> { NativeCxxModuleExample?.consumeCustomHostObject( NativeCxxModuleExample?.getCustomHostObject(), ), + getGraphNode: () => + NativeCxxModuleExample?.getGraphNode({ + label: 'root', + neighbors: [{label: 'left'}, {label: 'right'}], + }), getNumEnum: () => NativeCxxModuleExample?.getNumEnum(EnumInt.IB), getStrEnum: () => NativeCxxModuleExample?.getStrEnum(EnumNone.NB), getNumber: () => NativeCxxModuleExample?.getNumber(99.95),