-
Notifications
You must be signed in to change notification settings - Fork 24.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
react-native code-gen > Add a C++ only TurboModule example (for Andro…
…id/iOS/macOS/Windows) (#35138) Summary: Pull Request resolved: #35138 Changelog: [General][Added] - Add a C++ only TurboModule example (for Android/iOS/macOS/Windows) react-native@0.69 introduced a new bridging layer to ease integration for pure C++ TurboModules using C++ std:: types directly instead of the lower level jsi:: types: https://github.com/facebook/react-native/tree/v0.69.0/ReactCommon/react/bridging This bridging layer can be used in JSI functions or more conveniently in C++ TurboModules. Here is a example of an C++ only TurboModule which will work on Android and iOS and macOS/Windows (using microsoft/react-native-macos|windows) only using flow/TypeScript and standard C++ types. C++ only TurboModules are very handy as they do not require to work with JSI APIs - instead std:: or custom C++ can by used. Differential Revision: D39011736 fbshipit-source-id: d4ed6cecc00dafd1f478e4d3ea58611231635772
- Loading branch information
1 parent
87c356d
commit 9daa506
Showing
13 changed files
with
707 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
110 changes: 110 additions & 0 deletions
110
packages/rn-tester/NativeModuleExampleCxx/NativeModuleExampleCxx.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
/* | ||
* 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. | ||
*/ | ||
|
||
#include "NativeModuleExampleCxx.h" | ||
|
||
namespace facebook::react { | ||
|
||
NativeModuleExampleCxx::NativeModuleExampleCxx( | ||
std::shared_ptr<CallInvoker> jsInvoker) | ||
: NativeModuleExampleCxxCxxSpec(std::move(jsInvoker)) {} | ||
|
||
void NativeModuleExampleCxx::getValueWithCallback( | ||
jsi::Runtime &rt, | ||
AsyncCallback<std::string> callback) { | ||
callback({"value from callback!"}); | ||
} | ||
|
||
std::vector<std::optional<ObjectStruct>> NativeModuleExampleCxx::getArray( | ||
jsi::Runtime &rt, | ||
std::vector<std::optional<ObjectStruct>> arg) { | ||
return arg; | ||
} | ||
|
||
bool NativeModuleExampleCxx::getBool(jsi::Runtime &rt, bool arg) { | ||
return arg; | ||
} | ||
|
||
ConstantsStruct NativeModuleExampleCxx::getConstants(jsi::Runtime &rt) { | ||
return ConstantsStruct{true, 69, "react-native"}; | ||
} | ||
|
||
int32_t NativeModuleExampleCxx::getEnum(jsi::Runtime &rt, int32_t arg) { | ||
return arg; | ||
} | ||
|
||
std::map<std::string, std::optional<int32_t>> NativeModuleExampleCxx::getMap( | ||
jsi::Runtime &rt, | ||
std::map<std::string, std::optional<int32_t>> arg) { | ||
return arg; | ||
} | ||
|
||
double NativeModuleExampleCxx::getNumber(jsi::Runtime &rt, double arg) { | ||
return arg; | ||
} | ||
|
||
ObjectStruct NativeModuleExampleCxx::getObject( | ||
jsi::Runtime &rt, | ||
ObjectStruct arg) { | ||
return arg; | ||
} | ||
|
||
std::set<float> NativeModuleExampleCxx::getSet( | ||
jsi::Runtime &rt, | ||
std::set<float> arg) { | ||
return arg; | ||
} | ||
|
||
std::string NativeModuleExampleCxx::getString( | ||
jsi::Runtime &rt, | ||
std::string arg) { | ||
return arg; | ||
} | ||
|
||
std::string NativeModuleExampleCxx::getUnion( | ||
jsi::Runtime &rt, | ||
float x, | ||
std::string y, | ||
jsi::Object z) { | ||
std::string result = "x: " + std::to_string(x) + ", y: " + y + ", z: { "; | ||
if (z.hasProperty(rt, "value")) { | ||
result += "value: "; | ||
result += std::to_string(z.getProperty(rt, "value").getNumber()); | ||
} else if (z.hasProperty(rt, "low")) { | ||
result += "low: "; | ||
result += z.getProperty(rt, "low").getString(rt).utf8(rt); | ||
} | ||
result += " }"; | ||
return result; | ||
} | ||
|
||
ValueStruct NativeModuleExampleCxx::getValue( | ||
jsi::Runtime &rt, | ||
double x, | ||
std::string y, | ||
ObjectStruct z) { | ||
ValueStruct result{x, y, z}; | ||
return result; | ||
} | ||
|
||
AsyncPromise<std::string> NativeModuleExampleCxx::getValueWithPromise( | ||
jsi::Runtime &rt, | ||
bool error) { | ||
auto promise = AsyncPromise<std::string>(rt, jsInvoker_); | ||
if (error) { | ||
promise.reject("intentional promise rejection"); | ||
} else { | ||
promise.resolve("result!"); | ||
} | ||
return promise; | ||
} | ||
|
||
void NativeModuleExampleCxx::voidFunc(jsi::Runtime &rt) { | ||
// Nothing to do | ||
} | ||
|
||
} // namespace facebook::react |
62 changes: 62 additions & 0 deletions
62
packages/rn-tester/NativeModuleExampleCxx/NativeModuleExampleCxx.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
/* | ||
* 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 <NativeModuleExampleCxxSpec/NativeModuleExampleCxxSpecJSI.h> | ||
#include <memory> | ||
#include <set> | ||
#include <string> | ||
#include <vector> | ||
#include "NativeModuleExampleCxx_ConstantsStruct.h" | ||
#include "NativeModuleExampleCxx_ObjectStruct.h" | ||
#include "NativeModuleExampleCxx_ValueStruct.h" | ||
|
||
namespace facebook::react { | ||
|
||
class NativeModuleExampleCxx | ||
: public NativeModuleExampleCxxCxxSpec<NativeModuleExampleCxx> { | ||
public: | ||
NativeModuleExampleCxx(std::shared_ptr<CallInvoker> jsInvoker); | ||
|
||
void getValueWithCallback( | ||
jsi::Runtime &rt, | ||
AsyncCallback<std::string> callback); | ||
|
||
std::vector<std::optional<ObjectStruct>> getArray( | ||
jsi::Runtime &rt, | ||
std::vector<std::optional<ObjectStruct>> arg); | ||
|
||
bool getBool(jsi::Runtime &rt, bool arg); | ||
|
||
ConstantsStruct getConstants(jsi::Runtime &rt); | ||
|
||
int32_t getEnum(jsi::Runtime &rt, int32_t arg); | ||
|
||
std::map<std::string, std::optional<int32_t>> getMap( | ||
jsi::Runtime &rt, | ||
std::map<std::string, std::optional<int32_t>> arg); | ||
|
||
double getNumber(jsi::Runtime &rt, double arg); | ||
|
||
ObjectStruct getObject(jsi::Runtime &rt, ObjectStruct arg); | ||
|
||
std::set<float> getSet(jsi::Runtime &rt, std::set<float> arg); | ||
|
||
std::string getString(jsi::Runtime &rt, std::string arg); | ||
|
||
std::string getUnion(jsi::Runtime &rt, float x, std::string y, jsi::Object z); | ||
|
||
ValueStruct | ||
getValue(jsi::Runtime &rt, double x, std::string y, ObjectStruct z); | ||
|
||
AsyncPromise<std::string> getValueWithPromise(jsi::Runtime &rt, bool error); | ||
|
||
void voidFunc(jsi::Runtime &rt); | ||
}; | ||
|
||
} // namespace facebook::react |
57 changes: 57 additions & 0 deletions
57
packages/rn-tester/NativeModuleExampleCxx/NativeModuleExampleCxx.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
/** | ||
* 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. | ||
* | ||
* @flow strict-local | ||
* @format | ||
*/ | ||
|
||
import type {TurboModule} from 'react-native/Libraries/TurboModule/RCTExport'; | ||
|
||
import {TurboModuleRegistry} from 'react-native'; | ||
|
||
export enum EnumInt { | ||
A = 23, | ||
B = 42, | ||
} | ||
|
||
export type UnionFloat = 1.44 | 2.88 | 5.76; | ||
export type UnionString = 'One' | 'Two' | 'Three'; | ||
export type UnionObject = {value: number} | {low: string}; | ||
|
||
export type ObjectStruct = $ReadOnly<{ | ||
a: number, | ||
b: string, | ||
c?: ?string, | ||
}>; | ||
|
||
export type ValueStruct = $ReadOnly<{ | ||
x: number, | ||
y: string, | ||
z: ObjectStruct, | ||
}>; | ||
|
||
export interface Spec extends TurboModule { | ||
+getArray: (arg: Array<ObjectStruct | null>) => Array<ObjectStruct | null>; | ||
+getBool: (arg: boolean) => boolean; | ||
+getConstants: () => {| | ||
const1: boolean, | ||
const2: number, | ||
const3: string, | ||
|}; | ||
+getEnum: (arg: EnumInt) => EnumInt; | ||
+getMap: (arg: {[key: string]: ?number}) => {[key: string]: ?number}; | ||
+getNumber: (arg: number) => number; | ||
+getObject: (arg: ObjectStruct) => ObjectStruct; | ||
+getSet: (arg: Array<number>) => Array<number>; | ||
+getString: (arg: string) => string; | ||
+getUnion: (x: UnionFloat, y: UnionString, z: UnionObject) => string; | ||
+getValue: (x: number, y: string, z: ObjectStruct) => ObjectStruct; | ||
+getValueWithCallback: (callback: (value: string) => void) => void; | ||
+getValueWithPromise: (error: boolean) => Promise<string>; | ||
+voidFunc: () => void; | ||
} | ||
|
||
export default (TurboModuleRegistry.get<Spec>('NativeModuleExampleCxx'): ?Spec); |
35 changes: 35 additions & 0 deletions
35
packages/rn-tester/NativeModuleExampleCxx/NativeModuleExampleCxx.podspec
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
# 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. | ||
|
||
require "json" | ||
|
||
package = JSON.parse(File.read(File.join(__dir__, "../package.json"))) | ||
|
||
Pod::Spec.new do |s| | ||
s.name = "NativeModuleExampleCxx" | ||
s.version = package["version"] | ||
s.summary = package["description"] | ||
s.description = "NativeModuleExampleCxx" | ||
s.homepage = "https://github.com/facebook/react-native.git" | ||
s.license = "MIT" | ||
s.platforms = { :ios => "12.4" } | ||
s.compiler_flags = '-Wno-nullability-completeness' | ||
s.author = "Facebook, Inc. and its affiliates" | ||
s.source = { :git => "https://github.com/facebook/react-native.git", :tag => "#{s.version}" } | ||
|
||
s.source_files = "**/*.{h,cpp}" | ||
s.requires_arc = true | ||
|
||
install_modules_dependencies(s) | ||
|
||
# s.dependency "..." | ||
|
||
# Enable codegen for this library | ||
use_react_native_codegen!(s, { | ||
:react_native_path => "../../..", | ||
:js_srcs_dir => "./", | ||
:library_type => "modules", | ||
}) | ||
end |
37 changes: 37 additions & 0 deletions
37
packages/rn-tester/NativeModuleExampleCxx/NativeModuleExampleCxx_ConstantsStruct.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
/* | ||
* 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 |
Oops, something went wrong.