1 // Copyright © 2021-present 650 Industries, Inc. (aka Expo) 2 3 #pragma once 4 5 #include <fbjni/fbjni.h> 6 #include "boost/functional/hash.hpp" 7 8 #include <memory> 9 #include <unordered_map> 10 11 namespace jni = facebook::jni; 12 13 namespace expo { 14 using MethodHashMap = std::unordered_map< 15 std::pair<std::string, std::string>, 16 jmethodID, 17 boost::hash<std::pair<std::string, std::string>> 18 >; 19 20 /** 21 * Singleton registry used to store references to often used Java classes. 22 */ 23 class JavaReferencesCache { 24 public: 25 /** 26 * An entry in the Java class registry. 27 */ 28 class CachedJClass { 29 public: 30 CachedJClass(jclass clazz, MethodHashMap methods); 31 32 /** 33 * A bare reference to the class object. 34 */ 35 jclass clazz; 36 37 /** 38 * Returns a cached method id for provided method name and signature. 39 */ 40 jmethodID getMethod(const std::string &name, const std::string &signature); 41 42 private: 43 MethodHashMap methods; 44 }; 45 46 JavaReferencesCache(JavaReferencesCache const &) = delete; 47 48 JavaReferencesCache &operator=(JavaReferencesCache const &) = delete; 49 50 /** 51 * Gets a singleton instance 52 */ 53 static std::shared_ptr<JavaReferencesCache> instance(); 54 55 /** 56 * Gets a cached Java class entry. 57 */ 58 CachedJClass &getJClass(const std::string &className); 59 60 /** 61 * Gets a cached Java class entry or loads it to the registry. 62 */ 63 CachedJClass &getOrLoadJClass(JNIEnv *env, const std::string &className); 64 65 /** 66 * Loads predefined set of Java classes and stores them 67 */ 68 void loadJClasses(JNIEnv *env); 69 70 private: 71 JavaReferencesCache() = default; 72 73 std::unordered_map<std::string, CachedJClass> jClassRegistry; 74 75 void loadJClass( 76 JNIEnv *env, 77 const std::string &name, 78 const std::vector<std::pair<std::string, std::string>> &methods 79 ); 80 }; 81 } // namespace expo 82