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