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 <fbjni/fbjni.h>
6b7d1787dSŁukasz Kosmaty
7b7d1787dSŁukasz Kosmaty #include <memory>
8b7d1787dSŁukasz Kosmaty #include <unordered_map>
9b7d1787dSŁukasz Kosmaty
10b7d1787dSŁukasz Kosmaty namespace jni = facebook::jni;
11b7d1787dSŁukasz Kosmaty
12b7d1787dSŁukasz Kosmaty namespace expo {
13*75c7ead1SKudo Chien
14*75c7ead1SKudo Chien template <typename T>
hash_combine(std::size_t & seed,const T & v)15*75c7ead1SKudo Chien inline void hash_combine(std::size_t& seed, const T& v)
16*75c7ead1SKudo Chien {
17*75c7ead1SKudo Chien std::hash<T> hasher;
18*75c7ead1SKudo Chien // Reference from: https://github.com/boostorg/container_hash/blob/boost-1.76.0/include/boost/container_hash/hash.hpp
19*75c7ead1SKudo Chien seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
20*75c7ead1SKudo Chien }
21*75c7ead1SKudo Chien
22*75c7ead1SKudo Chien struct pairhash {
23*75c7ead1SKudo Chien template <typename A, typename B>
operatorpairhash24*75c7ead1SKudo Chien std::size_t operator()(const std::pair<A, B>& v) const {
25*75c7ead1SKudo Chien std::size_t seed = 0;
26*75c7ead1SKudo Chien hash_combine(seed, v.first);
27*75c7ead1SKudo Chien hash_combine(seed, v.second);
28*75c7ead1SKudo Chien return seed;
29*75c7ead1SKudo Chien }
30*75c7ead1SKudo Chien };
31*75c7ead1SKudo Chien
32*75c7ead1SKudo Chien using MethodHashMap = std::unordered_map<std::pair<std::string, std::string>, jmethodID, pairhash>;
33b7d1787dSŁukasz Kosmaty
34b7d1787dSŁukasz Kosmaty /**
35b7d1787dSŁukasz Kosmaty * Singleton registry used to store references to often used Java classes.
36b7d1787dSŁukasz Kosmaty */
37b7d1787dSŁukasz Kosmaty class JavaReferencesCache {
38b7d1787dSŁukasz Kosmaty public:
39b7d1787dSŁukasz Kosmaty /**
40b7d1787dSŁukasz Kosmaty * An entry in the Java class registry.
41b7d1787dSŁukasz Kosmaty */
42b7d1787dSŁukasz Kosmaty class CachedJClass {
43b7d1787dSŁukasz Kosmaty public:
44b7d1787dSŁukasz Kosmaty CachedJClass(jclass clazz, MethodHashMap methods);
45b7d1787dSŁukasz Kosmaty
46b7d1787dSŁukasz Kosmaty /**
47b7d1787dSŁukasz Kosmaty * A bare reference to the class object.
48b7d1787dSŁukasz Kosmaty */
49b7d1787dSŁukasz Kosmaty jclass clazz;
50b7d1787dSŁukasz Kosmaty
51b7d1787dSŁukasz Kosmaty /**
52b7d1787dSŁukasz Kosmaty * Returns a cached method id for provided method name and signature.
53b7d1787dSŁukasz Kosmaty */
54b7d1787dSŁukasz Kosmaty jmethodID getMethod(const std::string &name, const std::string &signature);
55b7d1787dSŁukasz Kosmaty
56b7d1787dSŁukasz Kosmaty private:
57b7d1787dSŁukasz Kosmaty MethodHashMap methods;
58b7d1787dSŁukasz Kosmaty };
59b7d1787dSŁukasz Kosmaty
60b7d1787dSŁukasz Kosmaty JavaReferencesCache(JavaReferencesCache const &) = delete;
61b7d1787dSŁukasz Kosmaty
62b7d1787dSŁukasz Kosmaty JavaReferencesCache &operator=(JavaReferencesCache const &) = delete;
63b7d1787dSŁukasz Kosmaty
64b7d1787dSŁukasz Kosmaty /**
65b7d1787dSŁukasz Kosmaty * Gets a singleton instance
66b7d1787dSŁukasz Kosmaty */
67b7d1787dSŁukasz Kosmaty static std::shared_ptr<JavaReferencesCache> instance();
68b7d1787dSŁukasz Kosmaty
69b7d1787dSŁukasz Kosmaty /**
70b7d1787dSŁukasz Kosmaty * Gets a cached Java class entry.
71b7d1787dSŁukasz Kosmaty */
72b7d1787dSŁukasz Kosmaty CachedJClass &getJClass(const std::string &className);
73b7d1787dSŁukasz Kosmaty
74b7d1787dSŁukasz Kosmaty /**
758d89495bSŁukasz Kosmaty * Gets a cached Java class entry or loads it to the registry.
768d89495bSŁukasz Kosmaty */
778d89495bSŁukasz Kosmaty CachedJClass &getOrLoadJClass(JNIEnv *env, const std::string &className);
788d89495bSŁukasz Kosmaty
798d89495bSŁukasz Kosmaty /**
80b7d1787dSŁukasz Kosmaty * Loads predefined set of Java classes and stores them
81b7d1787dSŁukasz Kosmaty */
82b7d1787dSŁukasz Kosmaty void loadJClasses(JNIEnv *env);
83b7d1787dSŁukasz Kosmaty
84b7d1787dSŁukasz Kosmaty private:
85b7d1787dSŁukasz Kosmaty JavaReferencesCache() = default;
86b7d1787dSŁukasz Kosmaty
87b7d1787dSŁukasz Kosmaty std::unordered_map<std::string, CachedJClass> jClassRegistry;
88b7d1787dSŁukasz Kosmaty
89b7d1787dSŁukasz Kosmaty void loadJClass(
90b7d1787dSŁukasz Kosmaty JNIEnv *env,
91b7d1787dSŁukasz Kosmaty const std::string &name,
92b7d1787dSŁukasz Kosmaty const std::vector<std::pair<std::string, std::string>> &methods
93b7d1787dSŁukasz Kosmaty );
94b7d1787dSŁukasz Kosmaty };
95b7d1787dSŁukasz Kosmaty } // namespace expo
96