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