// Copyright © 2021-present 650 Industries, Inc. (aka Expo) #pragma once #include "JavaScriptRuntime.h" #include "JavaScriptModuleObject.h" #include "JavaScriptValue.h" #include "JavaScriptObject.h" #include "JavaReferencesCache.h" #include "JSReferencesCache.h" #include "JNIDeallocator.h" #include #include #include #include #if REACT_NATIVE_TARGET_VERSION >= 73 #include #endif #include namespace jni = facebook::jni; namespace jsi = facebook::jsi; namespace react = facebook::react; namespace expo { #if REACT_NATIVE_TARGET_VERSION >= 73 using NativeMethodCallInvokerHolderCompatible = react::NativeMethodCallInvokerHolder; #else using NativeMethodCallInvokerHolderCompatible = react::CallInvokerHolder; #endif /** * A JNI wrapper to initialize CPP part of modules and access all data from the module registry. */ class JSIInteropModuleRegistry : public jni::HybridClass { public: static auto constexpr kJavaDescriptor = "Lexpo/modules/kotlin/jni/JSIInteropModuleRegistry;"; static auto constexpr TAG = "JSIInteropModuleRegistry"; static jni::local_ref initHybrid(jni::alias_ref jThis); static void registerNatives(); /** * Initializes the `ExpoModulesHostObject` and adds it to the global object. */ void installJSI( jlong jsRuntimePointer, jni::alias_ref jniDeallocator, jni::alias_ref jsInvokerHolder, jni::alias_ref nativeInvokerHolder ); /** * Initializes the test runtime. Shouldn't be used in the production. */ void installJSIForTests( jni::alias_ref jniDeallocator ); /** * Gets a module for a given name. It will throw an exception if the module doesn't exist. * * @param moduleName * @return An instance of `JavaScriptModuleObject` */ jni::local_ref getModule(const std::string &moduleName) const; bool hasModule(const std::string &moduleName) const; /** * Gets names of all available modules. */ jni::local_ref> getModulesName() const; /** * Exposes a `JavaScriptRuntime::evaluateScript` function to Kotlin */ jni::local_ref evaluateScript(jni::JString script); /** * Exposes a `JavaScriptRuntime::global` function to Kotlin */ jni::local_ref global(); /** * Exposes a `JavaScriptRuntime::createObject` function to Kotlin */ jni::local_ref createObject(); /** * Gets a core module. */ jni::local_ref getCoreModule() const; /** * Adds a shared object to the internal registry * @param native part of the shared object * @param js part of the shared object */ void registerSharedObject( jni::local_ref native, jni::local_ref js ); /** * Exposes a `JavaScriptRuntime::drainJSEventLoop` function to Kotlin */ void drainJSEventLoop(); std::shared_ptr jsInvoker; std::shared_ptr nativeInvoker; std::shared_ptr runtimeHolder; std::unique_ptr jsRegistry; jni::global_ref jniDeallocator; private: friend HybridBase; jni::global_ref javaPart_; explicit JSIInteropModuleRegistry(jni::alias_ref jThis); inline jni::local_ref callGetJavaScriptModuleObjectMethod(const std::string &moduleName) const; inline jni::local_ref> callGetJavaScriptModulesNames() const; inline jni::local_ref callGetCoreModuleObject() const; inline bool callHasModule(const std::string &moduleName) const; }; } // namespace expo