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 CODED_ERROR 26 }; 27 28 JSReferencesCache() = delete; 29 30 JSReferencesCache(jsi::Runtime &runtime); 31 32 /** 33 * Gets a cached object. 34 */ 35 template<class T, typename std::enable_if_t<std::is_base_of_v<jsi::Object, T>, int> = 0> 36 T &getObject(JSKeys key) { 37 return static_cast<T &>(*jsObjectRegistry.at(key)); 38 } 39 40 /** 41 * Gets a cached object if present. Otherwise, returns nullptr. 42 */ 43 template<class T, typename std::enable_if_t<std::is_base_of_v<jsi::Object, T>, int> = 0> 44 T *getOptionalObject(JSKeys key) { 45 auto result = jsObjectRegistry.find(key); 46 47 if (result == jsObjectRegistry.end()) { 48 return nullptr; 49 } 50 jsi::Object &object = *result->second; 51 return &static_cast<T &>(object); 52 } 53 54 /** 55 * Gets a cached jsi::PropNameID or creates a new one for the provided string. 56 */ 57 jsi::PropNameID &getPropNameID(jsi::Runtime &runtime, const std::string &name); 58 59 private: 60 std::unordered_map<JSKeys, std::unique_ptr<jsi::Object>> jsObjectRegistry; 61 62 std::unordered_map<std::string, std::unique_ptr<jsi::PropNameID>> propNameIDRegistry; 63 }; 64 } // namespace expo 65