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
|
@@ -7,6 +7,12 @@ import kotlin.reflect.KClass
|
|
|
7
7
|
import kotlin.reflect.KProperty1
|
|
8
8
|
import kotlin.reflect.KType
|
|
9
9
|
|
|
10
|
+
@Suppress("NOTHING_TO_INLINE")
|
|
11
|
+
inline fun Throwable.toCodedException() = when (this) {
|
|
12
|
+
is CodedException -> this
|
|
13
|
+
else -> UnexpectedException(this)
|
|
14
|
+
}
|
|
15
|
+
|
|
10
16
|
/**
|
|
11
17
|
* A class for errors specifying its `code` and providing the `description`.
|
|
12
18
|
*/
|
|
@@ -85,6 +91,7 @@ internal class MissingTypeConverter(
|
|
|
85
91
|
message = "Cannot find type converter for '$forType'.",
|
|
86
92
|
)
|
|
87
93
|
|
|
94
|
+
@DoNotStrip
|
|
88
95
|
internal class InvalidArgsNumberException(received: Int, expected: Int, required: Int = expected) :
|
|
89
96
|
CodedException(
|
|
90
97
|
message = if (required < expected) {
|
|
@@ -145,6 +152,14 @@ internal class PropSetException(
|
|
|
145
152
|
cause,
|
|
146
153
|
)
|
|
147
154
|
|
|
155
|
+
internal class OnViewDidUpdatePropsException(
|
|
156
|
+
viewType: KClass<*>,
|
|
157
|
+
cause: CodedException
|
|
158
|
+
) : DecoratedException(
|
|
159
|
+
message = "Error occurred when invoking 'onViewDidUpdateProps' on '${viewType.simpleName}'",
|
|
160
|
+
cause
|
|
161
|
+
)
|
|
162
|
+
|
|
148
163
|
internal class ArgumentCastException(
|
|
149
164
|
argDesiredType: KType,
|
|
150
165
|
argIndex: Int,
|
|
@@ -165,6 +180,12 @@ internal class ArgumentCastException(
|
|
|
165
180
|
}
|
|
166
181
|
}
|
|
167
182
|
|
|
183
|
+
internal class InvalidSharedObjectException(
|
|
184
|
+
sharedType: KType,
|
|
185
|
+
) : CodedException(
|
|
186
|
+
message = "Cannot convert provided JavaScriptObject to the '$sharedType', because it doesn't contain valid id"
|
|
187
|
+
)
|
|
188
|
+
|
|
168
189
|
internal class FieldCastException(
|
|
169
190
|
fieldName: String,
|
|
170
191
|
fieldType: KType,
|
|
@@ -14,6 +14,11 @@ class Exceptions {
|
|
|
14
14
|
viewTag: Int
|
|
15
15
|
) : CodedException(message = "Unable to find the $viewType view with tag $viewTag")
|
|
16
16
|
|
|
17
|
+
/**
|
|
18
|
+
* The app context is no longer available.
|
|
19
|
+
*/
|
|
20
|
+
class AppContextLost : CodedException(message = "The app context has been lost")
|
|
21
|
+
|
|
17
22
|
/**
|
|
18
23
|
* The react app context is no longer available.
|
|
19
24
|
*/
|
|
@@ -43,4 +48,14 @@ class Exceptions {
|
|
|
43
48
|
* An exception to throw when the current Android activity is not longer available.
|
|
44
49
|
*/
|
|
45
50
|
class MissingActivity : CodedException(message = "The current activity is no longer available")
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* An exception to throw when function was called on the incorrect thread.
|
|
54
|
+
*/
|
|
55
|
+
class IncorrectThreadException(
|
|
56
|
+
currentThreadName: String,
|
|
57
|
+
expectedThreadName: String
|
|
58
|
+
) : CodedException(
|
|
59
|
+
message = "Expected to run on $expectedThreadName thread, but was run on $currentThreadName"
|
|
60
|
+
)
|
|
46
61
|
}
|
|
@@ -9,8 +9,12 @@ import expo.modules.kotlin.exception.exceptionDecorator
|
|
|
9
9
|
import expo.modules.kotlin.iterator
|
|
10
10
|
import expo.modules.kotlin.jni.ExpectedType
|
|
11
11
|
import expo.modules.kotlin.jni.JavaScriptModuleObject
|
|
12
|
+
import expo.modules.kotlin.jni.JavaScriptObject
|
|
12
13
|
import expo.modules.kotlin.recycle
|
|
13
14
|
import expo.modules.kotlin.types.AnyType
|
|
15
|
+
import kotlin.reflect.KType
|
|
16
|
+
import kotlin.reflect.full.isSubtypeOf
|
|
17
|
+
import kotlin.reflect.typeOf
|
|
14
18
|
|
|
15
19
|
/**
|
|
16
20
|
* Base class of all exported functions
|
|
@@ -21,6 +25,16 @@ abstract class AnyFunction(
|
|
|
21
25
|
) {
|
|
22
26
|
internal val argsCount get() = desiredArgsTypes.size
|
|
23
27
|
|
|
28
|
+
internal var canTakeOwner: Boolean = false
|
|
29
|
+
|
|
30
|
+
@PublishedApi
|
|
31
|
+
internal var ownerType: KType? = null
|
|
32
|
+
|
|
33
|
+
internal val takesOwner: Boolean
|
|
34
|
+
get() = canTakeOwner &&
|
|
35
|
+
desiredArgsTypes.firstOrNull()?.kType?.isSubtypeOf(typeOf<JavaScriptObject>()) == true ||
|
|
36
|
+
(ownerType != null && desiredArgsTypes.firstOrNull()?.kType?.isSubtypeOf(ownerType!!) == true)
|
|
37
|
+
|
|
24
38
|
/**
|
|
25
39
|
* A minimum number of arguments the functions needs which equals to `argumentsCount` reduced by the number of trailing optional arguments.
|
|
26
40
|
*/
|
|
@@ -29,7 +43,7 @@ abstract class AnyFunction(
|
|
|
29
43
|
.reversed()
|
|
30
44
|
.indexOfFirst { !it.kType.isMarkedNullable }
|
|
31
45
|
if (nonNullableArgIndex < 0) {
|
|
32
|
-
return@run
|
|
46
|
+
return@run 0
|
|
33
47
|
}
|
|
34
48
|
|
|
35
49
|
return@run desiredArgsTypes.size - nonNullableArgIndex
|
|
@@ -69,7 +83,7 @@ abstract class AnyFunction(
|
|
|
69
83
|
* @throws `CodedException` if conversion isn't possible
|
|
70
84
|
*/
|
|
71
85
|
@Throws(CodedException::class)
|
|
72
|
-
protected fun convertArgs(args: Array<Any
|
|
86
|
+
protected fun convertArgs(args: Array<Any?>, appContext: AppContext? = null): Array<out Any?> {
|
|
73
87
|
if (requiredArgumentsCount > args.size || args.size > desiredArgsTypes.size) {
|
|
74
88
|
throw InvalidArgsNumberException(args.size, desiredArgsTypes.size, requiredArgumentsCount)
|
|
75
89
|
}
|
|
@@ -82,7 +96,7 @@ abstract class AnyFunction(
|
|
|
82
96
|
exceptionDecorator({ cause ->
|
|
83
97
|
ArgumentCastException(desiredType.kType, index, element?.javaClass.toString(), cause)
|
|
84
98
|
}) {
|
|
85
|
-
finalArgs[index] = desiredType.convert(element)
|
|
99
|
+
finalArgs[index] = desiredType.convert(element, appContext)
|
|
86
100
|
}
|
|
87
101
|
}
|
|
88
102
|
return finalArgs
|
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
package expo.modules.kotlin.functions
|
|
2
2
|
|
|
3
|
+
import com.facebook.react.bridge.ReactContext
|
|
3
4
|
import com.facebook.react.bridge.ReadableArray
|
|
5
|
+
import com.facebook.react.uimanager.UIManagerHelper
|
|
6
|
+
import com.facebook.react.uimanager.UIManagerModule
|
|
7
|
+
import com.facebook.react.uimanager.common.UIManagerType
|
|
8
|
+
import expo.modules.BuildConfig
|
|
4
9
|
import expo.modules.kotlin.AppContext
|
|
5
10
|
import expo.modules.kotlin.ModuleHolder
|
|
6
11
|
import expo.modules.kotlin.Promise
|
|
7
12
|
import expo.modules.kotlin.exception.CodedException
|
|
13
|
+
import expo.modules.kotlin.exception.Exceptions
|
|
8
14
|
import expo.modules.kotlin.exception.FunctionCallException
|
|
9
15
|
import expo.modules.kotlin.exception.UnexpectedException
|
|
10
16
|
import expo.modules.kotlin.exception.exceptionDecorator
|
|
@@ -48,25 +54,21 @@ abstract class AsyncFunction(
|
|
|
48
54
|
@Throws(CodedException::class)
|
|
49
55
|
internal abstract fun callUserImplementation(args: ReadableArray, promise: Promise)
|
|
50
56
|
|
|
51
|
-
internal abstract fun callUserImplementation(args: Array<Any?>, promise: Promise)
|
|
57
|
+
internal abstract fun callUserImplementation(args: Array<Any?>, promise: Promise, appContext: AppContext)
|
|
52
58
|
|
|
53
59
|
override fun attachToJSObject(appContext: AppContext, jsObject: JavaScriptModuleObject) {
|
|
54
60
|
jsObject.registerAsyncFunction(
|
|
55
61
|
name,
|
|
62
|
+
takesOwner,
|
|
56
63
|
argsCount,
|
|
57
64
|
desiredArgsTypes.map { it.getCppRequiredTypes() }.toTypedArray()
|
|
58
65
|
) { args, bridgePromise ->
|
|
59
|
-
val
|
|
60
|
-
Queues.MAIN -> appContext.mainQueue
|
|
61
|
-
Queues.DEFAULT -> appContext.modulesQueue
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
queue.launch {
|
|
66
|
+
val functionBody = {
|
|
65
67
|
try {
|
|
66
68
|
exceptionDecorator({
|
|
67
69
|
FunctionCallException(name, jsObject.name, it)
|
|
68
70
|
}) {
|
|
69
|
-
callUserImplementation(args, bridgePromise)
|
|
71
|
+
callUserImplementation(args, bridgePromise, appContext)
|
|
70
72
|
}
|
|
71
73
|
} catch (e: CodedException) {
|
|
72
74
|
bridgePromise.reject(e)
|
|
@@ -74,6 +76,34 @@ abstract class AsyncFunction(
|
|
|
74
76
|
bridgePromise.reject(UnexpectedException(e))
|
|
75
77
|
}
|
|
76
78
|
}
|
|
79
|
+
|
|
80
|
+
if (queue == Queues.MAIN) {
|
|
81
|
+
if (!BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
|
|
82
|
+
// On certain occasions, invoking a function on a view could lead to an error
|
|
83
|
+
// because of the asynchronous communication between the JavaScript and native components.
|
|
84
|
+
// In such cases, the native view may not have been mounted yet,
|
|
85
|
+
// but the JavaScript code has already received the future tag of the view.
|
|
86
|
+
// To avoid this issue, we have decided to temporarily utilize
|
|
87
|
+
// the UIManagerModule for dispatching functions on the main thread.
|
|
88
|
+
val uiManager = UIManagerHelper.getUIManagerForReactTag(
|
|
89
|
+
appContext.reactContext as? ReactContext ?: throw Exceptions.ReactContextLost(),
|
|
90
|
+
UIManagerType.DEFAULT
|
|
91
|
+
) as UIManagerModule
|
|
92
|
+
|
|
93
|
+
uiManager.addUIBlock {
|
|
94
|
+
functionBody()
|
|
95
|
+
}
|
|
96
|
+
return@registerAsyncFunction
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
appContext.mainQueue.launch {
|
|
100
|
+
functionBody()
|
|
101
|
+
}
|
|
102
|
+
} else {
|
|
103
|
+
appContext.modulesQueue.launch {
|
|
104
|
+
functionBody()
|
|
105
|
+
}
|
|
106
|
+
}
|
|
77
107
|
}
|
|
78
108
|
}
|
|
79
109
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
package expo.modules.kotlin.functions
|
|
2
2
|
|
|
3
3
|
import com.facebook.react.bridge.ReadableArray
|
|
4
|
+
import expo.modules.kotlin.AppContext
|
|
4
5
|
import expo.modules.kotlin.Promise
|
|
5
6
|
import expo.modules.kotlin.exception.CodedException
|
|
6
7
|
import expo.modules.kotlin.types.AnyType
|
|
@@ -15,7 +16,7 @@ class AsyncFunctionComponent(
|
|
|
15
16
|
promise.resolve(body(convertArgs(args)))
|
|
16
17
|
}
|
|
17
18
|
|
|
18
|
-
override fun callUserImplementation(args: Array<Any?>, promise: Promise) {
|
|
19
|
-
promise.resolve(body(convertArgs(args)))
|
|
19
|
+
override fun callUserImplementation(args: Array<Any?>, promise: Promise, appContext: AppContext) {
|
|
20
|
+
promise.resolve(body(convertArgs(args, appContext)))
|
|
20
21
|
}
|
|
21
22
|
}
|
package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionWithPromiseComponent.kt
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
package expo.modules.kotlin.functions
|
|
2
2
|
|
|
3
3
|
import com.facebook.react.bridge.ReadableArray
|
|
4
|
+
import expo.modules.kotlin.AppContext
|
|
4
5
|
import expo.modules.kotlin.Promise
|
|
5
6
|
import expo.modules.kotlin.exception.CodedException
|
|
6
7
|
import expo.modules.kotlin.types.AnyType
|
|
@@ -15,7 +16,7 @@ class AsyncFunctionWithPromiseComponent(
|
|
|
15
16
|
body(convertArgs(args), promise)
|
|
16
17
|
}
|
|
17
18
|
|
|
18
|
-
override fun callUserImplementation(args: Array<Any?>, promise: Promise) {
|
|
19
|
-
body(convertArgs(args), promise)
|
|
19
|
+
override fun callUserImplementation(args: Array<Any?>, promise: Promise, appContext: AppContext) {
|
|
20
|
+
body(convertArgs(args, appContext), promise)
|
|
20
21
|
}
|
|
21
22
|
}
|
|
@@ -48,6 +48,7 @@ class SuspendFunctionComponent(
|
|
|
48
48
|
override fun attachToJSObject(appContext: AppContext, jsObject: JavaScriptModuleObject) {
|
|
49
49
|
jsObject.registerAsyncFunction(
|
|
50
50
|
name,
|
|
51
|
+
takesOwner,
|
|
51
52
|
argsCount,
|
|
52
53
|
desiredArgsTypes.map { it.getCppRequiredTypes() }.toTypedArray()
|
|
53
54
|
) { args, bridgePromise ->
|
|
@@ -5,6 +5,7 @@ import expo.modules.kotlin.AppContext
|
|
|
5
5
|
import expo.modules.kotlin.exception.CodedException
|
|
6
6
|
import expo.modules.kotlin.exception.FunctionCallException
|
|
7
7
|
import expo.modules.kotlin.exception.exceptionDecorator
|
|
8
|
+
import expo.modules.kotlin.jni.JNIFunctionBody
|
|
8
9
|
import expo.modules.kotlin.jni.JavaScriptModuleObject
|
|
9
10
|
import expo.modules.kotlin.types.AnyType
|
|
10
11
|
import expo.modules.kotlin.types.JSTypeConverter
|
|
@@ -19,22 +20,28 @@ class SyncFunctionComponent(
|
|
|
19
20
|
return body(convertArgs(args))
|
|
20
21
|
}
|
|
21
22
|
|
|
22
|
-
fun call(args: Array<Any
|
|
23
|
-
return body(convertArgs(args))
|
|
23
|
+
fun call(args: Array<Any?>, appContext: AppContext? = null): Any? {
|
|
24
|
+
return body(convertArgs(args, appContext))
|
|
24
25
|
}
|
|
25
26
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
getCppRequiredTypes().toTypedArray()
|
|
31
|
-
) { args ->
|
|
32
|
-
return@registerSyncFunction exceptionDecorator({
|
|
33
|
-
FunctionCallException(name, jsObject.name, it)
|
|
27
|
+
internal fun getJNIFunctionBody(moduleName: String, appContext: AppContext?): JNIFunctionBody {
|
|
28
|
+
return JNIFunctionBody { args ->
|
|
29
|
+
return@JNIFunctionBody exceptionDecorator({
|
|
30
|
+
FunctionCallException(name, moduleName, it)
|
|
34
31
|
}) {
|
|
35
|
-
val result = call(args)
|
|
32
|
+
val result = call(args, appContext)
|
|
36
33
|
return@exceptionDecorator JSTypeConverter.convertToJSValue(result)
|
|
37
34
|
}
|
|
38
35
|
}
|
|
39
36
|
}
|
|
37
|
+
|
|
38
|
+
override fun attachToJSObject(appContext: AppContext, jsObject: JavaScriptModuleObject) {
|
|
39
|
+
jsObject.registerSyncFunction(
|
|
40
|
+
name,
|
|
41
|
+
takesOwner,
|
|
42
|
+
argsCount,
|
|
43
|
+
getCppRequiredTypes().toTypedArray(),
|
|
44
|
+
getJNIFunctionBody(jsObject.name, appContext)
|
|
45
|
+
)
|
|
46
|
+
}
|
|
40
47
|
}
|
|
@@ -27,5 +27,8 @@ enum class CppType(val clazz: KClass<*>, val value: Int = nextValue()) {
|
|
|
27
27
|
TYPED_ARRAY(TypedArray::class),
|
|
28
28
|
PRIMITIVE_ARRAY(Array::class),
|
|
29
29
|
LIST(List::class),
|
|
30
|
-
MAP(Map::class)
|
|
30
|
+
MAP(Map::class),
|
|
31
|
+
VIEW_TAG(Int::class),
|
|
32
|
+
SHARED_OBJECT_ID(Int::class),
|
|
33
|
+
JS_FUNCTION(JavaScriptFunction::class);
|
|
31
34
|
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
package expo.modules.kotlin.jni
|
|
2
|
+
|
|
3
|
+
import java.lang.ref.PhantomReference
|
|
4
|
+
import java.lang.ref.ReferenceQueue
|
|
5
|
+
import java.lang.ref.WeakReference
|
|
6
|
+
|
|
7
|
+
interface Destructible {
|
|
8
|
+
fun deallocate()
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
object JNIDeallocator {
|
|
12
|
+
/**
|
|
13
|
+
* A [PhantomReference] queue managed by JVM
|
|
14
|
+
*/
|
|
15
|
+
private val referenceQueue = ReferenceQueue<Destructible>()
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* A registry to keep all active [Destructible] objects and their [PhantomReference]s
|
|
19
|
+
*/
|
|
20
|
+
private val destructorMap = mutableMapOf<PhantomReference<Destructible>, WeakReference<Destructible>>()
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* A thread that clears your registry when an object has been garbage collected
|
|
24
|
+
* to not store invalid references to every created object.
|
|
25
|
+
*/
|
|
26
|
+
private val destructorThread = object : Thread("Expo JNI deallocator") {
|
|
27
|
+
override fun run() {
|
|
28
|
+
while (true) {
|
|
29
|
+
try {
|
|
30
|
+
// Referent of PhantomReference were garbage collected so we can remove it from our registry.
|
|
31
|
+
// Note that we don't have to call `deallocate` method - it was called [com.facebook.jni.HybridData].
|
|
32
|
+
val current = referenceQueue.remove()
|
|
33
|
+
synchronized(this) {
|
|
34
|
+
destructorMap.remove(current)
|
|
35
|
+
}
|
|
36
|
+
} catch (e: InterruptedException) {
|
|
37
|
+
// Continue. This thread should never be terminated.
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}.also {
|
|
42
|
+
it.start()
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Adds reference to the internal registry.
|
|
47
|
+
* That reference will be deallocated when [JNIDeallocator.deallocate] is called or
|
|
48
|
+
* when the reference won't be reachable by the GC.
|
|
49
|
+
*/
|
|
50
|
+
internal fun addReference(destructible: Destructible) = synchronized(this) {
|
|
51
|
+
val weakRef = WeakReference(destructible)
|
|
52
|
+
val phantomRef = PhantomReference(destructible, referenceQueue)
|
|
53
|
+
destructorMap[phantomRef] = weakRef
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Deallocates valid references and clears the internal registry.
|
|
58
|
+
*/
|
|
59
|
+
internal fun deallocate() = synchronized(this) {
|
|
60
|
+
destructorMap.values.forEach {
|
|
61
|
+
it.get()?.deallocate()
|
|
62
|
+
}
|
|
63
|
+
destructorMap.clear()
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Returns references to all hybrid objects that contain references to the jsi value
|
|
68
|
+
* and are present in the memory.
|
|
69
|
+
*/
|
|
70
|
+
fun inspectMemory() = synchronized(this) {
|
|
71
|
+
destructorMap.values.mapNotNull { it.get() }
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -6,12 +6,19 @@ import com.facebook.soloader.SoLoader
|
|
|
6
6
|
import expo.modules.core.interfaces.DoNotStrip
|
|
7
7
|
import expo.modules.kotlin.AppContext
|
|
8
8
|
import expo.modules.kotlin.exception.JavaScriptEvaluateException
|
|
9
|
+
import expo.modules.kotlin.sharedobjects.SharedObject
|
|
9
10
|
import java.lang.ref.WeakReference
|
|
10
11
|
|
|
12
|
+
/**
|
|
13
|
+
* Despite the fact that this class is marked as [Destructible], it is not included in the [JNIDeallocator].
|
|
14
|
+
* The deallocation of the [JSIInteropModuleRegistry] should be performed at the very end
|
|
15
|
+
* to prevent the destructor of the [Destructible] object from accessing data that has already been freed.
|
|
16
|
+
*/
|
|
11
17
|
@Suppress("KotlinJniMissingFunction")
|
|
12
18
|
@DoNotStrip
|
|
13
|
-
class JSIInteropModuleRegistry(appContext: AppContext) {
|
|
14
|
-
|
|
19
|
+
class JSIInteropModuleRegistry(appContext: AppContext) : Destructible {
|
|
20
|
+
|
|
21
|
+
internal val appContextHolder = WeakReference(appContext)
|
|
15
22
|
|
|
16
23
|
// Has to be called "mHybridData" - fbjni uses it via reflection
|
|
17
24
|
@DoNotStrip
|
|
@@ -68,6 +75,12 @@ class JSIInteropModuleRegistry(appContext: AppContext) {
|
|
|
68
75
|
return appContextHolder.get()?.registry?.getModuleHolder(name)?.jsObject
|
|
69
76
|
}
|
|
70
77
|
|
|
78
|
+
@Suppress("unused")
|
|
79
|
+
@DoNotStrip
|
|
80
|
+
fun hasModule(name: String): Boolean {
|
|
81
|
+
return appContextHolder.get()?.registry?.hasModule(name) ?: false
|
|
82
|
+
}
|
|
83
|
+
|
|
71
84
|
/**
|
|
72
85
|
* Returns an array that contains names of available modules.
|
|
73
86
|
*/
|
|
@@ -77,8 +90,21 @@ class JSIInteropModuleRegistry(appContext: AppContext) {
|
|
|
77
90
|
return appContextHolder.get()?.registry?.registry?.keys?.toTypedArray() ?: emptyArray()
|
|
78
91
|
}
|
|
79
92
|
|
|
93
|
+
@Suppress("unused")
|
|
94
|
+
@DoNotStrip
|
|
95
|
+
fun registerSharedObject(native: Any, js: JavaScriptObject) {
|
|
96
|
+
appContextHolder
|
|
97
|
+
.get()
|
|
98
|
+
?.sharedObjectRegistry
|
|
99
|
+
?.add(native as SharedObject, js)
|
|
100
|
+
}
|
|
101
|
+
|
|
80
102
|
@Throws(Throwable::class)
|
|
81
103
|
protected fun finalize() {
|
|
104
|
+
deallocate()
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
override fun deallocate() {
|
|
82
108
|
mHybridData.resetNative()
|
|
83
109
|
}
|
|
84
110
|
|
|
@@ -8,7 +8,10 @@ import expo.modules.kotlin.exception.UnexpectedException
|
|
|
8
8
|
|
|
9
9
|
@Suppress("KotlinJniMissingFunction")
|
|
10
10
|
@DoNotStrip
|
|
11
|
-
class JavaCallback @DoNotStrip internal constructor(@DoNotStrip private val mHybridData: HybridData) {
|
|
11
|
+
class JavaCallback @DoNotStrip internal constructor(@DoNotStrip private val mHybridData: HybridData) : Destructible {
|
|
12
|
+
init {
|
|
13
|
+
JNIDeallocator.addReference(this)
|
|
14
|
+
}
|
|
12
15
|
|
|
13
16
|
operator fun invoke(result: Any?) {
|
|
14
17
|
if (result == null) {
|
|
@@ -38,6 +41,10 @@ class JavaCallback @DoNotStrip internal constructor(@DoNotStrip private val mHyb
|
|
|
38
41
|
|
|
39
42
|
@Throws(Throwable::class)
|
|
40
43
|
protected fun finalize() {
|
|
44
|
+
deallocate()
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
override fun deallocate() {
|
|
41
48
|
mHybridData.resetNative()
|
|
42
49
|
}
|
|
43
50
|
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
package expo.modules.kotlin.jni
|
|
2
|
+
|
|
3
|
+
import com.facebook.jni.HybridData
|
|
4
|
+
import expo.modules.core.interfaces.DoNotStrip
|
|
5
|
+
import expo.modules.kotlin.AppContext
|
|
6
|
+
import expo.modules.kotlin.types.JSTypeConverter
|
|
7
|
+
import expo.modules.kotlin.types.TypeConverterProviderImpl
|
|
8
|
+
import kotlin.reflect.KType
|
|
9
|
+
import kotlin.reflect.typeOf
|
|
10
|
+
|
|
11
|
+
@Suppress("KotlinJniMissingFunction")
|
|
12
|
+
@DoNotStrip
|
|
13
|
+
class JavaScriptFunction<ReturnType : Any?> @DoNotStrip private constructor(@DoNotStrip private val mHybridData: HybridData) : Destructible {
|
|
14
|
+
init {
|
|
15
|
+
JNIDeallocator.addReference(this)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
@PublishedApi
|
|
19
|
+
internal var returnType: KType? = null
|
|
20
|
+
|
|
21
|
+
fun isValid() = mHybridData.isValid
|
|
22
|
+
|
|
23
|
+
private external fun invoke(args: Array<Any?>, expectedReturnType: ExpectedType): Any?
|
|
24
|
+
|
|
25
|
+
operator fun invoke(vararg args: Any?, appContext: AppContext? = null): ReturnType {
|
|
26
|
+
// TODO(@lukmccall): check current thread
|
|
27
|
+
val convertedArgs = args
|
|
28
|
+
.map { JSTypeConverter.convertToJSValue(it) }
|
|
29
|
+
.toTypedArray()
|
|
30
|
+
|
|
31
|
+
val converter = TypeConverterProviderImpl
|
|
32
|
+
.obtainTypeConverter(returnType ?: typeOf<Unit>())
|
|
33
|
+
|
|
34
|
+
val expectedReturnType = converter.getCppRequiredTypes()
|
|
35
|
+
val result = invoke(convertedArgs, expectedReturnType)
|
|
36
|
+
@Suppress("UNCHECKED_CAST")
|
|
37
|
+
return converter.convert(result, appContext) as ReturnType
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
@Throws(Throwable::class)
|
|
41
|
+
protected fun finalize() {
|
|
42
|
+
deallocate()
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
override fun deallocate() {
|
|
46
|
+
mHybridData.resetNative()
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -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
|
}
|