1 // Copyright © 2021-present 650 Industries, Inc. (aka Expo)
2 
3 #pragma once
4 
5 #include "JavaScriptRuntime.h"
6 #include "JavaScriptModuleObject.h"
7 
8 #include <fbjni/fbjni.h>
9 #include <jsi/jsi.h>
10 #include <ReactCommon/CallInvokerHolder.h>
11 #include <ReactCommon/CallInvoker.h>
12 
13 #include <memory>
14 
15 namespace jni = facebook::jni;
16 namespace jsi = facebook::jsi;
17 namespace react = facebook::react;
18 
19 namespace expo {
20 /**
21  * A JNI wrapper to initialize CPP part of modules and access all data from the module registry.
22  */
23 class JSIInteropModuleRegistry : public jni::HybridClass<JSIInteropModuleRegistry> {
24 public:
25   static auto constexpr
26     kJavaDescriptor = "Lexpo/modules/kotlin/jni/JSIInteropModuleRegistry;";
27   static auto constexpr TAG = "JSIInteropModuleRegistry";
28 
29   static jni::local_ref<jhybriddata> initHybrid(jni::alias_ref<jhybridobject> jThis);
30 
31   static void registerNatives();
32 
33   /**
34    * Initializes the `ExpoModulesHostObject` and adds it to the global object.
35    */
36   void installJSI(
37     jlong jsRuntimePointer,
38     jni::alias_ref<react::CallInvokerHolder::javaobject> jsInvokerHolder,
39     jni::alias_ref<react::CallInvokerHolder::javaobject> nativeInvokerHolder
40   );
41 
42   /**
43    * Gets a module for a given name. It will throw an exception if the module doesn't exist.
44    *
45    * @param moduleName
46    * @return An instance of `JavaScriptModuleObject`
47    */
48   jni::local_ref<JavaScriptModuleObject::javaobject> getModule(const std::string &moduleName) const;
49 
50   std::shared_ptr<react::CallInvoker> jsInvoker;
51   std::shared_ptr<react::CallInvoker> nativeInvoker;
52 
53 private:
54   friend HybridBase;
55   std::unique_ptr<JavaScriptRuntime> runtimeHolder;
56   jni::global_ref<JSIInteropModuleRegistry::javaobject> javaPart_;
57 
58   explicit JSIInteropModuleRegistry(jni::alias_ref<jhybridobject> jThis);
59 
60   inline jni::local_ref<JavaScriptModuleObject::javaobject>
61   callGetJavaScriptModuleObjectMethod(const std::string &moduleName) const;
62 };
63 } // namespace expo
64