-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy pathReferencedAssetLoader.kt
More file actions
108 lines (87 loc) · 2.8 KB
/
ReferencedAssetLoader.kt
File metadata and controls
108 lines (87 loc) · 2.8 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
package com.margelo.nitro.rive
import android.util.Log
import app.rive.runtime.kotlin.core.*
import com.margelo.nitro.NitroModules
import kotlinx.coroutines.*
typealias ReferencedAssetCache = MutableMap<String, FileAsset>
class ReferencedAssetLoader {
private val scope = CoroutineScope(Dispatchers.IO + SupervisorJob())
private fun logError(message: String) {
Log.e("ReferencedAssetLoader", message)
}
private fun processAssetBytes(bytes: ByteArray, asset: FileAsset) {
when (asset) {
is ImageAsset -> asset.image = RiveRenderImage.fromEncoded(bytes)
is FontAsset -> asset.font = RiveFont.make(bytes)
is AudioAsset -> asset.audio = RiveAudio.make(bytes)
}
}
private fun handlePreloadedImage(image: HybridRiveImageSpec, asset: FileAsset) {
if (asset is ImageAsset && image is HybridRiveImage) {
asset.image = image.renderImage
}
}
private fun loadAsset(assetData: ResolvedReferencedAsset, asset: FileAsset): Deferred<Unit> {
val deferred = CompletableDeferred<Unit>()
if (assetData.image != null) {
handlePreloadedImage(assetData.image, asset)
deferred.complete(Unit)
return deferred
}
val dataSource = try {
DataSourceResolver.resolve(assetData)
} catch (e: Exception) {
logError("Failed to resolve asset: ${e.message}")
deferred.complete(Unit)
return deferred
}
if (dataSource == null) {
deferred.complete(Unit)
return deferred
}
scope.launch {
try {
val bytes = dataSource.createLoader().load(dataSource)
withContext(Dispatchers.Main) {
processAssetBytes(bytes, asset)
deferred.complete(Unit)
}
} catch (e: Exception) {
logError("Failed to load asset: ${e.message}")
withContext(Dispatchers.Main) {
deferred.complete(Unit)
}
}
}
return deferred
}
fun updateAsset(assetData: ResolvedReferencedAsset, asset: FileAsset): Deferred<Unit> {
return loadAsset(assetData, asset)
}
fun createCustomLoader(
referencedAssets: ReferencedAssetsType?,
cache: ReferencedAssetCache
): FileAssetLoader? {
val assetsData = referencedAssets?.data ?: return null
val context = NitroModules.applicationContext ?: return null
return object : FileAssetLoader() {
override fun loadContents(asset: FileAsset, inBandBytes: ByteArray): Boolean {
var key = asset.uniqueFilename.substringBeforeLast(".")
var assetData = assetsData[key]
if (assetData == null) {
key = asset.name
assetData = assetsData[asset.name]
}
if (assetData == null) {
return false
}
cache[key] = asset
loadAsset(assetData, asset)
return true
}
}
}
fun dispose() {
scope.cancel()
}
}