-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathHybridRiveFileFactory.kt
More file actions
136 lines (121 loc) · 4.8 KB
/
HybridRiveFileFactory.kt
File metadata and controls
136 lines (121 loc) · 4.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
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
package com.margelo.nitro.rive
import android.annotation.SuppressLint
import androidx.annotation.Keep
import app.rive.runtime.kotlin.core.File
import app.rive.runtime.kotlin.core.Rive
import com.facebook.proguard.annotations.DoNotStrip
import com.margelo.nitro.core.ArrayBuffer
import com.margelo.nitro.core.Promise
import com.margelo.nitro.NitroModules
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.io.File as JavaFile
import java.net.URI
import java.net.URL
data class FileAndCache(
val file: File,
val cache: ReferencedAssetCache,
val loader: ReferencedAssetLoader?
)
@Keep
@DoNotStrip
class HybridRiveFileFactory : HybridRiveFileFactorySpec() {
private fun buildRiveFile(
data: ByteArray,
referencedAssets: ReferencedAssetsType?
): FileAndCache {
val cache = mutableMapOf<String, app.rive.runtime.kotlin.core.FileAsset>()
val loader = ReferencedAssetLoader()
val customLoader = loader.createCustomLoader(referencedAssets, cache)
// TODO: The File object in Android does not have the concept of loading CDN assets
val riveFile = if (customLoader != null) {
File(data, Rive.defaultRendererType, customLoader)
} else {
File(data)
}
return FileAndCache(riveFile, cache, if (customLoader != null) loader else null)
}
override fun fromURL(url: String, loadCdn: Boolean, referencedAssets: ReferencedAssetsType?): Promise<HybridRiveFileSpec> {
return Promise.async {
try {
val fileAndCache = withContext(Dispatchers.IO) {
val urlObj = URL(url)
val riveData = urlObj.readBytes()
buildRiveFile(riveData, referencedAssets)
}
val hybridRiveFile = HybridRiveFile()
hybridRiveFile.riveFile = fileAndCache.file
hybridRiveFile.referencedAssetCache = fileAndCache.cache
hybridRiveFile.assetLoader = fileAndCache.loader
hybridRiveFile
} catch (e: Exception) {
throw Error("Failed to download Rive file: ${e.message}")
}
}
}
override fun fromFileURL(fileURL: String, loadCdn: Boolean, referencedAssets: ReferencedAssetsType?): Promise<HybridRiveFileSpec> {
if (!fileURL.startsWith("file://")) {
throw Error("fromFileURL: URL must be a file URL: $fileURL")
}
return Promise.async {
try {
val uri = URI(fileURL)
val path = uri.path ?: throw Error("fromFileURL: Invalid URL: $fileURL")
val fileAndCache = withContext(Dispatchers.IO) {
val file = JavaFile(path)
val riveData = file.readBytes()
buildRiveFile(riveData, referencedAssets)
}
val hybridRiveFile = HybridRiveFile()
hybridRiveFile.riveFile = fileAndCache.file
hybridRiveFile.referencedAssetCache = fileAndCache.cache
hybridRiveFile.assetLoader = fileAndCache.loader
hybridRiveFile
} catch (e: Exception) {
throw Error("Failed to load Rive file: ${e.message}")
}
}
}
@SuppressLint("DiscouragedApi")
override fun fromResource(resource: String, loadCdn: Boolean, referencedAssets: ReferencedAssetsType?): Promise<HybridRiveFileSpec> {
return Promise.async {
try {
val context = NitroModules.applicationContext
?: throw Error("Could not load Rive file ($resource) from resource. No application context.")
val fileAndCache = withContext(Dispatchers.IO) {
val resourceId = context.resources.getIdentifier(resource, "raw", context.packageName)
if (resourceId == 0) {
throw Error("Could not find Rive file: $resource.riv")
}
val inputStream = context.resources.openRawResource(resourceId)
val riveData = inputStream.readBytes()
buildRiveFile(riveData, referencedAssets)
}
val hybridRiveFile = HybridRiveFile()
hybridRiveFile.riveFile = fileAndCache.file
hybridRiveFile.referencedAssetCache = fileAndCache.cache
hybridRiveFile.assetLoader = fileAndCache.loader
hybridRiveFile
} catch (e: Exception) {
throw Error("Failed to load Rive file: ${e.message}")
}
}
}
override fun fromBytes(bytes: ArrayBuffer, loadCdn: Boolean, referencedAssets: ReferencedAssetsType?): Promise<HybridRiveFileSpec> {
val buffer = bytes.getBuffer(false)
return Promise.async {
try {
val byteArray = ByteArray(buffer.remaining())
buffer.get(byteArray)
val fileAndCache = buildRiveFile(byteArray, referencedAssets)
val hybridRiveFile = HybridRiveFile()
hybridRiveFile.riveFile = fileAndCache.file
hybridRiveFile.referencedAssetCache = fileAndCache.cache
hybridRiveFile.assetLoader = fileAndCache.loader
hybridRiveFile
} catch (e: Exception) {
throw Error("Failed to load Rive file from bytes: ${e.message}")
}
}
}
}