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/CallInvoker.h> 8 9 10 namespace jsi = facebook::jsi; 11 namespace jni = facebook::jni; 12 namespace react = facebook::react; 13 14 namespace expo { 15 class JavaScriptValue; 16 class JavaScriptObject; 17 18 /** 19 * A wrapper for the jsi::Runtime. 20 * This class is used as a bridge between CPP and Kotlin and to encapsulate common runtime helper functions. 21 * 22 * Instances of this class should be managed using a shared smart pointer. 23 * To pass runtime information to all of `JavaScriptValue` and `JavaScriptObject` we use `weak_from_this()` 24 * that requires that the object is held via a smart pointer. Otherwise, `weak_from_this()` returns `nullptr`. 25 */ 26 class JavaScriptRuntime : public std::enable_shared_from_this<JavaScriptRuntime> { 27 public: 28 /** 29 * Initializes a runtime that is independent from React Native and its runtime initialization. 30 * This flow is mostly intended for tests. The JS call invoker is unavailable thus calling async functions is not supported. 31 */ 32 JavaScriptRuntime(); 33 34 JavaScriptRuntime( 35 jsi::Runtime *runtime, 36 std::shared_ptr<react::CallInvoker> jsInvoker, 37 std::shared_ptr<react::CallInvoker> nativeInvoker 38 ); 39 40 /** 41 * Returns the underlying runtime object. 42 */ 43 jsi::Runtime *get(); 44 45 /** 46 * Evaluates given JavaScript source code. 47 * @throws if the input format is unknown, or evaluation causes an error, 48 * a jni::JniException<JavaScriptEvaluateException> will be thrown. 49 */ 50 jni::local_ref<jni::HybridClass<JavaScriptValue>::javaobject> evaluateScript(const std::string &script); 51 52 /** 53 * Returns the runtime global object for use in Kotlin. 54 */ 55 jni::local_ref<jni::HybridClass<JavaScriptObject>::javaobject> global(); 56 57 /** 58 * Creates a new object for use in Kotlin. 59 */ 60 jni::local_ref<jni::HybridClass<JavaScriptObject>::javaobject> createObject(); 61 62 /** 63 * Drains the JavaScript VM internal Microtask (a.k.a. event loop) queue. 64 */ 65 void drainJSEventLoop(); 66 67 std::shared_ptr<react::CallInvoker> jsInvoker; 68 std::shared_ptr<react::CallInvoker> nativeInvoker; 69 private: 70 std::shared_ptr<jsi::Runtime> runtime; 71 }; 72 } // namespace expo 73