expo-modules-core 1.2.6 → 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 +33 -4
- 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 +18 -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 +34 -21
- package/android/src/main/java/expo/modules/kotlin/ModuleRegistry.kt +13 -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 -4
- 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 +7 -8
- 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
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
package expo.modules.kotlin.jni
|
|
2
2
|
|
|
3
3
|
import com.facebook.jni.HybridData
|
|
4
|
+
import com.facebook.react.bridge.Arguments
|
|
4
5
|
import com.facebook.react.bridge.NativeMap
|
|
5
6
|
import expo.modules.core.interfaces.DoNotStrip
|
|
7
|
+
import expo.modules.kotlin.AppContext
|
|
8
|
+
import expo.modules.kotlin.objects.ObjectDefinitionData
|
|
6
9
|
|
|
7
10
|
/**
|
|
8
11
|
* A class to communicate with CPP part of the [expo.modules.kotlin.modules.Module] class.
|
|
@@ -13,13 +16,35 @@ import expo.modules.core.interfaces.DoNotStrip
|
|
|
13
16
|
*/
|
|
14
17
|
@Suppress("KotlinJniMissingFunction")
|
|
15
18
|
@DoNotStrip
|
|
16
|
-
class JavaScriptModuleObject(val name: String) {
|
|
19
|
+
class JavaScriptModuleObject(val name: String) : Destructible {
|
|
17
20
|
// Has to be called "mHybridData" - fbjni uses it via reflection
|
|
18
21
|
@DoNotStrip
|
|
19
22
|
private val mHybridData = initHybrid()
|
|
20
23
|
|
|
21
24
|
private external fun initHybrid(): HybridData
|
|
22
25
|
|
|
26
|
+
init {
|
|
27
|
+
JNIDeallocator.addReference(this)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
fun initUsingObjectDefinition(appContext: AppContext, definition: ObjectDefinitionData) = apply {
|
|
31
|
+
val constants = definition.constantsProvider()
|
|
32
|
+
val convertedConstants = Arguments.makeNativeMap(constants)
|
|
33
|
+
exportConstants(convertedConstants)
|
|
34
|
+
|
|
35
|
+
definition
|
|
36
|
+
.functions
|
|
37
|
+
.forEach { function ->
|
|
38
|
+
function.attachToJSObject(appContext, this)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
definition
|
|
42
|
+
.properties
|
|
43
|
+
.forEach { (_, prop) ->
|
|
44
|
+
prop.attachToJSObject(this)
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
23
48
|
/**
|
|
24
49
|
* Exports constants
|
|
25
50
|
*/
|
|
@@ -29,18 +54,30 @@ class JavaScriptModuleObject(val name: String) {
|
|
|
29
54
|
* Register a promise-less function on the CPP module representation.
|
|
30
55
|
* After calling this function, user can access the exported function in the JS code.
|
|
31
56
|
*/
|
|
32
|
-
external fun registerSyncFunction(name: String, args: Int, desiredTypes: Array<ExpectedType>, body: JNIFunctionBody)
|
|
57
|
+
external fun registerSyncFunction(name: String, takesOwner: Boolean, args: Int, desiredTypes: Array<ExpectedType>, body: JNIFunctionBody)
|
|
33
58
|
|
|
34
59
|
/**
|
|
35
60
|
* Register a promise function on the CPP module representation.
|
|
36
61
|
* After calling this function, user can access the exported function in the JS code.
|
|
37
62
|
*/
|
|
38
|
-
external fun registerAsyncFunction(name: String, args: Int, desiredTypes: Array<ExpectedType>, body: JNIAsyncFunctionBody)
|
|
63
|
+
external fun registerAsyncFunction(name: String, takesOwner: Boolean, args: Int, desiredTypes: Array<ExpectedType>, body: JNIAsyncFunctionBody)
|
|
39
64
|
|
|
40
65
|
external fun registerProperty(name: String, desiredType: ExpectedType, getter: JNIFunctionBody?, setter: JNIFunctionBody?)
|
|
41
66
|
|
|
67
|
+
external fun registerClass(name: String, classModule: JavaScriptModuleObject, takesOwner: Boolean, args: Int, desiredTypes: Array<ExpectedType>, body: JNIFunctionBody)
|
|
68
|
+
|
|
69
|
+
external fun registerViewPrototype(viewPrototype: JavaScriptModuleObject)
|
|
70
|
+
|
|
42
71
|
@Throws(Throwable::class)
|
|
43
72
|
protected fun finalize() {
|
|
73
|
+
deallocate()
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
override fun deallocate() {
|
|
44
77
|
mHybridData.resetNative()
|
|
45
78
|
}
|
|
79
|
+
|
|
80
|
+
override fun toString(): String {
|
|
81
|
+
return "JavaScriptModuleObject_$name"
|
|
82
|
+
}
|
|
46
83
|
}
|
|
@@ -9,7 +9,12 @@ import expo.modules.core.interfaces.DoNotStrip
|
|
|
9
9
|
*/
|
|
10
10
|
@Suppress("KotlinJniMissingFunction")
|
|
11
11
|
@DoNotStrip
|
|
12
|
-
open class JavaScriptObject @DoNotStrip internal constructor(@DoNotStrip private val mHybridData: HybridData) {
|
|
12
|
+
open class JavaScriptObject @DoNotStrip internal constructor(@DoNotStrip private val mHybridData: HybridData) : Destructible {
|
|
13
|
+
init {
|
|
14
|
+
@Suppress("LeakingThis")
|
|
15
|
+
JNIDeallocator.addReference(this)
|
|
16
|
+
}
|
|
17
|
+
|
|
13
18
|
/**
|
|
14
19
|
* The property descriptor options for the property being defined or modified.
|
|
15
20
|
*/
|
|
@@ -30,23 +35,34 @@ open class JavaScriptObject @DoNotStrip internal constructor(@DoNotStrip private
|
|
|
30
35
|
Writable(1 shl 2),
|
|
31
36
|
}
|
|
32
37
|
|
|
38
|
+
fun isValid() = mHybridData.isValid
|
|
39
|
+
|
|
33
40
|
external fun hasProperty(name: String): Boolean
|
|
34
41
|
external fun getProperty(name: String): JavaScriptValue
|
|
35
|
-
external fun getPropertyNames(): Array<String>
|
|
36
42
|
|
|
43
|
+
external fun getPropertyNames(): Array<String>
|
|
37
44
|
private external fun setBoolProperty(name: String, value: Boolean)
|
|
38
45
|
private external fun setDoubleProperty(name: String, value: Double)
|
|
39
46
|
private external fun setStringProperty(name: String, value: String?)
|
|
40
47
|
private external fun setJSValueProperty(name: String, value: JavaScriptValue?)
|
|
41
48
|
private external fun setJSObjectProperty(name: String, value: JavaScriptObject?)
|
|
42
|
-
private external fun unsetProperty(name: String)
|
|
43
49
|
|
|
50
|
+
private external fun unsetProperty(name: String)
|
|
44
51
|
private external fun defineBoolProperty(name: String, value: Boolean, options: Int)
|
|
45
52
|
private external fun defineDoubleProperty(name: String, value: Double, options: Int)
|
|
46
53
|
private external fun defineStringProperty(name: String, value: String?, options: Int)
|
|
47
54
|
private external fun defineJSValueProperty(name: String, value: JavaScriptValue?, options: Int)
|
|
55
|
+
|
|
48
56
|
private external fun defineJSObjectProperty(name: String, value: JavaScriptObject?, options: Int)
|
|
49
57
|
|
|
58
|
+
private external fun defineNativeDeallocator(deallocator: JNIFunctionBody)
|
|
59
|
+
|
|
60
|
+
internal fun defineDeallocator(deallocator: () -> Unit) {
|
|
61
|
+
defineNativeDeallocator {
|
|
62
|
+
deallocator()
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
50
66
|
fun setProperty(name: String, value: Boolean) = setBoolProperty(name, value)
|
|
51
67
|
fun setProperty(name: String, value: Int) = setDoubleProperty(name, value.toDouble())
|
|
52
68
|
fun setProperty(name: String, value: Double) = setDoubleProperty(name, value)
|
|
@@ -103,6 +119,10 @@ open class JavaScriptObject @DoNotStrip internal constructor(@DoNotStrip private
|
|
|
103
119
|
|
|
104
120
|
@Throws(Throwable::class)
|
|
105
121
|
protected fun finalize() {
|
|
122
|
+
deallocate()
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
override fun deallocate() {
|
|
106
126
|
mHybridData.resetNative()
|
|
107
127
|
}
|
|
108
128
|
}
|
|
@@ -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
|
}
|