1 // Copyright © 2021-present 650 Industries, Inc. (aka Expo)
2 
3 #pragma once
4 
5 #include "JSIObjectWrapper.h"
6 #include "JavaScriptRuntime.h"
7 #include "WeakRuntimeHolder.h"
8 #include "types/ExpectedType.h"
9 
10 #include <fbjni/fbjni.h>
11 #include <jsi/jsi.h>
12 
13 namespace jni = facebook::jni;
14 namespace jsi = facebook::jsi;
15 
16 namespace expo {
17 
18 /**
19  * Represents any JavaScript function. Its purpose is to expose the `jsi::Function` API back to Kotlin.
20  */
21 class JavaScriptFunction : public jni::HybridClass<JavaScriptFunction, Destructible>, JSIFunctionWrapper {
22 public:
23   static auto constexpr
24     kJavaDescriptor = "Lexpo/modules/kotlin/jni/JavaScriptFunction;";
25   static auto constexpr TAG = "JavaScriptFunction";
26 
27   static void registerNatives();
28 
29   static jni::local_ref<JavaScriptFunction::javaobject> newInstance(
30     JSIInteropModuleRegistry *jsiInteropModuleRegistry,
31     std::weak_ptr<JavaScriptRuntime> runtime,
32     std::shared_ptr<jsi::Function> jsFunction
33   );
34 
35   JavaScriptFunction(
36     std::weak_ptr<JavaScriptRuntime> runtime,
37     std::shared_ptr<jsi::Function> jsFunction
38   );
39 
40   JavaScriptFunction(
41     WeakRuntimeHolder runtime,
42     std::shared_ptr<jsi::Function> jsFunction
43   );
44 
45   std::shared_ptr<jsi::Function> get() override;
46 
47 
48 private:
49   friend HybridBase;
50 
51   WeakRuntimeHolder runtimeHolder;
52   std::shared_ptr<jsi::Function> jsFunction;
53 
54   jobject invoke(
55     jni::alias_ref<jni::JArrayClass<jni::JObject>> args,
56     jni::alias_ref<ExpectedType::javaobject> expectedReturnType
57   );
58 };
59 
60 } // namespace expo
61