-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy pathHybridViewModel.kt
More file actions
157 lines (142 loc) · 6.36 KB
/
HybridViewModel.kt
File metadata and controls
157 lines (142 loc) · 6.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
package com.margelo.nitro.rive
import androidx.annotation.Keep
import app.rive.RiveFile
import app.rive.ViewModelInstance
import app.rive.ViewModelSource
import app.rive.core.CommandQueue
import com.facebook.proguard.annotations.DoNotStrip
import com.margelo.nitro.core.Promise
import kotlinx.coroutines.runBlocking
@Keep
@DoNotStrip
class HybridViewModel(
private val riveFile: RiveFile,
private val riveWorker: CommandQueue,
// Null when constructed via DefaultForArtboard — the Rive Android SDK does not expose
// the ViewModel name from a ViewModelInstance, so name-dependent operations are unavailable.
// Track: https://github.com/rive-app/rive-android/issues/XXX
private val viewModelName: String?,
private val parentFile: HybridRiveFile,
private val vmSource: ViewModelSource
) : HybridViewModelSpec() {
companion object {
private const val TAG = "HybridViewModel"
private const val NO_NAME_ERROR =
"This operation requires the ViewModel name, which is unavailable for ViewModels " +
"obtained via defaultArtboardViewModel(). The Rive Android SDK does not yet expose " +
"the ViewModel name from a ViewModelInstance. Use a named ViewModel instead, or " +
"track the upstream fix: https://github.com/rive-app/rive-android/issues/XXX"
}
override val propertyCount: Double
get() {
DeprecationWarning.warn("propertyCount", "getPropertyCountAsync")
val name = viewModelName ?: throw UnsupportedOperationException(NO_NAME_ERROR)
return try {
runBlocking { riveFile.getViewModelProperties(name) }.size.toDouble()
} catch (e: Exception) {
RiveLog.e(TAG, "propertyCount failed: ${e.message}")
0.0
}
}
override val instanceCount: Double
get() {
DeprecationWarning.warn("instanceCount", "getInstanceCountAsync")
val name = viewModelName ?: throw UnsupportedOperationException(NO_NAME_ERROR)
return try {
runBlocking { riveFile.getViewModelInstanceNames(name) }.size.toDouble()
} catch (e: Exception) {
RiveLog.e(TAG, "instanceCount failed: ${e.message}")
0.0
}
}
override val modelName: String
get() = viewModelName ?: throw UnsupportedOperationException(NO_NAME_ERROR)
override fun getPropertyCountAsync(): Promise<Double> {
val name = viewModelName ?: return Promise.rejected(UnsupportedOperationException(NO_NAME_ERROR))
return Promise.async { riveFile.getViewModelProperties(name).size.toDouble() }
}
override fun getInstanceCountAsync(): Promise<Double> {
val name = viewModelName ?: return Promise.rejected(UnsupportedOperationException(NO_NAME_ERROR))
return Promise.async { riveFile.getViewModelInstanceNames(name).size.toDouble() }
}
// Deprecated: Use createInstanceByNameAsync instead
override fun createInstanceByIndex(index: Double): HybridViewModelInstanceSpec? {
DeprecationWarning.warn("createInstanceByIndex", "createInstanceByNameAsync")
val name = viewModelName ?: throw UnsupportedOperationException(NO_NAME_ERROR)
return try {
val idx = index.toInt()
val instanceNames = runBlocking { riveFile.getViewModelInstanceNames(name) }
if (idx < 0 || idx >= instanceNames.size) return null
val instanceName = instanceNames[idx]
runBlocking { createInstanceByNameImpl(instanceName) }
} catch (e: UnsupportedOperationException) {
throw e
} catch (e: Exception) {
RiveLog.e(TAG, "createInstanceByIndex($index) failed: ${e.message}")
null
}
}
private suspend fun createInstanceByNameImpl(instanceName: String): HybridViewModelInstanceSpec? {
val name = viewModelName ?: throw UnsupportedOperationException(NO_NAME_ERROR)
val instanceNames = riveFile.getViewModelInstanceNames(name)
if (!instanceNames.contains(instanceName)) return null
val source = vmSource.namedInstance(instanceName)
val vmi = ViewModelInstance.fromFile(riveFile, source)
return HybridViewModelInstance(vmi, riveWorker, parentFile, name, instanceName)
}
// Deprecated: Use createInstanceByNameAsync instead
override fun createInstanceByName(name: String): HybridViewModelInstanceSpec? {
DeprecationWarning.warn("createInstanceByName", "createInstanceByNameAsync")
if (viewModelName == null) throw UnsupportedOperationException(NO_NAME_ERROR)
return try {
runBlocking { createInstanceByNameImpl(name) }
} catch (e: UnsupportedOperationException) {
throw e
} catch (e: Exception) {
RiveLog.e(TAG, "createInstanceByName('$name') failed: ${e.message}")
null
}
}
override fun createInstanceByNameAsync(name: String): Promise<HybridViewModelInstanceSpec?> {
if (viewModelName == null) return Promise.rejected(UnsupportedOperationException(NO_NAME_ERROR))
return Promise.async { createInstanceByNameImpl(name) }
}
// Deprecated: Use createDefaultInstanceAsync instead
override fun createDefaultInstance(): HybridViewModelInstanceSpec? {
DeprecationWarning.warn("createDefaultInstance", "createDefaultInstanceAsync")
return try {
val source = vmSource.defaultInstance()
val vmi = ViewModelInstance.fromFile(riveFile, source)
HybridViewModelInstance(vmi, riveWorker, parentFile, viewModelName)
} catch (e: Exception) {
RiveLog.e(TAG, "createDefaultInstance failed: ${e.message}")
null
}
}
override fun createDefaultInstanceAsync(): Promise<HybridViewModelInstanceSpec?> {
return Promise.async {
val source = vmSource.defaultInstance()
val vmi = ViewModelInstance.fromFile(riveFile, source)
HybridViewModelInstance(vmi, riveWorker, parentFile, viewModelName)
}
}
// Deprecated: Use createBlankInstanceAsync instead
override fun createInstance(): HybridViewModelInstanceSpec? {
DeprecationWarning.warn("createInstance", "createBlankInstanceAsync")
return try {
val source = vmSource.blankInstance()
val vmi = ViewModelInstance.fromFile(riveFile, source)
HybridViewModelInstance(vmi, riveWorker, parentFile, viewModelName)
} catch (e: Exception) {
RiveLog.e(TAG, "createInstance (blank) failed: ${e.message}")
null
}
}
override fun createBlankInstanceAsync(): Promise<HybridViewModelInstanceSpec?> {
return Promise.async {
val source = vmSource.blankInstance()
val vmi = ViewModelInstance.fromFile(riveFile, source)
HybridViewModelInstance(vmi, riveWorker, parentFile, viewModelName)
}
}
}