Browse Source
Changes: - added k/wasm target to library and demo - added libs.versions.toml with coroutines version Tested: - using demo project - publishToMavenLocal I'll setup the test separately. --------- Co-authored-by: Oleksandr.Karpovich <oleksandr.karpovich@jetbrains.com>pull/4031/head
Oleksandr Karpovich
12 months ago
committed by
GitHub
13 changed files with 198 additions and 8 deletions
@ -0,0 +1,7 @@
|
||||
[versions] |
||||
kotlinx-coroutines = "1.8.0-RC" |
||||
|
||||
[libraries] |
||||
kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinx-coroutines" } |
||||
kotlinx-coroutines-swing = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-swing", version.ref = "kotlinx-coroutines" } |
||||
kotlinx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "kotlinx-coroutines" } |
@ -0,0 +1,16 @@
|
||||
import androidx.compose.ui.ExperimentalComposeUiApi |
||||
import androidx.compose.ui.window.CanvasBasedWindow |
||||
import org.jetbrains.compose.resources.ExperimentalResourceApi |
||||
import org.jetbrains.compose.resources.configureWebResources |
||||
import org.jetbrains.compose.resources.demo.shared.UseResources |
||||
|
||||
@OptIn(ExperimentalComposeUiApi::class, ExperimentalResourceApi::class) |
||||
fun main() { |
||||
configureWebResources { |
||||
// Not necessary - It's the same as the default. We add it here just to present this feature. |
||||
resourcePathMapping { path -> "./$path" } |
||||
} |
||||
CanvasBasedWindow("Resources demo + K/Wasm") { |
||||
UseResources() |
||||
} |
||||
} |
@ -0,0 +1,11 @@
|
||||
<!DOCTYPE html> |
||||
<html lang="en"> |
||||
<head> |
||||
<meta charset="UTF-8"> |
||||
<title>Resources demo + K/Wasm</title> |
||||
</head> |
||||
<body> |
||||
<canvas id="ComposeTarget"></canvas> |
||||
<script src="shared.js"></script> |
||||
</body> |
||||
</html> |
@ -0,0 +1,13 @@
|
||||
package org.jetbrains.compose.resources |
||||
|
||||
import org.jetbrains.compose.resources.vector.xmldom.Element |
||||
import org.jetbrains.compose.resources.vector.xmldom.ElementImpl |
||||
import org.jetbrains.compose.resources.vector.xmldom.MalformedXMLException |
||||
import org.w3c.dom.parsing.DOMParser |
||||
|
||||
internal actual fun ByteArray.toXmlElement(): Element { |
||||
val xmlString = decodeToString() |
||||
val xmlDom = DOMParser().parseFromString(xmlString, "application/xml".toJsString()) |
||||
val domElement = xmlDom.documentElement ?: throw MalformedXMLException("missing documentElement") |
||||
return ElementImpl(domElement.unsafeCast()) |
||||
} |
@ -0,0 +1,51 @@
|
||||
package org.jetbrains.compose.resources |
||||
|
||||
import kotlinx.browser.window |
||||
import kotlinx.coroutines.await |
||||
import org.khronos.webgl.ArrayBuffer |
||||
import org.khronos.webgl.Int8Array |
||||
import org.w3c.fetch.Response |
||||
import kotlin.wasm.unsafe.UnsafeWasmMemoryApi |
||||
import kotlin.wasm.unsafe.withScopedMemoryAllocator |
||||
|
||||
/** |
||||
* Reads the content of the resource file at the specified path and returns it as a byte array. |
||||
* |
||||
* @param path The path of the file to read in the resource's directory. |
||||
* @return The content of the file as a byte array. |
||||
*/ |
||||
@ExperimentalResourceApi |
||||
actual suspend fun readResourceBytes(path: String): ByteArray { |
||||
val resPath = WebResourcesConfiguration.getResourcePath(path) |
||||
val response = window.fetch(resPath).await<Response>() |
||||
if (!response.ok) { |
||||
throw MissingResourceException(resPath) |
||||
} |
||||
return response.arrayBuffer().await<ArrayBuffer>().toByteArray() |
||||
} |
||||
|
||||
private 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() } |
||||
} |
||||
} |
@ -0,0 +1,19 @@
|
||||
package org.jetbrains.compose.resources.vector.xmldom |
||||
|
||||
import org.w3c.dom.Element as DomElement |
||||
|
||||
internal class ElementImpl(val element: DomElement): NodeImpl(element), Element { |
||||
override val textContent: String? |
||||
get() = element.textContent |
||||
|
||||
override val localName: String |
||||
get() = element.localName |
||||
|
||||
override val namespaceURI: String |
||||
get() = element.namespaceURI ?: "" |
||||
|
||||
override fun getAttributeNS(nameSpaceURI: String, localName: String): String = |
||||
element.getAttributeNS(nameSpaceURI, localName) ?: "" |
||||
|
||||
override fun getAttribute(name: String): String = element.getAttribute(name) ?: "" |
||||
} |
@ -0,0 +1,31 @@
|
||||
package org.jetbrains.compose.resources.vector.xmldom |
||||
|
||||
import org.w3c.dom.Element as DomElement |
||||
import org.w3c.dom.Node as DomNode |
||||
|
||||
internal open class NodeImpl(val n: DomNode): Node { |
||||
override val textContent: String? |
||||
get() = n.textContent |
||||
|
||||
override val nodeName: String |
||||
get() = n.nodeName |
||||
|
||||
override val localName = "" /* localName is not a Node property, only applies to Elements and Attrs */ |
||||
|
||||
override val namespaceURI = "" /* namespaceURI is not a Node property, only applies to Elements and Attrs */ |
||||
|
||||
override val childNodes: NodeList by lazy { |
||||
object: NodeList { |
||||
override fun item(i: Int): Node { |
||||
val child = n.childNodes.item(i) |
||||
?: throw IndexOutOfBoundsException("no child node accessible at index=$i") |
||||
return if (child is DomElement) ElementImpl(child) else NodeImpl(child) |
||||
} |
||||
|
||||
override val length: Int = n.childNodes.length |
||||
} |
||||
} |
||||
|
||||
override fun lookupPrefix(namespaceURI: String): String = n.lookupPrefix(namespaceURI) ?: "" |
||||
|
||||
} |
@ -0,0 +1,7 @@
|
||||
package org.jetbrains.compose.resources |
||||
|
||||
import kotlinx.coroutines.CoroutineScope |
||||
|
||||
actual fun runBlockingTest(block: suspend CoroutineScope.() -> Unit) { |
||||
TODO("To be implemented in PR 4031") |
||||
} |
Loading…
Reference in new issue