expo-modules-core 1.2.7 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +28 -5
- package/ExpoModulesCore.podspec +1 -0
- package/README.md +1 -1
- package/android/ExpoModulesCorePlugin.gradle +16 -0
- package/android/build.gradle +3 -2
- package/android/src/main/cpp/Exceptions.cpp +8 -0
- package/android/src/main/cpp/Exceptions.h +11 -0
- package/android/src/main/cpp/ExpoModulesHostObject.cpp +22 -5
- package/android/src/main/cpp/ExpoModulesHostObject.h +5 -0
- package/android/src/main/cpp/JNIInjector.cpp +2 -0
- package/android/src/main/cpp/JSIInteropModuleRegistry.cpp +25 -1
- package/android/src/main/cpp/JSIInteropModuleRegistry.h +14 -0
- package/android/src/main/cpp/JSIObjectWrapper.h +15 -4
- package/android/src/main/cpp/JSITypeConverter.h +3 -2
- package/android/src/main/cpp/JavaReferencesCache.cpp +2 -0
- package/android/src/main/cpp/JavaScriptFunction.cpp +56 -0
- package/android/src/main/cpp/JavaScriptFunction.h +54 -0
- package/android/src/main/cpp/JavaScriptModuleObject.cpp +225 -105
- package/android/src/main/cpp/JavaScriptModuleObject.h +67 -34
- package/android/src/main/cpp/JavaScriptObject.cpp +55 -1
- package/android/src/main/cpp/JavaScriptObject.h +17 -13
- package/android/src/main/cpp/JavaScriptRuntime.cpp +12 -3
- package/android/src/main/cpp/JavaScriptRuntime.h +9 -1
- package/android/src/main/cpp/JavaScriptValue.cpp +9 -0
- package/android/src/main/cpp/JavaScriptValue.h +4 -0
- package/android/src/main/cpp/MethodMetadata.cpp +66 -87
- package/android/src/main/cpp/MethodMetadata.h +18 -16
- package/android/src/main/cpp/ObjectDeallocator.h +25 -0
- package/android/src/main/cpp/WeakRuntimeHolder.cpp +7 -0
- package/android/src/main/cpp/WeakRuntimeHolder.h +4 -0
- package/android/src/main/cpp/types/CppType.h +4 -1
- package/android/src/main/cpp/types/FrontendConverter.cpp +58 -0
- package/android/src/main/cpp/types/FrontendConverter.h +45 -0
- package/android/src/main/cpp/types/FrontendConverterProvider.cpp +3 -0
- package/android/src/main/cpp/types/JNIToJSIConverter.cpp +88 -0
- package/android/src/main/cpp/types/JNIToJSIConverter.h +22 -0
- package/android/src/main/java/com/facebook/react/uimanager/ReactStylesDiffMapHelper.kt +10 -0
- package/android/src/main/java/expo/modules/kotlin/AppContext.kt +8 -25
- package/android/src/main/java/expo/modules/kotlin/FilteredIterator.kt +37 -0
- package/android/src/main/java/expo/modules/kotlin/KotlinInteropModuleRegistry.kt +1 -1
- package/android/src/main/java/expo/modules/kotlin/ModuleHolder.kt +30 -23
- package/android/src/main/java/expo/modules/kotlin/ModuleRegistry.kt +0 -3
- package/android/src/main/java/expo/modules/kotlin/Utils.kt +21 -0
- package/android/src/main/java/expo/modules/kotlin/activityresult/AppContextActivityResultCaller.kt +21 -1
- package/android/src/main/java/expo/modules/kotlin/classcomponent/ClassComponentBuilder.kt +112 -0
- package/android/src/main/java/expo/modules/kotlin/classcomponent/ClassDefinitionData.kt +10 -0
- package/android/src/main/java/expo/modules/kotlin/exception/CodedException.kt +21 -0
- package/android/src/main/java/expo/modules/kotlin/exception/CommonExceptions.kt +15 -0
- package/android/src/main/java/expo/modules/kotlin/functions/AnyFunction.kt +17 -3
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunction.kt +38 -8
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionComponent.kt +3 -2
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionWithPromiseComponent.kt +3 -2
- package/android/src/main/java/expo/modules/kotlin/functions/SuspendFunctionComponent.kt +1 -0
- package/android/src/main/java/expo/modules/kotlin/functions/SyncFunctionComponent.kt +18 -11
- package/android/src/main/java/expo/modules/kotlin/jni/CppType.kt +4 -1
- package/android/src/main/java/expo/modules/kotlin/jni/JNIDeallocator.kt +73 -0
- package/android/src/main/java/expo/modules/kotlin/jni/JSIInteropModuleRegistry.kt +28 -2
- package/android/src/main/java/expo/modules/kotlin/jni/JavaCallback.kt +8 -1
- package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptFunction.kt +48 -0
- package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptModuleObject.kt +40 -3
- package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptObject.kt +23 -3
- package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptValue.kt +26 -1
- package/android/src/main/java/expo/modules/kotlin/modules/Module.kt +0 -11
- package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionBuilder.kt +26 -16
- package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionData.kt +3 -1
- package/android/src/main/java/expo/modules/kotlin/sharedobjects/SharedObject.kt +12 -0
- package/android/src/main/java/expo/modules/kotlin/sharedobjects/SharedObjectRegistry.kt +62 -0
- package/android/src/main/java/expo/modules/kotlin/sharedobjects/SharedObjectTypeConverter.kt +27 -0
- package/android/src/main/java/expo/modules/kotlin/types/AnyType.kt +2 -1
- package/android/src/main/java/expo/modules/kotlin/types/EitherTypeConverter.kt +7 -6
- package/android/src/main/java/expo/modules/kotlin/types/JavaScriptFunctionTypeConverter.kt +22 -0
- package/android/src/main/java/expo/modules/kotlin/types/TypeConverter.kt +30 -24
- package/android/src/main/java/expo/modules/kotlin/types/TypeConverterProvider.kt +45 -1
- package/android/src/main/java/expo/modules/kotlin/types/TypedArrayTypeConverter.kt +3 -2
- package/android/src/main/java/expo/modules/kotlin/views/AnyViewProp.kt +3 -1
- package/android/src/main/java/expo/modules/kotlin/views/ConcreteViewProp.kt +3 -3
- package/android/src/main/java/expo/modules/kotlin/views/FilteredReadableMap.kt +53 -0
- package/android/src/main/java/expo/modules/kotlin/views/GroupViewManagerWrapper.kt +25 -5
- package/android/src/main/java/expo/modules/kotlin/views/SimpleViewManagerWrapper.kt +25 -5
- package/android/src/main/java/expo/modules/kotlin/views/ViewDefinitionBuilder.kt +161 -10
- package/android/src/main/java/expo/modules/kotlin/views/ViewGroupDefinitionBuilder.kt +0 -67
- package/android/src/main/java/expo/modules/kotlin/views/ViewManagerDefinition.kt +6 -7
- package/android/src/main/java/expo/modules/kotlin/views/ViewManagerWrapperDelegate.kt +40 -3
- package/android/src/main/java/expo/modules/kotlin/views/ViewTypeConverter.kt +44 -0
- package/android-annotation/build.gradle +45 -0
- package/android-annotation/src/main/java/expo/modules/annotation/Config.kt +7 -0
- package/android-annotation/src/main/java/expo/modules/annotation/ConverterBinder.kt +7 -0
- package/android-annotation-processor/build.gradle +51 -0
- package/android-annotation-processor/src/main/java/expo/modules/annotationprocessor/ExpoSymbolProcessor.kt +175 -0
- package/android-annotation-processor/src/main/java/expo/modules/annotationprocessor/ExpoSymbolProcessorProvider.kt +10 -0
- package/android-annotation-processor/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider +1 -0
- package/build/NativeViewManagerAdapter.native.d.ts.map +1 -1
- package/build/NativeViewManagerAdapter.native.js +36 -23
- package/build/NativeViewManagerAdapter.native.js.map +1 -1
- package/build/requireNativeModule.js +2 -2
- package/build/requireNativeModule.js.map +1 -1
- package/common/cpp/fabric/ExpoViewProps.cpp +18 -3
- package/common/cpp/fabric/ExpoViewProps.h +4 -1
- package/ios/Fabric/ExpoFabricView.swift +10 -10
- package/ios/Fabric/ExpoFabricViewObjC.h +2 -0
- package/ios/Fabric/ExpoFabricViewObjC.mm +17 -2
- package/ios/JSI/EXJSIInstaller.mm +1 -1
- package/ios/JSI/EXJSIUtils.h +5 -0
- package/ios/JSI/EXJSIUtils.mm +17 -0
- package/ios/JSI/EXJavaScriptRuntime.h +5 -0
- package/ios/JSI/EXJavaScriptRuntime.mm +6 -0
- package/ios/JSI/EXJavaScriptValue.h +2 -0
- package/ios/JSI/EXJavaScriptValue.mm +8 -0
- package/ios/JSI/EXJavaScriptWeakObject.mm +29 -8
- package/ios/JSI/EXRawJavaScriptFunction.h +24 -0
- package/ios/JSI/EXRawJavaScriptFunction.mm +52 -0
- package/ios/JSI/ExpoModulesHostObject.mm +1 -1
- package/ios/JSI/JavaScriptValue.swift +28 -1
- package/ios/ModuleRegistry/EXModuleRegistry.h +0 -4
- package/ios/ModuleRegistry/EXModuleRegistry.m +0 -23
- package/ios/ModuleRegistryAdapter/EXModuleRegistryAdapter.m +0 -16
- package/ios/ModuleRegistryProvider/EXModuleRegistryProvider.m +0 -6
- package/ios/NativeModulesProxy/EXNativeModulesProxy.mm +1 -31
- package/ios/Swift/AppContext.swift +46 -6
- package/ios/Swift/Arguments/Convertible.swift +3 -3
- package/ios/Swift/Arguments/Convertibles.swift +5 -5
- package/ios/Swift/Classes/ClassComponent.swift +18 -12
- package/ios/Swift/Classes/ClassRegistry.swift +31 -0
- package/ios/Swift/Conversions.swift +19 -3
- package/ios/Swift/Convertibles/Convertibles+Color.swift +3 -3
- package/ios/Swift/Convertibles/Either.swift +6 -4
- package/ios/Swift/DynamicTypes/AnyDynamicType.swift +18 -2
- package/ios/Swift/DynamicTypes/DynamicArrayType.swift +3 -3
- package/ios/Swift/DynamicTypes/DynamicConvertibleType.swift +2 -2
- package/ios/Swift/DynamicTypes/DynamicEnumType.swift +1 -1
- package/ios/Swift/DynamicTypes/DynamicJavaScriptType.swift +27 -0
- package/ios/Swift/DynamicTypes/DynamicOptionalType.swift +9 -2
- package/ios/Swift/DynamicTypes/DynamicRawType.swift +1 -1
- package/ios/Swift/DynamicTypes/DynamicSharedObjectType.swift +16 -2
- package/ios/Swift/DynamicTypes/DynamicType.swift +6 -0
- package/ios/Swift/DynamicTypes/DynamicTypedArrayType.swift +15 -4
- package/ios/Swift/DynamicTypes/DynamicViewType.swift +68 -0
- package/ios/Swift/ExpoBridgeModule.swift +1 -1
- package/ios/Swift/Functions/AnyFunction.swift +5 -4
- package/ios/Swift/Functions/AsyncFunctionComponent.swift +22 -19
- package/ios/Swift/Functions/ConcurrentFunctionDefinition.swift +29 -13
- package/ios/Swift/Functions/SyncFunctionComponent.swift +26 -15
- package/ios/Swift/JavaScriptFunction.swift +68 -0
- package/ios/Swift/JavaScriptUtils.swift +57 -18
- package/ios/Swift/ModuleHolder.swift +22 -10
- package/ios/Swift/Modules/ModuleDefinition.swift +8 -2
- package/ios/Swift/Objects/JavaScriptObjectBuilder.swift +8 -8
- package/ios/Swift/Objects/ObjectDefinition.swift +17 -15
- package/ios/Swift/Objects/PropertyComponent.swift +23 -17
- package/ios/Swift/Records/AnyField.swift +1 -1
- package/ios/Swift/Records/Field.swift +2 -2
- package/ios/Swift/Records/Record.swift +5 -5
- package/ios/Swift/SharedObjects/SharedObjectRegistry.swift +4 -0
- package/ios/Swift/Views/AnyViewProp.swift +1 -1
- package/ios/Swift/Views/ComponentData.swift +37 -2
- package/ios/Swift/Views/ConcreteViewProp.swift +2 -2
- package/ios/Swift/Views/ViewDefinition.swift +39 -0
- package/ios/Swift/Views/ViewModuleWrapper.swift +0 -29
- package/ios/Tests/ClassComponentSpec.swift +39 -27
- package/ios/Tests/ConvertiblesSpec.swift +75 -49
- package/ios/Tests/DynamicTypeSpec.swift +29 -27
- package/ios/Tests/EitherSpec.swift +9 -7
- package/ios/Tests/ExpoModulesSpec.swift +13 -13
- package/ios/Tests/FunctionSpec.swift +38 -22
- package/ios/Tests/JavaScriptRuntimeSpec.swift +4 -0
- package/ios/Tests/PropertyComponentSpec.swift +33 -30
- package/ios/Tests/RecordSpec.swift +7 -5
- package/ios/Tests/SharedObjectRegistrySpec.swift +12 -12
- package/ios/Tests/TypedArraysSpec.swift +1 -1
- package/ios/Tests/ViewDefinitionSpec.swift +4 -2
- package/package.json +2 -2
- package/src/NativeViewManagerAdapter.native.tsx +33 -29
- package/src/requireNativeModule.ts +2 -2
- package/android/src/main/java/expo/modules/kotlin/views/ViewManagerDefinitionBuilder.kt +0 -132
- package/ios/EXViewManager.h +0 -21
- package/ios/EXViewManager.m +0 -128
- package/ios/ModuleRegistryAdapter/EXViewManagerAdapterClassesRegistry.h +0 -17
- package/ios/ModuleRegistryAdapter/EXViewManagerAdapterClassesRegistry.m +0 -67
- package/ios/ViewManagerAdapter/EXViewManagerAdapter.h +0 -17
- package/ios/ViewManagerAdapter/EXViewManagerAdapter.m +0 -45
|
@@ -2,6 +2,7 @@ package expo.modules.kotlin.jni
|
|
|
2
2
|
|
|
3
3
|
import com.facebook.jni.HybridData
|
|
4
4
|
import expo.modules.core.interfaces.DoNotStrip
|
|
5
|
+
import kotlin.reflect.typeOf
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* A Kotlin representation of jsi::Value.
|
|
@@ -9,7 +10,12 @@ import expo.modules.core.interfaces.DoNotStrip
|
|
|
9
10
|
*/
|
|
10
11
|
@Suppress("KotlinJniMissingFunction")
|
|
11
12
|
@DoNotStrip
|
|
12
|
-
class JavaScriptValue @DoNotStrip private constructor(@DoNotStrip private val mHybridData: HybridData) {
|
|
13
|
+
class JavaScriptValue @DoNotStrip private constructor(@DoNotStrip private val mHybridData: HybridData) : Destructible {
|
|
14
|
+
init {
|
|
15
|
+
JNIDeallocator.addReference(this)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
fun isValid() = mHybridData.isValid
|
|
13
19
|
external fun kind(): String
|
|
14
20
|
|
|
15
21
|
external fun isNull(): Boolean
|
|
@@ -30,12 +36,31 @@ class JavaScriptValue @DoNotStrip private constructor(@DoNotStrip private val mH
|
|
|
30
36
|
external fun getArray(): Array<JavaScriptValue>
|
|
31
37
|
external fun getTypedArray(): JavaScriptTypedArray
|
|
32
38
|
|
|
39
|
+
private external fun <T : Any?> jniGetFunction(): JavaScriptFunction<T>
|
|
40
|
+
@PublishedApi
|
|
41
|
+
internal fun <T : Any?> internalJniGetFunction(): JavaScriptFunction<T> = jniGetFunction()
|
|
42
|
+
inline fun <reified ReturnType : Any?> getFunction(): JavaScriptFunction<ReturnType> {
|
|
43
|
+
return internalJniGetFunction<ReturnType>().apply {
|
|
44
|
+
returnType = typeOf<ReturnType>()
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
@JvmName("getVoidFunction")
|
|
48
|
+
fun getFunction(): JavaScriptFunction<Unit> {
|
|
49
|
+
return internalJniGetFunction<Unit>().apply {
|
|
50
|
+
returnType = typeOf<Unit>()
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
33
54
|
fun getInt() = getDouble().toInt()
|
|
34
55
|
fun getLong() = getDouble().toLong()
|
|
35
56
|
fun getFloat() = getDouble().toFloat()
|
|
36
57
|
|
|
37
58
|
@Throws(Throwable::class)
|
|
38
59
|
protected fun finalize() {
|
|
60
|
+
deallocate()
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
override fun deallocate() {
|
|
39
64
|
mHybridData.resetNative()
|
|
40
65
|
}
|
|
41
66
|
}
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
package expo.modules.kotlin.modules
|
|
2
2
|
|
|
3
3
|
import android.os.Bundle
|
|
4
|
-
import expo.modules.core.errors.ModuleDestroyedException
|
|
5
4
|
import expo.modules.kotlin.AppContext
|
|
6
5
|
import expo.modules.kotlin.providers.AppContextProvider
|
|
7
6
|
import kotlinx.coroutines.CoroutineScope
|
|
8
|
-
import kotlinx.coroutines.cancel
|
|
9
7
|
|
|
10
8
|
abstract class Module : AppContextProvider {
|
|
11
9
|
|
|
@@ -25,9 +23,6 @@ abstract class Module : AppContextProvider {
|
|
|
25
23
|
@PublishedApi
|
|
26
24
|
internal lateinit var coroutineScopeDelegate: Lazy<CoroutineScope>
|
|
27
25
|
|
|
28
|
-
@Deprecated(message = "Use a scope from the AppContext", replaceWith = ReplaceWith("appContext.modulesQueue"))
|
|
29
|
-
val coroutineScope get() = coroutineScopeDelegate.value
|
|
30
|
-
|
|
31
26
|
fun sendEvent(name: String, body: Bundle? = Bundle.EMPTY) {
|
|
32
27
|
moduleEventEmitter?.emit(name, body)
|
|
33
28
|
}
|
|
@@ -37,12 +32,6 @@ abstract class Module : AppContextProvider {
|
|
|
37
32
|
}
|
|
38
33
|
|
|
39
34
|
abstract fun definition(): ModuleDefinitionData
|
|
40
|
-
|
|
41
|
-
internal fun cleanUp() {
|
|
42
|
-
if (coroutineScopeDelegate.isInitialized()) {
|
|
43
|
-
coroutineScope.cancel(ModuleDestroyedException())
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
35
|
}
|
|
47
36
|
|
|
48
37
|
@Suppress("FunctionName")
|
|
@@ -6,6 +6,8 @@ import android.app.Activity
|
|
|
6
6
|
import android.content.Intent
|
|
7
7
|
import android.view.View
|
|
8
8
|
import expo.modules.kotlin.activityresult.AppContextActivityResultCaller
|
|
9
|
+
import expo.modules.kotlin.classcomponent.ClassComponentBuilder
|
|
10
|
+
import expo.modules.kotlin.classcomponent.ClassDefinitionData
|
|
9
11
|
import expo.modules.kotlin.events.BasicEventListener
|
|
10
12
|
import expo.modules.kotlin.events.EventListener
|
|
11
13
|
import expo.modules.kotlin.events.EventListenerWithPayload
|
|
@@ -13,10 +15,11 @@ import expo.modules.kotlin.events.EventListenerWithSenderAndPayload
|
|
|
13
15
|
import expo.modules.kotlin.events.EventName
|
|
14
16
|
import expo.modules.kotlin.events.OnActivityResultPayload
|
|
15
17
|
import expo.modules.kotlin.objects.ObjectDefinitionBuilder
|
|
18
|
+
import expo.modules.kotlin.sharedobjects.SharedObject
|
|
16
19
|
import expo.modules.kotlin.views.ViewDefinitionBuilder
|
|
17
20
|
import expo.modules.kotlin.views.ViewManagerDefinition
|
|
18
|
-
import expo.modules.kotlin.views.ViewManagerDefinitionBuilder
|
|
19
21
|
import kotlin.reflect.KClass
|
|
22
|
+
import kotlin.reflect.typeOf
|
|
20
23
|
|
|
21
24
|
@DefinitionMarker
|
|
22
25
|
class ModuleDefinitionBuilder(@PublishedApi internal val module: Module? = null) : ObjectDefinitionBuilder() {
|
|
@@ -31,6 +34,9 @@ class ModuleDefinitionBuilder(@PublishedApi internal val module: Module? = null)
|
|
|
31
34
|
@PublishedApi
|
|
32
35
|
internal var registerContracts: (suspend AppContextActivityResultCaller.() -> Unit)? = null
|
|
33
36
|
|
|
37
|
+
@PublishedApi
|
|
38
|
+
internal var classData = mutableListOf<ClassDefinitionData>()
|
|
39
|
+
|
|
34
40
|
fun buildModule(): ModuleDefinitionData {
|
|
35
41
|
val moduleName = name ?: module?.javaClass?.simpleName
|
|
36
42
|
|
|
@@ -39,7 +45,8 @@ class ModuleDefinitionBuilder(@PublishedApi internal val module: Module? = null)
|
|
|
39
45
|
buildObject(),
|
|
40
46
|
viewManagerDefinition,
|
|
41
47
|
eventListeners,
|
|
42
|
-
registerContracts
|
|
48
|
+
registerContracts,
|
|
49
|
+
classData
|
|
43
50
|
)
|
|
44
51
|
}
|
|
45
52
|
|
|
@@ -53,22 +60,10 @@ class ModuleDefinitionBuilder(@PublishedApi internal val module: Module? = null)
|
|
|
53
60
|
/**
|
|
54
61
|
* Creates the view manager definition that scopes other view-related definitions.
|
|
55
62
|
*/
|
|
56
|
-
|
|
57
|
-
inline fun ViewManager(body: ViewManagerDefinitionBuilder.() -> Unit) {
|
|
63
|
+
inline fun <reified T : View> View(viewClass: KClass<T>, body: ViewDefinitionBuilder<T>.() -> Unit) {
|
|
58
64
|
require(viewManagerDefinition == null) { "The module definition may have exported only one view manager." }
|
|
59
65
|
|
|
60
|
-
val
|
|
61
|
-
body.invoke(viewManagerDefinitionBuilder)
|
|
62
|
-
viewManagerDefinition = viewManagerDefinitionBuilder.build()
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Creates the view manager definition that scopes other view-related definitions.
|
|
67
|
-
*/
|
|
68
|
-
inline fun <T : View> View(viewType: KClass<T>, body: ViewDefinitionBuilder<T>.() -> Unit) {
|
|
69
|
-
require(viewManagerDefinition == null) { "The module definition may have exported only one view manager." }
|
|
70
|
-
|
|
71
|
-
val viewDefinitionBuilder = ViewDefinitionBuilder(viewType)
|
|
66
|
+
val viewDefinitionBuilder = ViewDefinitionBuilder(viewClass, typeOf<T>())
|
|
72
67
|
body.invoke(viewDefinitionBuilder)
|
|
73
68
|
viewManagerDefinition = viewDefinitionBuilder.build()
|
|
74
69
|
}
|
|
@@ -129,4 +124,19 @@ class ModuleDefinitionBuilder(@PublishedApi internal val module: Module? = null)
|
|
|
129
124
|
eventListeners[EventName.ON_ACTIVITY_RESULT] =
|
|
130
125
|
EventListenerWithSenderAndPayload<Activity, OnActivityResultPayload>(EventName.ON_ACTIVITY_RESULT) { sender, payload -> body(sender, payload) }
|
|
131
126
|
}
|
|
127
|
+
|
|
128
|
+
inline fun Class(name: String, body: ClassComponentBuilder<Unit>.() -> Unit = {}) {
|
|
129
|
+
val clazzBuilder = ClassComponentBuilder(name, Unit::class, typeOf<Unit>())
|
|
130
|
+
body.invoke(clazzBuilder)
|
|
131
|
+
classData.add(clazzBuilder.buildClass())
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
inline fun <reified SharedObjectType : SharedObject> Class(
|
|
135
|
+
sharedObjectClass: KClass<SharedObjectType>,
|
|
136
|
+
body: ClassComponentBuilder<SharedObjectType>.() -> Unit = {}
|
|
137
|
+
) {
|
|
138
|
+
val clazzBuilder = ClassComponentBuilder(sharedObjectClass.java.simpleName, sharedObjectClass, typeOf<SharedObjectType>())
|
|
139
|
+
body.invoke(clazzBuilder)
|
|
140
|
+
classData.add(clazzBuilder.buildClass())
|
|
141
|
+
}
|
|
132
142
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
package expo.modules.kotlin.modules
|
|
2
2
|
|
|
3
3
|
import expo.modules.kotlin.activityresult.AppContextActivityResultCaller
|
|
4
|
+
import expo.modules.kotlin.classcomponent.ClassDefinitionData
|
|
4
5
|
import expo.modules.kotlin.events.EventListener
|
|
5
6
|
import expo.modules.kotlin.events.EventName
|
|
6
7
|
import expo.modules.kotlin.objects.ObjectDefinitionData
|
|
@@ -11,7 +12,8 @@ class ModuleDefinitionData(
|
|
|
11
12
|
val objectDefinition: ObjectDefinitionData,
|
|
12
13
|
val viewManagerDefinition: ViewManagerDefinition? = null,
|
|
13
14
|
val eventListeners: Map<EventName, EventListener> = emptyMap(),
|
|
14
|
-
val registerContracts: (suspend AppContextActivityResultCaller.() -> Unit)? = null
|
|
15
|
+
val registerContracts: (suspend AppContextActivityResultCaller.() -> Unit)? = null,
|
|
16
|
+
val classData: List<ClassDefinitionData> = emptyList()
|
|
15
17
|
) {
|
|
16
18
|
|
|
17
19
|
val constantsProvider = objectDefinition.constantsProvider
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
package expo.modules.kotlin.sharedobjects
|
|
2
|
+
|
|
3
|
+
import expo.modules.core.interfaces.DoNotStrip
|
|
4
|
+
|
|
5
|
+
@DoNotStrip
|
|
6
|
+
open class SharedObject {
|
|
7
|
+
/**
|
|
8
|
+
* An identifier of the native shared object that maps to the JavaScript object.
|
|
9
|
+
* When the object is not linked with any JavaScript object, its value is 0.
|
|
10
|
+
*/
|
|
11
|
+
internal var sharedObjectId: SharedObjectId = SharedObjectId(0)
|
|
12
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
package expo.modules.kotlin.sharedobjects
|
|
2
|
+
|
|
3
|
+
import expo.modules.kotlin.jni.JavaScriptObject
|
|
4
|
+
|
|
5
|
+
@JvmInline
|
|
6
|
+
value class SharedObjectId(val value: Int)
|
|
7
|
+
|
|
8
|
+
// TODO(@lukmccall): use weak ref to hold js object
|
|
9
|
+
typealias SharedObjectPair = Pair<SharedObject, JavaScriptObject>
|
|
10
|
+
|
|
11
|
+
const val sharedObjectIdPropertyName = "__expo_shared_object_id__"
|
|
12
|
+
|
|
13
|
+
class SharedObjectRegistry {
|
|
14
|
+
private var currentId: SharedObjectId = SharedObjectId(1)
|
|
15
|
+
|
|
16
|
+
internal var pairs = mutableMapOf<SharedObjectId, SharedObjectPair>()
|
|
17
|
+
|
|
18
|
+
private fun pullNextId(): SharedObjectId {
|
|
19
|
+
val current = currentId
|
|
20
|
+
currentId = SharedObjectId(current.value + 1)
|
|
21
|
+
return current
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
internal fun add(native: SharedObject, js: JavaScriptObject): SharedObjectId {
|
|
25
|
+
val id = pullNextId()
|
|
26
|
+
native.sharedObjectId = id
|
|
27
|
+
js.defineProperty(sharedObjectIdPropertyName, id.value)
|
|
28
|
+
|
|
29
|
+
js.defineDeallocator {
|
|
30
|
+
delete(id)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
pairs[id] = native to js
|
|
34
|
+
return id
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
internal fun delete(id: SharedObjectId) {
|
|
38
|
+
pairs.remove(id)?.let { (native, js) ->
|
|
39
|
+
native.sharedObjectId = SharedObjectId(0)
|
|
40
|
+
if (js.isValid()) {
|
|
41
|
+
js.defineProperty(sharedObjectIdPropertyName, 0)
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
internal fun toNativeObject(id: SharedObjectId): SharedObject? {
|
|
47
|
+
return pairs[id]?.first
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
internal fun toNativeObject(js: JavaScriptObject): SharedObject? {
|
|
51
|
+
if (!js.hasProperty(sharedObjectIdPropertyName)) {
|
|
52
|
+
return null
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
val id = SharedObjectId(js.getProperty(sharedObjectIdPropertyName).getInt())
|
|
56
|
+
return pairs[id]?.first
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
internal fun toJavaScriptObjet(native: SharedObject): JavaScriptObject? {
|
|
60
|
+
return pairs[native.sharedObjectId]?.second
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
package expo.modules.kotlin.sharedobjects
|
|
2
|
+
|
|
3
|
+
import expo.modules.kotlin.AppContext
|
|
4
|
+
import expo.modules.kotlin.exception.InvalidSharedObjectException
|
|
5
|
+
import expo.modules.kotlin.jni.CppType
|
|
6
|
+
import expo.modules.kotlin.jni.ExpectedType
|
|
7
|
+
import expo.modules.kotlin.toStrongReference
|
|
8
|
+
import expo.modules.kotlin.types.NullAwareTypeConverter
|
|
9
|
+
import kotlin.reflect.KType
|
|
10
|
+
|
|
11
|
+
class SharedObjectTypeConverter<T : SharedObject>(
|
|
12
|
+
val type: KType
|
|
13
|
+
) : NullAwareTypeConverter<T>(type.isMarkedNullable) {
|
|
14
|
+
@Suppress("UNCHECKED_CAST")
|
|
15
|
+
override fun convertNonOptional(value: Any, context: AppContext?): T {
|
|
16
|
+
val id = SharedObjectId(value as Int)
|
|
17
|
+
val appContext = context.toStrongReference()
|
|
18
|
+
val result = appContext.sharedObjectRegistry.toNativeObject(id)
|
|
19
|
+
?: throw InvalidSharedObjectException(type)
|
|
20
|
+
|
|
21
|
+
return result as T
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
override fun getCppRequiredTypes() = ExpectedType(CppType.SHARED_OBJECT_ID)
|
|
25
|
+
|
|
26
|
+
override fun isTrivial(): Boolean = false
|
|
27
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
package expo.modules.kotlin.types
|
|
2
2
|
|
|
3
|
+
import expo.modules.kotlin.AppContext
|
|
3
4
|
import expo.modules.kotlin.jni.ExpectedType
|
|
4
5
|
import kotlin.reflect.KType
|
|
5
6
|
|
|
@@ -10,7 +11,7 @@ class AnyType(val kType: KType) {
|
|
|
10
11
|
TypeConverterProviderImpl.obtainTypeConverter(kType)
|
|
11
12
|
}
|
|
12
13
|
|
|
13
|
-
fun convert(value: Any?): Any? = converter.convert(value)
|
|
14
|
+
fun convert(value: Any?, appContext: AppContext? = null): Any? = converter.convert(value, appContext)
|
|
14
15
|
|
|
15
16
|
fun getCppRequiredTypes(): ExpectedType = converter.getCppRequiredTypes()
|
|
16
17
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
package expo.modules.kotlin.types
|
|
2
2
|
|
|
3
|
+
import expo.modules.kotlin.AppContext
|
|
3
4
|
import expo.modules.kotlin.apifeatures.EitherType
|
|
4
5
|
import expo.modules.kotlin.jni.ExpectedType
|
|
5
6
|
import expo.modules.kotlin.jni.SingleType
|
|
@@ -9,7 +10,7 @@ import kotlin.reflect.KType
|
|
|
9
10
|
class EitherTypeConverter<FirstType : Any, SecondType : Any>(
|
|
10
11
|
converterProvider: TypeConverterProvider,
|
|
11
12
|
eitherType: KType,
|
|
12
|
-
) :
|
|
13
|
+
) : NullAwareTypeConverter<Either<FirstType, SecondType>>(eitherType.isMarkedNullable) {
|
|
13
14
|
private val firstJavaType = requireNotNull(eitherType.arguments.getOrNull(0)?.type)
|
|
14
15
|
private val secondJavaType = requireNotNull(eitherType.arguments.getOrNull(1)?.type)
|
|
15
16
|
private val firstTypeConverter = converterProvider.obtainTypeConverter(
|
|
@@ -21,7 +22,7 @@ class EitherTypeConverter<FirstType : Any, SecondType : Any>(
|
|
|
21
22
|
private val firstType = firstTypeConverter.getCppRequiredTypes()
|
|
22
23
|
private val secondType = secondTypeConverter.getCppRequiredTypes()
|
|
23
24
|
|
|
24
|
-
override fun convertNonOptional(value: Any): Either<FirstType, SecondType> {
|
|
25
|
+
override fun convertNonOptional(value: Any, context: AppContext?): Either<FirstType, SecondType> {
|
|
25
26
|
val convertValueIfNeeded = Convert@{ types: Array<out SingleType>, converter: TypeConverter<*> ->
|
|
26
27
|
for (singleType in types) {
|
|
27
28
|
if (singleType.expectedCppType.clazz.isInstance(value)) {
|
|
@@ -54,7 +55,7 @@ class EitherTypeConverter<FirstType : Any, SecondType : Any>(
|
|
|
54
55
|
class EitherOfThreeTypeConverter<FirstType : Any, SecondType : Any, ThirdType : Any>(
|
|
55
56
|
converterProvider: TypeConverterProvider,
|
|
56
57
|
eitherType: KType,
|
|
57
|
-
) :
|
|
58
|
+
) : NullAwareTypeConverter<EitherOfThree<FirstType, SecondType, ThirdType>>(eitherType.isMarkedNullable) {
|
|
58
59
|
private val firstJavaType = requireNotNull(eitherType.arguments.getOrNull(0)?.type)
|
|
59
60
|
private val secondJavaType = requireNotNull(eitherType.arguments.getOrNull(1)?.type)
|
|
60
61
|
private val thirdJavaType = requireNotNull(eitherType.arguments.getOrNull(2)?.type)
|
|
@@ -71,7 +72,7 @@ class EitherOfThreeTypeConverter<FirstType : Any, SecondType : Any, ThirdType :
|
|
|
71
72
|
private val secondType = secondTypeConverter.getCppRequiredTypes()
|
|
72
73
|
private val thirdType = thirdTypeConverter.getCppRequiredTypes()
|
|
73
74
|
|
|
74
|
-
override fun convertNonOptional(value: Any): EitherOfThree<FirstType, SecondType, ThirdType> {
|
|
75
|
+
override fun convertNonOptional(value: Any, context: AppContext?): EitherOfThree<FirstType, SecondType, ThirdType> {
|
|
75
76
|
val convertValueIfNeeded = Convert@{ types: Array<out SingleType>, converter: TypeConverter<*> ->
|
|
76
77
|
for (singleType in types) {
|
|
77
78
|
if (singleType.expectedCppType.clazz.isInstance(value)) {
|
|
@@ -105,7 +106,7 @@ class EitherOfThreeTypeConverter<FirstType : Any, SecondType : Any, ThirdType :
|
|
|
105
106
|
class EitherOfFourTypeConverter<FirstType : Any, SecondType : Any, ThirdType : Any, FourthType : Any>(
|
|
106
107
|
converterProvider: TypeConverterProvider,
|
|
107
108
|
eitherType: KType,
|
|
108
|
-
) :
|
|
109
|
+
) : NullAwareTypeConverter<EitherOfFour<FirstType, SecondType, ThirdType, FourthType>>(eitherType.isMarkedNullable) {
|
|
109
110
|
private val firstJavaType = requireNotNull(eitherType.arguments.getOrNull(0)?.type)
|
|
110
111
|
private val secondJavaType = requireNotNull(eitherType.arguments.getOrNull(1)?.type)
|
|
111
112
|
private val thirdJavaType = requireNotNull(eitherType.arguments.getOrNull(2)?.type)
|
|
@@ -127,7 +128,7 @@ class EitherOfFourTypeConverter<FirstType : Any, SecondType : Any, ThirdType : A
|
|
|
127
128
|
private val thirdType = thirdTypeConverter.getCppRequiredTypes()
|
|
128
129
|
private val fourthType = fourthTypeConverter.getCppRequiredTypes()
|
|
129
130
|
|
|
130
|
-
override fun convertNonOptional(value: Any): EitherOfFour<FirstType, SecondType, ThirdType, FourthType> {
|
|
131
|
+
override fun convertNonOptional(value: Any, context: AppContext?): EitherOfFour<FirstType, SecondType, ThirdType, FourthType> {
|
|
131
132
|
val convertValueIfNeeded = Convert@{ types: Array<out SingleType>, converter: TypeConverter<*> ->
|
|
132
133
|
for (singleType in types) {
|
|
133
134
|
if (singleType.expectedCppType.clazz.isInstance(value)) {
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
package expo.modules.kotlin.types
|
|
2
|
+
|
|
3
|
+
import expo.modules.kotlin.AppContext
|
|
4
|
+
import expo.modules.kotlin.jni.CppType
|
|
5
|
+
import expo.modules.kotlin.jni.ExpectedType
|
|
6
|
+
import expo.modules.kotlin.jni.JavaScriptFunction
|
|
7
|
+
import kotlin.reflect.KType
|
|
8
|
+
|
|
9
|
+
class JavaScriptFunctionTypeConverter<T : Any>(
|
|
10
|
+
val type: KType
|
|
11
|
+
) : NullAwareTypeConverter<JavaScriptFunction<T>>(type.isMarkedNullable) {
|
|
12
|
+
override fun convertNonOptional(value: Any, context: AppContext?): JavaScriptFunction<T> {
|
|
13
|
+
@Suppress("UNCHECKED_CAST")
|
|
14
|
+
val jsFunction = value as JavaScriptFunction<T>
|
|
15
|
+
jsFunction.returnType = requireNotNull(type.arguments.first().type)
|
|
16
|
+
return jsFunction
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
override fun getCppRequiredTypes(): ExpectedType = ExpectedType(CppType.JS_FUNCTION)
|
|
20
|
+
|
|
21
|
+
override fun isTrivial(): Boolean = false
|
|
22
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
package expo.modules.kotlin.types
|
|
2
2
|
|
|
3
3
|
import com.facebook.react.bridge.Dynamic
|
|
4
|
+
import expo.modules.kotlin.AppContext
|
|
4
5
|
import expo.modules.kotlin.exception.NullArgumentException
|
|
5
6
|
import expo.modules.kotlin.exception.UnsupportedClass
|
|
6
7
|
import expo.modules.kotlin.jni.ExpectedType
|
|
@@ -9,30 +10,11 @@ import expo.modules.kotlin.jni.ExpectedType
|
|
|
9
10
|
* Basic type converter. It has to handle two different inputs - [Dynamic] and [Any].
|
|
10
11
|
* The first one is used in the bridge implementation. The second one is used in the JSI.
|
|
11
12
|
*/
|
|
12
|
-
abstract class TypeConverter<Type : Any>
|
|
13
|
-
/**
|
|
14
|
-
* Whether `null` can be assigned to the desired type.
|
|
15
|
-
*/
|
|
16
|
-
private val isOptional: Boolean
|
|
17
|
-
) {
|
|
13
|
+
abstract class TypeConverter<Type : Any> {
|
|
18
14
|
/**
|
|
19
15
|
* Tries to convert from [Any]? (can be also [Dynamic]) to the desired type.
|
|
20
16
|
*/
|
|
21
|
-
|
|
22
|
-
if (value == null || value is Dynamic && value.isNull) {
|
|
23
|
-
if (isOptional) {
|
|
24
|
-
return null
|
|
25
|
-
}
|
|
26
|
-
throw NullArgumentException()
|
|
27
|
-
}
|
|
28
|
-
return convertNonOptional(value)
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Tries to convert from [Any] to the desired type.
|
|
33
|
-
* We know in that place that we're not dealing with `null`.
|
|
34
|
-
*/
|
|
35
|
-
abstract fun convertNonOptional(value: Any): Type
|
|
17
|
+
abstract fun convert(value: Any?, context: AppContext? = null): Type?
|
|
36
18
|
|
|
37
19
|
/**
|
|
38
20
|
* Returns a list of [ExpectedType] types that can be converted to the desired type.
|
|
@@ -40,7 +22,7 @@ abstract class TypeConverter<Type : Any>(
|
|
|
40
22
|
* For instance js object can be pass as [Map] or [expo.modules.kotlin.jni.JavaScriptObject].
|
|
41
23
|
* This value tells us which one we should choose.
|
|
42
24
|
*/
|
|
43
|
-
|
|
25
|
+
open fun getCppRequiredTypes(): ExpectedType = ExpectedType.forAny()
|
|
44
26
|
|
|
45
27
|
/**
|
|
46
28
|
* Checks if the current converter is a trivial one.
|
|
@@ -50,13 +32,36 @@ abstract class TypeConverter<Type : Any>(
|
|
|
50
32
|
open fun isTrivial(): Boolean = true
|
|
51
33
|
}
|
|
52
34
|
|
|
35
|
+
abstract class NullAwareTypeConverter<Type : Any>(
|
|
36
|
+
/**
|
|
37
|
+
* Whether `null` can be assigned to the desired type.
|
|
38
|
+
*/
|
|
39
|
+
private val isOptional: Boolean
|
|
40
|
+
) : TypeConverter<Type>() {
|
|
41
|
+
override fun convert(value: Any?, context: AppContext?): Type? {
|
|
42
|
+
if (value == null || value is Dynamic && value.isNull) {
|
|
43
|
+
if (isOptional) {
|
|
44
|
+
return null
|
|
45
|
+
}
|
|
46
|
+
throw NullArgumentException()
|
|
47
|
+
}
|
|
48
|
+
return convertNonOptional(value, context)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Tries to convert from [Any] to the desired type.
|
|
53
|
+
* We know in that place that we're not dealing with `null`.
|
|
54
|
+
*/
|
|
55
|
+
abstract fun convertNonOptional(value: Any, context: AppContext?): Type
|
|
56
|
+
}
|
|
57
|
+
|
|
53
58
|
/**
|
|
54
59
|
* A helper class to make a clear separation between [Any] and [Dynamic].
|
|
55
60
|
* Right it is used as a default base class for all converters, but this will change when we
|
|
56
61
|
* stop using the bridge to pass data between JS and Kotlin.
|
|
57
62
|
*/
|
|
58
|
-
abstract class DynamicAwareTypeConverters<T : Any>(isOptional: Boolean) :
|
|
59
|
-
override fun convertNonOptional(value: Any): T =
|
|
63
|
+
abstract class DynamicAwareTypeConverters<T : Any>(isOptional: Boolean) : NullAwareTypeConverter<T>(isOptional) {
|
|
64
|
+
override fun convertNonOptional(value: Any, context: AppContext?): T =
|
|
60
65
|
if (value is Dynamic) {
|
|
61
66
|
convertFromDynamic(value)
|
|
62
67
|
} else {
|
|
@@ -75,6 +80,7 @@ inline fun <reified T : Any> createTrivialTypeConverter(
|
|
|
75
80
|
return object : DynamicAwareTypeConverters<T>(isOptional) {
|
|
76
81
|
override fun convertFromDynamic(value: Dynamic): T = dynamicFallback(value)
|
|
77
82
|
override fun getCppRequiredTypes(): ExpectedType = cppRequireType
|
|
83
|
+
|
|
78
84
|
@Suppress("UNCHECKED_CAST")
|
|
79
85
|
override fun convertFromAny(value: Any): T = value as T
|
|
80
86
|
}
|
|
@@ -4,17 +4,22 @@ package expo.modules.kotlin.types
|
|
|
4
4
|
|
|
5
5
|
import android.graphics.Color
|
|
6
6
|
import android.net.Uri
|
|
7
|
+
import android.view.View
|
|
7
8
|
import com.facebook.react.bridge.Dynamic
|
|
8
9
|
import com.facebook.react.bridge.ReadableArray
|
|
9
10
|
import com.facebook.react.bridge.ReadableMap
|
|
11
|
+
import expo.modules.annotation.Config
|
|
10
12
|
import expo.modules.kotlin.apifeatures.EitherType
|
|
11
13
|
import expo.modules.kotlin.exception.MissingTypeConverter
|
|
12
14
|
import expo.modules.kotlin.jni.CppType
|
|
13
15
|
import expo.modules.kotlin.jni.ExpectedType
|
|
16
|
+
import expo.modules.kotlin.jni.JavaScriptFunction
|
|
14
17
|
import expo.modules.kotlin.jni.JavaScriptObject
|
|
15
18
|
import expo.modules.kotlin.jni.JavaScriptValue
|
|
16
19
|
import expo.modules.kotlin.records.Record
|
|
17
20
|
import expo.modules.kotlin.records.RecordTypeConverter
|
|
21
|
+
import expo.modules.kotlin.sharedobjects.SharedObject
|
|
22
|
+
import expo.modules.kotlin.sharedobjects.SharedObjectTypeConverter
|
|
18
23
|
import expo.modules.kotlin.typedarray.BigInt64Array
|
|
19
24
|
import expo.modules.kotlin.typedarray.BigUint64Array
|
|
20
25
|
import expo.modules.kotlin.typedarray.Float32Array
|
|
@@ -32,6 +37,7 @@ import expo.modules.kotlin.types.io.PathTypeConverter
|
|
|
32
37
|
import expo.modules.kotlin.types.net.JavaURITypeConverter
|
|
33
38
|
import expo.modules.kotlin.types.net.URLTypConverter
|
|
34
39
|
import expo.modules.kotlin.types.net.UriTypeConverter
|
|
40
|
+
import expo.modules.kotlin.views.ViewTypeConverter
|
|
35
41
|
import java.io.File
|
|
36
42
|
import java.net.URI
|
|
37
43
|
import java.net.URL
|
|
@@ -69,6 +75,7 @@ fun convert(value: Dynamic, type: KType): Any? {
|
|
|
69
75
|
object TypeConverterProviderImpl : TypeConverterProvider {
|
|
70
76
|
private val cachedConverters = createCashedConverters(false) + createCashedConverters(true)
|
|
71
77
|
private val cachedRecordConverters = mutableMapOf<KClass<*>, TypeConverter<*>>()
|
|
78
|
+
private val cachedCustomConverters = mutableMapOf<KType, TypeConverter<*>>()
|
|
72
79
|
|
|
73
80
|
override fun obtainTypeConverter(type: KType): TypeConverter<*> {
|
|
74
81
|
cachedConverters[type]?.let {
|
|
@@ -113,7 +120,21 @@ object TypeConverterProviderImpl : TypeConverterProvider {
|
|
|
113
120
|
return converter
|
|
114
121
|
}
|
|
115
122
|
|
|
116
|
-
|
|
123
|
+
if (kClass.isSubclassOf(View::class)) {
|
|
124
|
+
return ViewTypeConverter<View>(type)
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (kClass.isSubclassOf(SharedObject::class)) {
|
|
128
|
+
return SharedObjectTypeConverter<SharedObject>(type)
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (kClass.isSubclassOf(JavaScriptFunction::class)) {
|
|
132
|
+
return JavaScriptFunctionTypeConverter<Any>(type)
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return handelEither(type, kClass)
|
|
136
|
+
?: handelCustomConverter(type, kClass)
|
|
137
|
+
?: throw MissingTypeConverter(type)
|
|
117
138
|
}
|
|
118
139
|
|
|
119
140
|
@OptIn(EitherType::class)
|
|
@@ -131,6 +152,29 @@ object TypeConverterProviderImpl : TypeConverterProvider {
|
|
|
131
152
|
return null
|
|
132
153
|
}
|
|
133
154
|
|
|
155
|
+
private fun handelCustomConverter(type: KType, kClass: KClass<*>): TypeConverter<*>? {
|
|
156
|
+
val cachedConverter = cachedCustomConverters[type]
|
|
157
|
+
if (cachedConverter != null) {
|
|
158
|
+
return cachedConverter
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
val typeName = kClass.java.canonicalName ?: return null
|
|
162
|
+
|
|
163
|
+
val converterProviderName = "${Config.packageNamePrefix}$typeName${Config.classNameSuffix}"
|
|
164
|
+
return try {
|
|
165
|
+
val converterClazz = Class.forName(converterProviderName)
|
|
166
|
+
val converterProvider = converterClazz.newInstance()
|
|
167
|
+
val method = converterProvider.javaClass.getMethod(Config.converterProviderFunctionName, KType::class.java)
|
|
168
|
+
|
|
169
|
+
(method.invoke(converterProvider, type) as TypeConverter<*>)
|
|
170
|
+
.also {
|
|
171
|
+
cachedCustomConverters[type] = it
|
|
172
|
+
}
|
|
173
|
+
} catch (e: Throwable) {
|
|
174
|
+
null
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
134
178
|
private fun createCashedConverters(isOptional: Boolean): Map<KType, TypeConverter<*>> {
|
|
135
179
|
val intTypeConverter = createTrivialTypeConverter(
|
|
136
180
|
isOptional, ExpectedType(CppType.INT)
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
package expo.modules.kotlin.types
|
|
2
2
|
|
|
3
|
+
import expo.modules.kotlin.AppContext
|
|
3
4
|
import expo.modules.kotlin.jni.CppType
|
|
4
5
|
import expo.modules.kotlin.jni.ExpectedType
|
|
5
6
|
import expo.modules.kotlin.jni.JavaScriptTypedArray
|
|
@@ -16,8 +17,8 @@ import expo.modules.kotlin.typedarray.Uint32Array
|
|
|
16
17
|
import expo.modules.kotlin.typedarray.Uint8Array
|
|
17
18
|
import expo.modules.kotlin.typedarray.Uint8ClampedArray
|
|
18
19
|
|
|
19
|
-
abstract class BaseTypeArrayConverter<T : TypedArray>(isOptional: Boolean) :
|
|
20
|
-
override fun convertNonOptional(value: Any): T = wrapJavaScriptTypedArray(value as JavaScriptTypedArray)
|
|
20
|
+
abstract class BaseTypeArrayConverter<T : TypedArray>(isOptional: Boolean) : NullAwareTypeConverter<T>(isOptional) {
|
|
21
|
+
override fun convertNonOptional(value: Any, context: AppContext?): T = wrapJavaScriptTypedArray(value as JavaScriptTypedArray)
|
|
21
22
|
override fun getCppRequiredTypes(): ExpectedType = ExpectedType(CppType.TYPED_ARRAY)
|
|
22
23
|
override fun isTrivial() = false
|
|
23
24
|
|
|
@@ -2,9 +2,11 @@ package expo.modules.kotlin.views
|
|
|
2
2
|
|
|
3
3
|
import android.view.View
|
|
4
4
|
import com.facebook.react.bridge.Dynamic
|
|
5
|
+
import expo.modules.kotlin.types.AnyType
|
|
5
6
|
|
|
6
7
|
abstract class AnyViewProp(
|
|
7
|
-
val name: String
|
|
8
|
+
val name: String,
|
|
9
|
+
internal val type: AnyType
|
|
8
10
|
) {
|
|
9
11
|
abstract fun set(prop: Dynamic, onView: View)
|
|
10
12
|
|
|
@@ -8,16 +8,16 @@ import expo.modules.kotlin.types.AnyType
|
|
|
8
8
|
|
|
9
9
|
class ConcreteViewProp<ViewType : View, PropType>(
|
|
10
10
|
name: String,
|
|
11
|
-
|
|
11
|
+
propType: AnyType,
|
|
12
12
|
private val setter: (view: ViewType, prop: PropType) -> Unit,
|
|
13
|
-
) : AnyViewProp(name) {
|
|
13
|
+
) : AnyViewProp(name, propType) {
|
|
14
14
|
|
|
15
15
|
@Suppress("UNCHECKED_CAST")
|
|
16
16
|
override fun set(prop: Dynamic, onView: View) {
|
|
17
17
|
exceptionDecorator({
|
|
18
18
|
PropSetException(name, onView::class, it)
|
|
19
19
|
}) {
|
|
20
|
-
setter(onView as ViewType,
|
|
20
|
+
setter(onView as ViewType, type.convert(prop) as PropType)
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
23
|
|