-
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. Reviewed By: javache Differential Revision: D39011736 fbshipit-source-id: 84c833d8540671fde8505f1aeb0265074b248730
- Loading branch information
1 parent
bbb3a61
commit d07575b
Showing
17 changed files
with
745 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
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,29 @@ | ||
# 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. | ||
|
||
cmake_minimum_required(VERSION 3.13) | ||
set(CMAKE_VERBOSE_MAKEFILE on) | ||
|
||
add_compile_options( | ||
-fexceptions | ||
-frtti | ||
-std=c++17 | ||
-Wall | ||
-Wpedantic | ||
-Wno-gnu-zero-variadic-macro-arguments | ||
-DFOLLY_NO_CONFIG=1 | ||
-DLOG_TAG=\"ReactNative\") | ||
|
||
file(GLOB nativecxxmoduleexample_SRC CONFIGURE_DEPENDS *.cpp) | ||
add_library(nativecxxmoduleexample STATIC ${nativecxxmoduleexample_SRC}) | ||
|
||
target_include_directories(nativecxxmoduleexample PUBLIC .) | ||
target_include_directories(react_codegen_AppSpecs PUBLIC .) | ||
|
||
target_link_libraries(nativecxxmoduleexample | ||
fbjni | ||
jsi | ||
react_nativemodule_core | ||
react_codegen_AppSpecs) |
110 changes: 110 additions & 0 deletions
110
packages/rn-tester/NativeCxxModuleExample/NativeCxxModuleExample.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 "NativeCxxModuleExample.h" | ||
|
||
namespace facebook::react { | ||
|
||
NativeCxxModuleExample::NativeCxxModuleExample( | ||
std::shared_ptr<CallInvoker> jsInvoker) | ||
: NativeCxxModuleExampleCxxSpec(std::move(jsInvoker)) {} | ||
|
||
void NativeCxxModuleExample::getValueWithCallback( | ||
jsi::Runtime &rt, | ||
AsyncCallback<std::string> callback) { | ||
callback({"value from callback!"}); | ||
} | ||
|
||
std::vector<std::optional<ObjectStruct>> NativeCxxModuleExample::getArray( | ||
jsi::Runtime &rt, | ||
std::vector<std::optional<ObjectStruct>> arg) { | ||
return arg; | ||
} | ||
|
||
bool NativeCxxModuleExample::getBool(jsi::Runtime &rt, bool arg) { | ||
return arg; | ||
} | ||
|
||
ConstantsStruct NativeCxxModuleExample::getConstants(jsi::Runtime &rt) { | ||
return ConstantsStruct{true, 69, "react-native"}; | ||
} | ||
|
||
int32_t NativeCxxModuleExample::getEnum(jsi::Runtime &rt, int32_t arg) { | ||
return arg; | ||
} | ||
|
||
std::map<std::string, std::optional<int32_t>> NativeCxxModuleExample::getMap( | ||
jsi::Runtime &rt, | ||
std::map<std::string, std::optional<int32_t>> arg) { | ||
return arg; | ||
} | ||
|
||
double NativeCxxModuleExample::getNumber(jsi::Runtime &rt, double arg) { | ||
return arg; | ||
} | ||
|
||
ObjectStruct NativeCxxModuleExample::getObject( | ||
jsi::Runtime &rt, | ||
ObjectStruct arg) { | ||
return arg; | ||
} | ||
|
||
std::set<float> NativeCxxModuleExample::getSet( | ||
jsi::Runtime &rt, | ||
std::set<float> arg) { | ||
return arg; | ||
} | ||
|
||
std::string NativeCxxModuleExample::getString( | ||
jsi::Runtime &rt, | ||
std::string arg) { | ||
return arg; | ||
} | ||
|
||
std::string NativeCxxModuleExample::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 NativeCxxModuleExample::getValue( | ||
jsi::Runtime &rt, | ||
double x, | ||
std::string y, | ||
ObjectStruct z) { | ||
ValueStruct result{x, y, z}; | ||
return result; | ||
} | ||
|
||
AsyncPromise<std::string> NativeCxxModuleExample::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 NativeCxxModuleExample::voidFunc(jsi::Runtime &rt) { | ||
// Nothing to do | ||
} | ||
|
||
} // namespace facebook::react |
68 changes: 68 additions & 0 deletions
68
packages/rn-tester/NativeCxxModuleExample/NativeCxxModuleExample.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,68 @@ | ||
/* | ||
* 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 | ||
|
||
#if __has_include(<React-Codegen/AppSpecsJSI.h>) // CocoaPod headers on Apple | ||
#include <React-Codegen/AppSpecsJSI.h> | ||
#elif __has_include("AppSpecsJSI.h") // Cmake headers on Android | ||
#include "AppSpecsJSI.h" | ||
#else // BUCK headers | ||
#include <AppSpecs/AppSpecsJSI.h> | ||
#endif | ||
#include <memory> | ||
#include <set> | ||
#include <string> | ||
#include <vector> | ||
#include "NativeCxxModuleExample_ConstantsStruct.h" | ||
#include "NativeCxxModuleExample_ObjectStruct.h" | ||
#include "NativeCxxModuleExample_ValueStruct.h" | ||
|
||
namespace facebook::react { | ||
|
||
class NativeCxxModuleExample | ||
: public NativeCxxModuleExampleCxxSpec<NativeCxxModuleExample> { | ||
public: | ||
NativeCxxModuleExample(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 |
64 changes: 64 additions & 0 deletions
64
packages/rn-tester/NativeCxxModuleExample/NativeCxxModuleExample.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,64 @@ | ||
/** | ||
* 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'; | ||
|
||
/** FIXME: Enable flow-enum support | ||
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 ConstantsStruct = {| | ||
const1: boolean, | ||
const2: number, | ||
const3: string, | ||
|}; | ||
|
||
export type ObjectStruct = {| | ||
a: number, | ||
b: string, | ||
c?: ?string, | ||
|}; | ||
|
||
export type ValueStruct = {| | ||
x: number, | ||
y: string, | ||
z: ObjectStruct, | ||
|}; | ||
|
||
export interface Spec extends TurboModule { | ||
+getArray: (arg: Array<ObjectStruct | null>) => Array<ObjectStruct | null>; | ||
+getBool: (arg: boolean) => boolean; | ||
+getConstants: () => ConstantsStruct; | ||
// FIXME: Enable flow-enum support | ||
+getEnum: (arg: number /*EnumInt*/) => number /*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) => ValueStruct; | ||
+getValueWithCallback: (callback: (value: string) => void) => void; | ||
+getValueWithPromise: (error: boolean) => Promise<string>; | ||
+voidFunc: () => void; | ||
} | ||
|
||
export default (TurboModuleRegistry.get<Spec>( | ||
'NativeCxxModuleExampleCxx', | ||
): ?Spec); |
31 changes: 31 additions & 0 deletions
31
packages/rn-tester/NativeCxxModuleExample/NativeCxxModuleExample.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,31 @@ | ||
# 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 = "NativeCxxModuleExample" | ||
s.version = package["version"] | ||
s.summary = package["description"] | ||
s.description = "NativeCxxModuleExample" | ||
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 = "Meta Platforms, 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 | ||
s.pod_target_xcconfig = { | ||
"USE_HEADERMAP" => "YES", | ||
"CLANG_CXX_LANGUAGE_STANDARD" => "c++17" | ||
} | ||
|
||
install_modules_dependencies(s) | ||
|
||
s.dependency "ReactCommon/turbomodule/core" | ||
end |
Oops, something went wrong.