1 // Copyright © 2021-present 650 Industries, Inc. (aka Expo) 2 3 #pragma once 4 5 #include <jsi/jsi.h> 6 #include <fbjni/fbjni.h> 7 #include <ReactCommon/TurboModuleUtils.h> 8 #include <react/jni/ReadableNativeArray.h> 9 #include <memory> 10 #include <folly/dynamic.h> 11 #include <jsi/JSIDynamic.h> 12 13 namespace jni = facebook::jni; 14 namespace jsi = facebook::jsi; 15 namespace react = facebook::react; 16 17 namespace expo { 18 class JSIInteropModuleRegistry; 19 20 /** 21 * A class that holds information about the exported function. 22 */ 23 class MethodMetadata { 24 public: 25 /** 26 * Function name 27 */ 28 std::string name; 29 /** 30 * Number of arguments 31 */ 32 int args; 33 /* 34 * Whether this function is async 35 */ 36 bool isAsync; 37 38 MethodMetadata( 39 std::string name, 40 int args, 41 bool isAsync, 42 jni::global_ref<jobject> &&jBodyReference 43 ); 44 45 // We deleted the copy contractor to not deal with transforming the ownership of the `jBodyReference`. 46 MethodMetadata(const MethodMetadata &) = delete; 47 48 /** 49 * MethodMetadata owns the only reference to the Kotlin function. 50 * We have to clean that, cause it's a `global_ref`. 51 */ 52 ~MethodMetadata() { 53 jBodyReference.release(); 54 } 55 56 /** 57 * Transforms metadata to a jsi::Function. 58 * 59 * @param runtime 60 * @param moduleRegistry 61 * @return shared ptr to the jsi::Function that wrapped the underlying Kotlin's function. 62 */ 63 std::shared_ptr<jsi::Function> toJSFunction( 64 jsi::Runtime &runtime, 65 JSIInteropModuleRegistry *moduleRegistry 66 ); 67 68 private: 69 /** 70 * Reference to one of two java objects - `JNIFunctionBody` or `JNIAsyncFunctionBody`. 71 * 72 * In case when `isAsync` is `true`, this variable will point to `JNIAsyncFunctionBody`. 73 * Otherwise to `JNIFunctionBody` 74 */ 75 jni::global_ref<jobject> jBodyReference; 76 77 /** 78 * To not create a jsi::Function always when we need it, we cached that value. 79 */ 80 std::shared_ptr<jsi::Function> body = nullptr; 81 82 jsi::Function toSyncFunction(jsi::Runtime &runtime); 83 84 jsi::Function toAsyncFunction(jsi::Runtime &runtime, JSIInteropModuleRegistry *moduleRegistry); 85 86 jsi::Function createPromiseBody( 87 jsi::Runtime &runtime, 88 JSIInteropModuleRegistry *moduleRegistry, 89 folly::dynamic &&args 90 ); 91 }; 92 } // namespace expo 93