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   std::shared_ptr<react::CallInvoker> jsInvoker;
63   std::shared_ptr<react::CallInvoker> nativeInvoker;
64 private:
65   std::shared_ptr<jsi::Runtime> runtime;
66 };
67 } // namespace expo
68