You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

66 lines
2.1 KiB

package com.example.jetsnack.ui.components
import org.jetbrains.skia.ExternalSymbolName
import org.jetbrains.skia.impl.NativePointer
import org.khronos.webgl.ArrayBuffer
import org.khronos.webgl.Int8Array
import org.w3c.xhr.XMLHttpRequest
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException
import kotlin.coroutines.suspendCoroutine
import kotlin.wasm.unsafe.UnsafeWasmMemoryApi
import kotlin.wasm.unsafe.withScopedMemoryAllocator
private class MissingResourceException(url: String): Exception("GET $url failed")
suspend fun loadImage(url: String): ArrayBuffer {
return suspendCoroutine { continuation ->
val req = XMLHttpRequest()
req.open("GET", url, true)
req.responseType = "arraybuffer".toJsString().unsafeCast()
req.onload = { _ ->
val arrayBuffer = req.response
if (arrayBuffer is ArrayBuffer) {
continuation.resume(arrayBuffer)
} else {
continuation.resumeWithException(MissingResourceException(url))
}
}
req.send("")
}
}
fun ArrayBuffer.toByteArray(): ByteArray {
val source = Int8Array(this, 0, byteLength)
return jsInt8ArrayToKotlinByteArray(source)
}
@JsFun(
""" (src, size, dstAddr) => {
const mem8 = new Int8Array(wasmExports.memory.buffer, dstAddr, size);
mem8.set(src);
}
"""
)
internal external fun jsExportInt8ArrayToWasm(src: Int8Array, size: Int, dstAddr: Int)
internal fun jsInt8ArrayToKotlinByteArray(x: Int8Array): ByteArray {
val size = x.length
@OptIn(UnsafeWasmMemoryApi::class)
return withScopedMemoryAllocator { allocator ->
val memBuffer = allocator.allocate(size)
val dstAddress = memBuffer.address.toInt()
jsExportInt8ArrayToWasm(x, size, dstAddress)
ByteArray(size) { i -> (memBuffer + i).loadByte() }
}
}
@ExternalSymbolName("_malloc")
@kotlin.wasm.WasmImport("skia", "malloc")
private external fun _malloc(size: Int): NativePointer
@ExternalSymbolName("_free")
@kotlin.wasm.WasmImport("skia", "free")
private external fun _free(ptr: NativePointer)