// Copyright © 2021-present 650 Industries, Inc. (aka Expo) #pragma once #include "types/CppType.h" #include "types/ExpectedType.h" #include "types/AnyType.h" #include #include #include #include #include #include #include #include namespace jni = facebook::jni; namespace jsi = facebook::jsi; namespace react = facebook::react; namespace expo { class JSIInteropModuleRegistry; /** * A class that holds information about the exported function. */ class MethodMetadata { public: /** * Function name */ std::string name; /** * Whether this function takes owner */ bool takesOwner; /** * Number of arguments */ int args; /** * Whether this function is async */ bool isAsync; /** * Representation of expected argument types. */ std::vector> argTypes; MethodMetadata( std::string name, bool takesOwner, int args, bool isAsync, jni::local_ref> expectedArgTypes, jni::global_ref &&jBodyReference ); MethodMetadata( std::string name, bool takesOwner, int args, bool isAsync, std::vector> &&expectedArgTypes, jni::global_ref &&jBodyReference ); // We deleted the copy contractor to not deal with transforming the ownership of the `jBodyReference`. MethodMetadata(const MethodMetadata &) = delete; MethodMetadata(MethodMetadata &&other) = default; /** * Transforms metadata to a jsi::Function. * * @param runtime * @param moduleRegistry * @return shared ptr to the jsi::Function that wrapped the underlying Kotlin's function. */ std::shared_ptr toJSFunction( jsi::Runtime &runtime, JSIInteropModuleRegistry *moduleRegistry ); /** * Calls the underlying Kotlin function. */ jsi::Value callSync( jsi::Runtime &rt, JSIInteropModuleRegistry *moduleRegistry, const jsi::Value &thisValue, const jsi::Value *args, size_t count ); jni::local_ref callJNISync( JNIEnv *env, jsi::Runtime &rt, JSIInteropModuleRegistry *moduleRegistry, const jsi::Value &thisValue, const jsi::Value *args, size_t count ); private: /** * Reference to one of two java objects - `JNIFunctionBody` or `JNIAsyncFunctionBody`. * * In case when `isAsync` is `true`, this variable will point to `JNIAsyncFunctionBody`. * Otherwise to `JNIFunctionBody` */ jni::global_ref jBodyReference; /** * To not create a jsi::Function always when we need it, we cached that value. */ std::shared_ptr body = nullptr; jsi::Function toSyncFunction(jsi::Runtime &runtime, JSIInteropModuleRegistry *moduleRegistry); jsi::Function toAsyncFunction(jsi::Runtime &runtime, JSIInteropModuleRegistry *moduleRegistry); jsi::Function createPromiseBody( jsi::Runtime &runtime, JSIInteropModuleRegistry *moduleRegistry, jobjectArray globalArgs ); jobjectArray convertJSIArgsToJNI( JSIInteropModuleRegistry *moduleRegistry, JNIEnv *env, jsi::Runtime &rt, const jsi::Value &thisValue, const jsi::Value *args, size_t count ); }; } // namespace expo