1 // Copyright © 2021-present 650 Industries, Inc. (aka Expo)
2 
3 #pragma once
4 
5 #include "JavaReferencesCache.h"
6 #include "Exceptions.h"
7 #include "JavaScriptObject.h"
8 #include "JavaScriptRuntime.h"
9 #include "JSIObjectWrapper.h"
10 #include "WeakRuntimeHolder.h"
11 
12 #include <jsi/jsi.h>
13 #include <memory>
14 #include <unordered_map>
15 
16 namespace expo {
17 /**
18  * Registry used to store references to often used JS objects like Promise.
19  * The object lifetime should be bound with the JS runtime.
20  */
21 class JSReferencesCache {
22 public:
23   enum class JSKeys {
24     PROMISE
25   };
26 
27   JSReferencesCache() = delete;
28 
29   JSReferencesCache(jsi::Runtime &runtime);
30 
31   /**
32    * Gets a cached object.
33    */
34   template<class T, typename std::enable_if_t<std::is_base_of_v<jsi::Object, T>, int> = 0>
35   T &getObject(JSKeys key) {
36     return static_cast<T &>(*jsObjectRegistry.at(key));
37   }
38 
39   /**
40    * Gets a cached object if present. Otherwise, returns nullptr.
41    */
42   template<class T, typename std::enable_if_t<std::is_base_of_v<jsi::Object, T>, int> = 0>
43   T *getOptionalObject(JSKeys key) {
44     auto result = jsObjectRegistry.find(key);
45 
46     if (result == jsObjectRegistry.end()) {
47       return nullptr;
48     }
49     jsi::Object &object = *result->second;
50     return &static_cast<T &>(object);
51   }
52 
53   /**
54    * Gets a cached jsi::PropNameID or creates a new one for the provided string.
55    */
56   jsi::PropNameID &getPropNameID(jsi::Runtime &runtime, const std::string &name);
57 
58 private:
59   std::unordered_map<JSKeys, std::unique_ptr<jsi::Object>> jsObjectRegistry;
60 
61   std::unordered_map<std::string, std::unique_ptr<jsi::PropNameID>> propNameIDRegistry;
62 };
63 } // namespace expo
64