1 // Copyright © 2021-present 650 Industries, Inc. (aka Expo) 2 3 #pragma once 4 5 #include "JSIObjectWrapper.h" 6 7 #include <fbjni/fbjni.h> 8 #include <jsi/jsi.h> 9 10 #include <type_traits> 11 12 namespace jni = facebook::jni; 13 namespace jsi = facebook::jsi; 14 15 namespace expo { 16 /** 17 * A base template of the jni to jsi types converter. 18 * To make this conversion as fast and easy as possible we used the type trait technic. 19 */ 20 template<class T, typename = void> 21 struct jsi_type_converter { 22 static const bool isDefined = false; 23 }; 24 25 /** 26 * Conversion from jni::alias_ref<T::javaobject> to jsi::Value where T extends JSIValueWrapper, JSIObjectWrapper or JSIFunctionWrapper. 27 */ 28 template<class T> 29 struct jsi_type_converter< 30 jni::alias_ref<T>, 31 std::enable_if_t< 32 // jni::ReprType<T>::HybridType>::value if T looks like `R::javaobject`, it will return R 33 std::is_base_of<JSIValueWrapper, typename jni::ReprType<T>::HybridType>::value || 34 std::is_base_of<JSIObjectWrapper, typename jni::ReprType<T>::HybridType>::value || 35 std::is_base_of<JSIValueWrapper, typename jni::ReprType<T>::HybridType>::value 36 > 37 > { 38 static const bool isDefined = true; 39 40 inline static jsi::Value convert( 41 jsi::Runtime &runtime, 42 jni::alias_ref<T> &value) { 43 if (value == nullptr) { 44 return jsi::Value::undefined(); 45 } 46 return jsi::Value(runtime, *value->cthis()->get()); 47 } 48 }; 49 50 /** 51 * Conversion from primitive types from which jsi::Value can be constructed (like bool, double) to jsi::Value. 52 */ 53 template<class T> 54 struct jsi_type_converter< 55 T, 56 std::enable_if_t<std::is_fundamental_v<T> && std::is_constructible_v<jsi::Value, T>> 57 > { 58 static const bool isDefined = true; 59 60 inline static jsi::Value convert(jsi::Runtime &runtime, T value) { 61 return jsi::Value(value); 62 } 63 }; 64 65 /** 66 * Conversion from jni::alias_ref<jstring> to jsi::Value. 67 */ 68 template<> 69 struct jsi_type_converter<jni::alias_ref<jstring>> { 70 static const bool isDefined = true; 71 72 inline static jsi::Value convert(jsi::Runtime &runtime, jni::alias_ref<jstring> &value) { 73 if (value == nullptr) { 74 return jsi::Value::undefined(); 75 } 76 return jsi::Value(jsi::String::createFromUtf8(runtime, value->toStdString())); 77 } 78 }; 79 80 /** 81 * Helper that checks if the type converter was defined for the given type. 82 */ 83 template<class T> 84 inline constexpr bool is_jsi_type_converter_defined = jsi_type_converter<T>::isDefined; 85 } // namespace expo 86