From 6801bafe6f6757810cfe2d72abbdd0502799814e Mon Sep 17 00:00:00 2001 From: "Moon D." Date: Sat, 11 Oct 2025 17:35:33 -0400 Subject: [PATCH 01/26] =?UTF-8?q?*:=EA=94=AB:*Renderer=20Project*:?= =?UTF-8?q?=EA=94=AB:*?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- renderer/.gitignore | 2 ++ renderer/Cargo.lock | 7 +++++++ renderer/Cargo.toml | 6 ++++++ renderer/src/main.rs | 3 +++ 4 files changed, 18 insertions(+) create mode 100644 renderer/.gitignore create mode 100644 renderer/Cargo.lock create mode 100644 renderer/Cargo.toml create mode 100644 renderer/src/main.rs diff --git a/renderer/.gitignore b/renderer/.gitignore new file mode 100644 index 000000000..66cc71077 --- /dev/null +++ b/renderer/.gitignore @@ -0,0 +1,2 @@ +/target/ + diff --git a/renderer/Cargo.lock b/renderer/Cargo.lock new file mode 100644 index 000000000..b681fe3b6 --- /dev/null +++ b/renderer/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "renderer" +version = "0.1.0" diff --git a/renderer/Cargo.toml b/renderer/Cargo.toml new file mode 100644 index 000000000..c29f61c72 --- /dev/null +++ b/renderer/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "renderer" +version = "0.1.0" +edition = "2024" + +[dependencies] diff --git a/renderer/src/main.rs b/renderer/src/main.rs new file mode 100644 index 000000000..e7a11a969 --- /dev/null +++ b/renderer/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} From ebd4df624b0c33640f6a86a3ea14c45242319da3 Mon Sep 17 00:00:00 2001 From: Moon Date: Mon, 13 Oct 2025 23:04:13 -0400 Subject: [PATCH 02/26] Create workspaces for ffi and the renderer (#1275) --- {renderer => libProcessing}/.gitignore | 0 {renderer => libProcessing}/Cargo.lock | 8 ++++++++ libProcessing/Cargo.toml | 8 ++++++++ libProcessing/ffi/Cargo.toml | 6 ++++++ libProcessing/ffi/src/lib.rs | 14 ++++++++++++++ {renderer => libProcessing/renderer}/Cargo.toml | 0 libProcessing/renderer/src/lib.rs | 14 ++++++++++++++ {renderer => libProcessing}/src/main.rs | 0 8 files changed, 50 insertions(+) rename {renderer => libProcessing}/.gitignore (100%) rename {renderer => libProcessing}/Cargo.lock (60%) create mode 100644 libProcessing/Cargo.toml create mode 100644 libProcessing/ffi/Cargo.toml create mode 100644 libProcessing/ffi/src/lib.rs rename {renderer => libProcessing/renderer}/Cargo.toml (100%) create mode 100644 libProcessing/renderer/src/lib.rs rename {renderer => libProcessing}/src/main.rs (100%) diff --git a/renderer/.gitignore b/libProcessing/.gitignore similarity index 100% rename from renderer/.gitignore rename to libProcessing/.gitignore diff --git a/renderer/Cargo.lock b/libProcessing/Cargo.lock similarity index 60% rename from renderer/Cargo.lock rename to libProcessing/Cargo.lock index b681fe3b6..331701f44 100644 --- a/renderer/Cargo.lock +++ b/libProcessing/Cargo.lock @@ -2,6 +2,14 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "ffi" +version = "0.1.0" + +[[package]] +name = "libProcessing" +version = "0.1.0" + [[package]] name = "renderer" version = "0.1.0" diff --git a/libProcessing/Cargo.toml b/libProcessing/Cargo.toml new file mode 100644 index 000000000..614ee9fb0 --- /dev/null +++ b/libProcessing/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "libProcessing" +version = "0.1.0" +edition = "2024" + +[workspace] +resolver = "3" +members = ["ffi","renderer"] diff --git a/libProcessing/ffi/Cargo.toml b/libProcessing/ffi/Cargo.toml new file mode 100644 index 000000000..68c7917cd --- /dev/null +++ b/libProcessing/ffi/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "ffi" +version = "0.1.0" +edition = "2024" + +[dependencies] diff --git a/libProcessing/ffi/src/lib.rs b/libProcessing/ffi/src/lib.rs new file mode 100644 index 000000000..b93cf3ffd --- /dev/null +++ b/libProcessing/ffi/src/lib.rs @@ -0,0 +1,14 @@ +pub fn add(left: u64, right: u64) -> u64 { + left + right +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn it_works() { + let result = add(2, 2); + assert_eq!(result, 4); + } +} diff --git a/renderer/Cargo.toml b/libProcessing/renderer/Cargo.toml similarity index 100% rename from renderer/Cargo.toml rename to libProcessing/renderer/Cargo.toml diff --git a/libProcessing/renderer/src/lib.rs b/libProcessing/renderer/src/lib.rs new file mode 100644 index 000000000..b93cf3ffd --- /dev/null +++ b/libProcessing/renderer/src/lib.rs @@ -0,0 +1,14 @@ +pub fn add(left: u64, right: u64) -> u64 { + left + right +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn it_works() { + let result = add(2, 2); + assert_eq!(result, 4); + } +} diff --git a/renderer/src/main.rs b/libProcessing/src/main.rs similarity index 100% rename from renderer/src/main.rs rename to libProcessing/src/main.rs From 32c31b577cc521b0f1e4af17fa07d7d0b1db4dff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?charlotte=20=F0=9F=8C=B8?= Date: Wed, 15 Oct 2025 10:27:49 -0700 Subject: [PATCH 03/26] Inital scaffold for libprocessing ffi. --- app/build.gradle.kts | 170 +++--- build.gradle.kts | 13 + core/build.gradle.kts | 132 +++++ core/src/processing/core/NativeLibrary.java | 110 ++++ core/src/processing/webgpu/PWebGPU.java | 28 + core/test/processing/webgpu/PWebGPUTest.java | 15 + gradle/libs.versions.toml | 4 +- gradle/wrapper/gradle-wrapper.properties | 2 +- java/libraries/dxf/build.gradle.kts | 1 + libProcessing/Cargo.lock | 513 +++++++++++++++++++ libProcessing/ffi/Cargo.toml | 8 + libProcessing/ffi/build.rs | 23 + libProcessing/ffi/cbindgen.toml | 12 + libProcessing/ffi/include/processing.h | 17 + libProcessing/ffi/src/lib.rs | 18 +- libProcessing/renderer/src/lib.rs | 14 +- 16 files changed, 973 insertions(+), 107 deletions(-) create mode 100644 core/src/processing/core/NativeLibrary.java create mode 100644 core/src/processing/webgpu/PWebGPU.java create mode 100644 core/test/processing/webgpu/PWebGPUTest.java create mode 100644 libProcessing/ffi/build.rs create mode 100644 libProcessing/ffi/cbindgen.toml create mode 100644 libProcessing/ffi/include/processing.h diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 0d3fcbd12..f2615ce14 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -1,15 +1,94 @@ import org.gradle.internal.jvm.Jvm import org.gradle.internal.os.OperatingSystem import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform +import org.gradle.process.ExecOperations import org.jetbrains.compose.desktop.application.dsl.TargetFormat import org.jetbrains.compose.desktop.application.tasks.AbstractJPackageTask import org.jetbrains.compose.internal.de.undercouch.gradle.tasks.download.Download import java.io.FileOutputStream import java.util.zip.ZipEntry import java.util.zip.ZipOutputStream +import javax.inject.Inject // TODO: Update to 2.10.20 and add hot-reloading: https://github.com/JetBrains/compose-hot-reload +abstract class SignResourcesTask : DefaultTask() { + @get:Inject + abstract val execOperations: ExecOperations + + @get:InputDirectory + abstract val resourcesPath: DirectoryProperty + + @TaskAction + fun signResources() { + val resourcesDir = resourcesPath.get().asFile + val jars = mutableListOf() + + // Copy Info.plist if present + project.fileTree(resourcesDir) + .matching { include("**/Info.plist") } + .singleOrNull() + ?.let { file -> + project.copy { + from(file) + into(resourcesDir) + } + } + + project.fileTree(resourcesDir) { + include("**/*.jar") + exclude("**/*.jar.tmp/**") + }.forEach { file -> + val tempDir = file.parentFile.resolve("${file.name}.tmp") + project.copy { + from(project.zipTree(file)) + into(tempDir) + } + file.delete() + jars.add(tempDir) + } + + project.fileTree(resourcesDir) { + include("**/bin/**") + include("**/*.jnilib") + include("**/*.dylib") + include("**/*aarch64*") + include("**/*x86_64*") + include("**/*ffmpeg*") + include("**/ffmpeg*/**") + exclude("jdk/**") + exclude("*.jar") + exclude("*.so") + exclude("*.dll") + }.forEach { file -> + execOperations.exec { + commandLine("codesign", "--timestamp", "--force", "--deep", "--options=runtime", "--sign", "Developer ID Application", file) + } + } + + jars.forEach { file -> + FileOutputStream(File(file.parentFile, file.nameWithoutExtension)).use { fos -> + ZipOutputStream(fos).use { zos -> + file.walkTopDown().forEach { fileEntry -> + if (fileEntry.isFile) { + val zipEntryPath = fileEntry.relativeTo(file).path + val entry = ZipEntry(zipEntryPath) + zos.putNextEntry(entry) + fileEntry.inputStream().use { input -> + input.copyTo(zos) + } + zos.closeEntry() + } + } + } + } + file.deleteRecursively() + } + + File(resourcesDir, "Info.plist").delete() + } +} + plugins{ id("java") kotlin("jvm") version libs.versions.kotlin @@ -49,14 +128,17 @@ compose.desktop { application { mainClass = "processing.app.ProcessingKt" - jvmArgs(*listOf( - Pair("processing.version", rootProject.version), - Pair("processing.revision", findProperty("revision") ?: Int.MAX_VALUE), - Pair("processing.contributions.source", "https://contributions.processing.org/contribs"), - Pair("processing.download.page", "https://processing.org/download/"), - Pair("processing.download.latest", "https://processing.org/download/latest.txt"), - Pair("processing.tutorials", "https://processing.org/tutorials/"), - ).map { "-D${it.first}=${it.second}" }.toTypedArray()) + jvmArgs( + "--enable-native-access=ALL-UNNAMED", // Required for Java 25 native library access + *listOf( + Pair("processing.version", rootProject.version), + Pair("processing.revision", findProperty("revision") ?: Int.MAX_VALUE), + Pair("processing.contributions.source", "https://contributions.processing.org/contribs"), + Pair("processing.download.page", "https://processing.org/download/"), + Pair("processing.download.latest", "https://processing.org/download/latest.txt"), + Pair("processing.tutorials", "https://processing.org/tutorials/"), + ).map { "-D${it.first}=${it.second}" }.toTypedArray() + ) nativeDistributions{ modules("jdk.jdi", "java.compiler", "jdk.accessibility", "java.management.rmi", "java.scripting", "jdk.httpserver") @@ -421,82 +503,14 @@ tasks.register("includeProcessingResources"){ finalizedBy("signResources") } -tasks.register("signResources"){ +tasks.register("signResources") { onlyIf { OperatingSystem.current().isMacOsX && compose.desktop.application.nativeDistributions.macOS.signing.sign.get() } group = "compose desktop" - val resourcesPath = composeResources("") - - // find jars in the resources directory - val jars = mutableListOf() - doFirst{ - fileTree(resourcesPath) - .matching { include("**/Info.plist") } - .singleOrNull() - ?.let { file -> - copy { - from(file) - into(resourcesPath) - } - } - fileTree(resourcesPath) { - include("**/*.jar") - exclude("**/*.jar.tmp/**") - }.forEach { file -> - val tempDir = file.parentFile.resolve("${file.name}.tmp") - copy { - from(zipTree(file)) - into(tempDir) - } - file.delete() - jars.add(tempDir) - } - fileTree(resourcesPath){ - include("**/bin/**") - include("**/*.jnilib") - include("**/*.dylib") - include("**/*aarch64*") - include("**/*x86_64*") - include("**/*ffmpeg*") - include("**/ffmpeg*/**") - exclude("jdk/**") - exclude("*.jar") - exclude("*.so") - exclude("*.dll") - }.forEach{ file -> - exec { - commandLine("codesign", "--timestamp", "--force", "--deep","--options=runtime", "--sign", "Developer ID Application", file) - } - } - jars.forEach { file -> - FileOutputStream(File(file.parentFile, file.nameWithoutExtension)).use { fos -> - ZipOutputStream(fos).use { zos -> - file.walkTopDown().forEach { fileEntry -> - if (fileEntry.isFile) { - // Calculate the relative path for the zip entry - val zipEntryPath = fileEntry.relativeTo(file).path - val entry = ZipEntry(zipEntryPath) - zos.putNextEntry(entry) - - // Copy file contents to the zip - fileEntry.inputStream().use { input -> - input.copyTo(zos) - } - zos.closeEntry() - } - } - } - } - - file.deleteRecursively() - } - file(composeResources("Info.plist")).delete() - } - - + resourcesPath.set(composeResources("")) } tasks.register("setExecutablePermissions") { description = "Sets executable permissions on binaries in Processing.app resources" diff --git a/build.gradle.kts b/build.gradle.kts index 8e7ad44a7..06137398a 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -12,6 +12,19 @@ plugins { // Can be deleted after the migration to Gradle is complete layout.buildDirectory = file(".build") +allprojects { + tasks.withType().configureEach { + sourceCompatibility = "24" + targetCompatibility = "24" + } + + tasks.withType().configureEach { + compilerOptions { + jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_24) + } + } +} + // Configure the dependencyUpdates task tasks { dependencyUpdates { diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 8f7211b13..41d3de6bd 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -35,6 +35,138 @@ dependencies { testImplementation(libs.junit) } +val osName = System.getProperty("os.name").lowercase() +val osArch = System.getProperty("os.arch").lowercase() + +val platformName = when { + osName.contains("mac") || osName.contains("darwin") -> "macos" + osName.contains("win") -> "windows" + osName.contains("linux") -> "linux" + else -> throw GradleException("Unsupported OS: $osName") +} + +val archName = when { + osArch.contains("aarch64") || osArch.contains("arm") -> "aarch64" + osArch.contains("x86_64") || osArch.contains("amd64") -> "x86_64" + else -> throw GradleException("Unsupported architecture: $osArch") +} + +val libExtension = when (platformName) { + "macos" -> "dylib" + "windows" -> "dll" + "linux" -> "so" + else -> throw GradleException("Unknown platform: $platformName") +} + +val libName = when (platformName) { + "windows" -> "processing.$libExtension" + else -> "libprocessing.$libExtension" +} + +val platformTarget = "$platformName-$archName" +val libProcessingDir = file("${project.rootDir}/libProcessing") +val rustTargetDir = file("$libProcessingDir/target") +val nativeOutputDir = file("${layout.buildDirectory.get()}/native/$platformTarget") + +val cargoPath = System.getenv("CARGO_HOME")?.let { "$it/bin/cargo" } + ?: "${System.getProperty("user.home")}/.cargo/bin/cargo" + +val buildRustRelease by tasks.registering(Exec::class) { + group = "rust" + description = "Build Rust FFI library in release mode for current platform" + + workingDir = libProcessingDir + commandLine = listOf(cargoPath, "build", "--release", "--manifest-path", "ffi/Cargo.toml") + + inputs.files(fileTree("$libProcessingDir/ffi/src")) + inputs.file("$libProcessingDir/ffi/Cargo.toml") + inputs.file("$libProcessingDir/Cargo.toml") + inputs.file("$libProcessingDir/ffi/build.rs") + inputs.file("$libProcessingDir/ffi/cbindgen.toml") + + outputs.file("$rustTargetDir/release/$libName") + outputs.file("$libProcessingDir/ffi/include/processing.h") + + doFirst { + logger.lifecycle("Building Rust library for $platformTarget...") + } +} + +val copyNativeLibs by tasks.registering(Copy::class) { + group = "rust" + description = "Copy processing library to build directory" + + dependsOn(buildRustRelease) + + from("$rustTargetDir/release") { + include("libprocessing.a") + include("libprocessing.$libExtension") + } + + into(nativeOutputDir) + + doFirst { + logger.lifecycle("Copying native libraries to $nativeOutputDir") + } +} + +val bundleNativeLibs by tasks.registering(Copy::class) { + group = "rust" + description = "Bundle native library into resources" + + dependsOn(copyNativeLibs) + + from(nativeOutputDir) + into("${sourceSets.main.get().output.resourcesDir}/native/$platformTarget") + + doFirst { + logger.lifecycle("Bundling libraries for $platformTarget into resources") + } +} + +val jextractPath = "${System.getProperty("user.home")}/jextract-22/bin/jextract" +val generatedJavaDir = file("${layout.buildDirectory.get()}/generated/sources/jextract/java") +val headerFile = file("$libProcessingDir/ffi/include/processing.h") + +sourceSets.main { + java.srcDirs(generatedJavaDir) +} + +val generateJavaBindings by tasks.registering(Exec::class) { + group = "rust" + description = "Generate Java bindings from libProcessing headers using jextract" + + dependsOn(buildRustRelease) + + inputs.file(headerFile) + + outputs.dir(generatedJavaDir) + + doFirst { + generatedJavaDir.mkdirs() + logger.lifecycle("Generating Java bindings from $headerFile...") + } + + commandLine = listOf( + jextractPath, + "--output", generatedJavaDir.absolutePath, + "--target-package", "processing.ffi", + headerFile.absolutePath + ) +} + +tasks.named("compileJava") { + dependsOn(generateJavaBindings) +} + +tasks.named("compileKotlin") { + dependsOn(generateJavaBindings) +} + +tasks.named("processResources") { + dependsOn(bundleNativeLibs) +} + mavenPublishing{ publishToMavenCentral(SonatypeHost.CENTRAL_PORTAL) signAllPublications() diff --git a/core/src/processing/core/NativeLibrary.java b/core/src/processing/core/NativeLibrary.java new file mode 100644 index 000000000..15b7331c2 --- /dev/null +++ b/core/src/processing/core/NativeLibrary.java @@ -0,0 +1,110 @@ +package processing.core; + +import java.io.*; +import java.nio.file.*; + +/** + * Handles loading of Processing's native Rust library (libprocessing). + */ +public class NativeLibrary { + private static boolean loaded = false; + private static Throwable loadError = null; + + private static final String LIBRARY_NAME = "processing"; + + // Platform + private static final String OS_NAME = System.getProperty("os.name").toLowerCase(); + private static final String OS_ARCH = System.getProperty("os.arch").toLowerCase(); + + private static final String platform; + private static final String architecture; + private static final String libraryExtension; + + static { + // platform + if (OS_NAME.contains("mac") || OS_NAME.contains("darwin")) { + platform = "macos"; + libraryExtension = "dylib"; + } else if (OS_NAME.contains("win")) { + platform = "windows"; + libraryExtension = "dll"; + } else if (OS_NAME.contains("linux")) { + platform = "linux"; + libraryExtension = "so"; + } else { + throw new UnsupportedOperationException("Unsupported OS: " + OS_NAME); + } + + // architecture + if (OS_ARCH.contains("aarch64") || OS_ARCH.contains("arm")) { + architecture = "aarch64"; + } else if (OS_ARCH.contains("x86_64") || OS_ARCH.contains("amd64")) { + architecture = "x86_64"; + } else { + throw new UnsupportedOperationException("Unsupported architecture: " + OS_ARCH); + } + + // Load the dll + try { + loadNativeLibrary(); + loaded = true; + } catch (Throwable e) { + loadError = e; + System.err.println("Warning: Failed to load Processing native library: " + e.getMessage()); + } + } + + /** + * Ensures the native library is loaded. Throws if loading failed. + */ + public static void ensureLoaded() { + if (!loaded) { + throw new RuntimeException("Native library failed to load", loadError); + } + } + + /** + * Returns whether the native library was successfully loaded. + */ + public static boolean isLoaded() { + return loaded; + } + + /** + * Returns the platform string (e.g., "macos-aarch64"). + */ + public static String getPlatform() { + return platform + "-" + architecture; + } + + /** + * Extracts and loads the native library from JAR resources. + */ + private static void loadNativeLibrary() throws IOException { + String platformTarget = platform + "-" + architecture; + String libraryFileName = "lib" + LIBRARY_NAME + "." + libraryExtension; + String resourcePath = "/native/" + platformTarget + "/" + libraryFileName; + + // check classloader for resource in jar + InputStream libraryStream = NativeLibrary.class.getResourceAsStream(resourcePath); + if (libraryStream == null) { + throw new FileNotFoundException( + "Native library not found in JAR: " + resourcePath + + " (platform: " + platformTarget + ")" + ); + } + + // extract + Path tempDir = Files.createTempDirectory("processing-native-"); + tempDir.toFile().deleteOnExit(); + + Path libraryPath = tempDir.resolve(libraryFileName); + Files.copy(libraryStream, libraryPath, StandardCopyOption.REPLACE_EXISTING); + libraryStream.close(); + + libraryPath.toFile().deleteOnExit(); + + // load! + System.load(libraryPath.toAbsolutePath().toString()); + } +} diff --git a/core/src/processing/webgpu/PWebGPU.java b/core/src/processing/webgpu/PWebGPU.java new file mode 100644 index 000000000..304b5b26d --- /dev/null +++ b/core/src/processing/webgpu/PWebGPU.java @@ -0,0 +1,28 @@ +package processing.webgpu; + +import processing.core.NativeLibrary; +import processing.ffi.processing_h; + +/** + * PWebGPU provides the native interface layer for libProcessing's WebGPU support. + */ +public class PWebGPU { + + static { + NativeLibrary.ensureLoaded(); + } + + /** + * Ensure the native library is loaded. + */ + public static void ensureLoaded() { + NativeLibrary.ensureLoaded(); + } + + /** + * It's just math, silly! + */ + public static long add(long left, long right) { + return processing_h.processing_add(left, right); + } +} diff --git a/core/test/processing/webgpu/PWebGPUTest.java b/core/test/processing/webgpu/PWebGPUTest.java new file mode 100644 index 000000000..4b77d7aa7 --- /dev/null +++ b/core/test/processing/webgpu/PWebGPUTest.java @@ -0,0 +1,15 @@ +package processing.webgpu; + +import org.junit.Test; +import static org.junit.Assert.*; + +/** + * Tests for the PWebGPU native interface. + */ +public class PWebGPUTest { + @Test + public void testAddFunction() { + long result = PWebGPU.add(2, 2); + assertEquals("2 + 2 should equal 4", 4L, result); + } +} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 050502f4c..3b7e92605 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,6 +1,6 @@ [versions] -kotlin = "2.0.20" -compose-plugin = "1.7.1" +kotlin = "2.3.0-Beta1" +compose-plugin = "1.9.0" jogl = "2.5.0" antlr = "4.13.2" jupiter = "5.12.0" diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 94113f200..2e1113280 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.11-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.1.0-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/java/libraries/dxf/build.gradle.kts b/java/libraries/dxf/build.gradle.kts index cf4e3f507..eb8326b5d 100644 --- a/java/libraries/dxf/build.gradle.kts +++ b/java/libraries/dxf/build.gradle.kts @@ -12,6 +12,7 @@ sourceSets { repositories{ mavenCentral() maven("https://jogamp.org/deployment/maven/") + maven("https://maven.pkg.jetbrains.space/public/p/kotlin/p/kotlin/bootstrap") // Kotlin EAP repository } dependencies{ diff --git a/libProcessing/Cargo.lock b/libProcessing/Cargo.lock index 331701f44..8611d649c 100644 --- a/libProcessing/Cargo.lock +++ b/libProcessing/Cargo.lock @@ -2,14 +2,527 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "anstream" +version = "0.6.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" + +[[package]] +name = "anstyle-parse" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2" +dependencies = [ + "windows-sys 0.60.2", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a" +dependencies = [ + "anstyle", + "once_cell_polyfill", + "windows-sys 0.60.2", +] + +[[package]] +name = "bitflags" +version = "2.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394" + +[[package]] +name = "cbindgen" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "975982cdb7ad6a142be15bdf84aea7ec6a9e5d4d797c004d43185b24cfe4e684" +dependencies = [ + "clap", + "heck", + "indexmap", + "log", + "proc-macro2", + "quote", + "serde", + "serde_json", + "syn", + "tempfile", + "toml", +] + +[[package]] +name = "cfg-if" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" + +[[package]] +name = "clap" +version = "4.5.49" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4512b90fa68d3a9932cea5184017c5d200f5921df706d45e853537dea51508f" +dependencies = [ + "clap_builder", +] + +[[package]] +name = "clap_builder" +version = "4.5.49" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0025e98baa12e766c67ba13ff4695a887a1eba19569aad00a472546795bd6730" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_lex" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" + +[[package]] +name = "colorchoice" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + [[package]] name = "ffi" version = "0.1.0" +dependencies = [ + "cbindgen", + "renderer", +] + +[[package]] +name = "getrandom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasip2", +] + +[[package]] +name = "hashbrown" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "indexmap" +version = "2.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + +[[package]] +name = "itoa" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "libProcessing" version = "0.1.0" +[[package]] +name = "libc" +version = "0.2.177" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" + +[[package]] +name = "linux-raw-sys" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" + +[[package]] +name = "log" +version = "0.4.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" + +[[package]] +name = "memchr" +version = "2.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "once_cell_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" + +[[package]] +name = "proc-macro2" +version = "1.0.101" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + [[package]] name = "renderer" version = "0.1.0" + +[[package]] +name = "rustix" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.61.2", +] + +[[package]] +name = "ryu" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.145" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", + "serde_core", +] + +[[package]] +name = "serde_spanned" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" +dependencies = [ + "serde", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "syn" +version = "2.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tempfile" +version = "3.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" +dependencies = [ + "fastrand", + "getrandom", + "once_cell", + "rustix", + "windows-sys 0.61.2", +] + +[[package]] +name = "toml" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.22.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "toml_write", + "winnow", +] + +[[package]] +name = "toml_write" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" + +[[package]] +name = "unicode-ident" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "wasip2" +version = "1.0.1+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" +dependencies = [ + "wit-bindgen", +] + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-targets" +version = "0.53.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" +dependencies = [ + "windows-link", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" + +[[package]] +name = "windows_i686_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" + +[[package]] +name = "windows_i686_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" + +[[package]] +name = "winnow" +version = "0.7.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf" +dependencies = [ + "memchr", +] + +[[package]] +name = "wit-bindgen" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" diff --git a/libProcessing/ffi/Cargo.toml b/libProcessing/ffi/Cargo.toml index 68c7917cd..243f499d1 100644 --- a/libProcessing/ffi/Cargo.toml +++ b/libProcessing/ffi/Cargo.toml @@ -3,4 +3,12 @@ name = "ffi" version = "0.1.0" edition = "2024" +[lib] +name = "processing" +crate-type = ["cdylib"] + [dependencies] +renderer = { path = "../renderer" } + +[build-dependencies] +cbindgen = "0.29" diff --git a/libProcessing/ffi/build.rs b/libProcessing/ffi/build.rs new file mode 100644 index 000000000..b9dcb3d61 --- /dev/null +++ b/libProcessing/ffi/build.rs @@ -0,0 +1,23 @@ +use std::env; +use std::path::PathBuf; + +fn main() { + let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap(); + let output_dir = PathBuf::from(&crate_dir).join("include"); + + std::fs::create_dir_all(&output_dir).expect("Failed to create include directory"); + + let output_file = output_dir.join("processing.h"); + let config_path = PathBuf::from(&crate_dir).join("cbindgen.toml"); + + cbindgen::Builder::new() + .with_config(cbindgen::Config::from_file(&config_path).expect("Failed to load cbindgen.toml")) + .with_crate(&crate_dir) + .generate() + .expect("Unable to generate bindings") + .write_to_file(&output_file); + + println!("cargo:rerun-if-changed=src/lib.rs"); + println!("cargo:rerun-if-changed=cbindgen.toml"); + println!("cargo:warning=Generated header at: {}", output_file.display()); +} diff --git a/libProcessing/ffi/cbindgen.toml b/libProcessing/ffi/cbindgen.toml new file mode 100644 index 000000000..923b8ac56 --- /dev/null +++ b/libProcessing/ffi/cbindgen.toml @@ -0,0 +1,12 @@ +language = "C" +pragma_once = true +include_guard = "PROCESSING_H" +autogen_warning = "/* Warning, this file is autogenerated by cbindgen. Don't modify this manually. */" +include_version = true +documentation = true +documentation_style = "c99" + +[export] +# Export all + +[export.rename] \ No newline at end of file diff --git a/libProcessing/ffi/include/processing.h b/libProcessing/ffi/include/processing.h new file mode 100644 index 000000000..32b7ab01e --- /dev/null +++ b/libProcessing/ffi/include/processing.h @@ -0,0 +1,17 @@ +#ifndef PROCESSING_H +#define PROCESSING_H + +#pragma once + +/* Generated with cbindgen:0.29.0 */ + +/* Warning, this file is autogenerated by cbindgen. Don't modify this manually. */ + +#include +#include +#include +#include + +uint64_t processing_add(uint64_t left, uint64_t right); + +#endif /* PROCESSING_H */ diff --git a/libProcessing/ffi/src/lib.rs b/libProcessing/ffi/src/lib.rs index b93cf3ffd..9381e76b5 100644 --- a/libProcessing/ffi/src/lib.rs +++ b/libProcessing/ffi/src/lib.rs @@ -1,14 +1,4 @@ -pub fn add(left: u64, right: u64) -> u64 { - left + right -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn it_works() { - let result = add(2, 2); - assert_eq!(result, 4); - } -} +#[unsafe(no_mangle)] +pub extern "C" fn processing_add(left: u64, right: u64) -> u64 { + renderer::add(left, right) +} \ No newline at end of file diff --git a/libProcessing/renderer/src/lib.rs b/libProcessing/renderer/src/lib.rs index b93cf3ffd..048c97f07 100644 --- a/libProcessing/renderer/src/lib.rs +++ b/libProcessing/renderer/src/lib.rs @@ -1,14 +1,4 @@ pub fn add(left: u64, right: u64) -> u64 { + println!("Adding {} and {} in Rust", left, right); left + right -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn it_works() { - let result = add(2, 2); - assert_eq!(result, 4); - } -} +} \ No newline at end of file From a596ad2f0639bb8c5670dc3535864632d706d9a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?charlotte=20=F0=9F=8C=B8?= Date: Wed, 15 Oct 2025 10:33:32 -0700 Subject: [PATCH 04/26] Remove EAP. --- java/libraries/dxf/build.gradle.kts | 1 - 1 file changed, 1 deletion(-) diff --git a/java/libraries/dxf/build.gradle.kts b/java/libraries/dxf/build.gradle.kts index eb8326b5d..cf4e3f507 100644 --- a/java/libraries/dxf/build.gradle.kts +++ b/java/libraries/dxf/build.gradle.kts @@ -12,7 +12,6 @@ sourceSets { repositories{ mavenCentral() maven("https://jogamp.org/deployment/maven/") - maven("https://maven.pkg.jetbrains.space/public/p/kotlin/p/kotlin/bootstrap") // Kotlin EAP repository } dependencies{ From 9ae1d017bda2bd7aee43957edd3bbe7a90225eb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?charlotte=20=F0=9F=8C=B8?= Date: Wed, 15 Oct 2025 10:49:31 -0700 Subject: [PATCH 05/26] Update docs. --- BUILD.md | 52 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 14 deletions(-) diff --git a/BUILD.md b/BUILD.md index a7176776a..e44112537 100644 --- a/BUILD.md +++ b/BUILD.md @@ -12,9 +12,9 @@ First, [download the IntelliJ IDEA Community Edition](https://www.jetbrains.com/ 1. Clone the Processing4 repository to your machine locally 1. Open the cloned repository in IntelliJ IDEA CE 1. When prompted, select **Trust Project**. You can preview the project in Safe Mode but you won't be able to build Processing. -1. IntelliJ may ask if you want to load Gradle project. If you allow this, make sure you are using JDK version 17. +1. IntelliJ may ask if you want to load Gradle project. If you allow this, make sure you are using JDK version 25. 1. In the main menu, go to File > Project Structure > Project Settings > Project. -1. In the SDK Dropdown option, select a JDK version 17 or Download the jdk +1. In the SDK Dropdown option, select a JDK version 25 or Download the jdk 1. Click the green Run Icon in the top right of the window. This is also where you can find the option to debug Processing. 1. Logs can be found in the `Build` or `Debug` pane on the bottom left of the window @@ -46,18 +46,43 @@ If you don't have them installed, you will need to install [Git](https://git-scm cd processing4 ``` -2. **Install Temurin JDK 17:** - - Download and install the appropriate version for your platform: +2. **Install Temurin JDK 25:** + +Processing requires the Temurin distribution of OpenJDK. - - [Linux (x86)](https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.15%2B6/OpenJDK17U-jdk_x64_linux_hotspot_17.0.15_6.tar.gz) - - [macOS (Apple Silicon)](https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.15%2B6/OpenJDK17U-jdk_aarch64_mac_hotspot_17.0.15_6.pkg) - - [Other platforms](https://adoptium.net/temurin/releases/?package=jdk&version=17&os=any&arch=any) +You can download it from [Adoptium](https://adoptium.net/), from [GitHub releases](https://github.com/adoptium/temurin25-binaries/releases), +or find it in the package manager for your platform. + +### macOS: +```bash +brew install --cask temurin@25 +```` + +### Windows (using winget): +```bash +winget install --id=EclipseAdoptium.Temurin.25.JDK -e +``` + +### SDKMAN! + +[SDKMAN!](https://sdkman.io/) is a useful tool for developers working on multiple versions of the JVM. + +## Install `jextract` + +`jextract` is a tool included in the JDK that generates Java bindings from C header files. +It is required to build Processing when using WebGPU. You can download it [here](https://jdk.java.net/jextract/) +or install it using SDKMAN!: + +```bash +sdk install jextract +```` 3. **Set the `JAVA_HOME` environment variable:** +It may be necessary to set the `JAVA_HOME` environment variable to point to your Temurin JDK 25 installation. + ```bash - export JAVA_HOME=/path/to/temurin/jdk-17.0.15+6/ + export JAVA_HOME=/path/to/temurin/jdk-25/ ``` ### Build, Run, and Package Processing @@ -136,18 +161,18 @@ If you are specifically trying to run the `Processing CLI`, you can test command If you’re building Processing using IntelliJ IDEA and something’s not working, here are a few things that might help: -### Use the Correct JDK (temurin-17) +### Use the Correct JDK (temurin-25) -Make sure IntelliJ is using **temurin-17**, not another version. Some users have reported issues with ms-17. +Make sure IntelliJ is using **temurin-25**, not another version. 1. Go to **File > Project Structure > Project** -2. Set the **Project SDK** to: `temurin-17 java version "17.0.15"` +2. Set the **Project SDK** to: `temurin-25"` ![JDK Selection](.github/media/troubleshooting-Intellij-setting-djk-version-manually.png) If it is not already installed, you can download it by: 1. Clicking the SDK input field and then selecting the `Download JDK...` option from the menu -2. Select Version: `17`, Vendor: `Eclipse Temurin (AdoptOpenJDK HotSpot)` +2. Select Version: `25`, Vendor: `Eclipse Temurin (AdoptOpenJDK HotSpot)` ![JDK Download](.github/media/troubleshooting-Intellij-download-jdk.png) @@ -155,7 +180,6 @@ If it is not already installed, you can download it by: Now go back to your main window and 1. Click the green Run Icon in the top right of the window. - ### “Duplicate content roots detected” You may see this warning in IntelliJ: From 8f2542b84941899d440a0ea68a0ab1c2f519ac87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?charlotte=20=F0=9F=8C=B8?= Date: Thu, 16 Oct 2025 13:01:44 -0700 Subject: [PATCH 06/26] Factor out gradle utils. Add flag for disabling webgpu and enforcing android source level compat. --- .gitignore | 2 + app/build.gradle.kts | 83 +------- build.gradle.kts | 14 +- buildSrc/build.gradle.kts | 7 + .../processing/gradle/CargoBuildTask.kt | 56 +++++ .../processing/gradle/CargoCleanTask.kt | 38 ++++ .../processing/gradle/DownloadJextractTask.kt | 60 ++++++ .../gradle/GenerateJextractBindingsTask.kt | 49 +++++ .../kotlin/processing/gradle/JextractUtils.kt | 29 +++ .../kotlin/processing/gradle/PlatformUtils.kt | 53 +++++ .../processing/gradle/SignResourcesTask.kt | 108 ++++++++++ core/build.gradle.kts | 191 +++++++++--------- 12 files changed, 505 insertions(+), 185 deletions(-) create mode 100644 buildSrc/build.gradle.kts create mode 100644 buildSrc/src/main/kotlin/processing/gradle/CargoBuildTask.kt create mode 100644 buildSrc/src/main/kotlin/processing/gradle/CargoCleanTask.kt create mode 100644 buildSrc/src/main/kotlin/processing/gradle/DownloadJextractTask.kt create mode 100644 buildSrc/src/main/kotlin/processing/gradle/GenerateJextractBindingsTask.kt create mode 100644 buildSrc/src/main/kotlin/processing/gradle/JextractUtils.kt create mode 100644 buildSrc/src/main/kotlin/processing/gradle/PlatformUtils.kt create mode 100644 buildSrc/src/main/kotlin/processing/gradle/SignResourcesTask.kt diff --git a/.gitignore b/.gitignore index 67057f942..6a81e3cf7 100644 --- a/.gitignore +++ b/.gitignore @@ -124,3 +124,5 @@ generated/ /app/windows/obj /java/gradle/build /java/gradle/example/.processing + +libProcessing/ffi/include/* \ No newline at end of file diff --git a/app/build.gradle.kts b/app/build.gradle.kts index f2615ce14..0dd13783c 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -1,94 +1,13 @@ import org.gradle.internal.jvm.Jvm import org.gradle.internal.os.OperatingSystem import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform -import org.gradle.process.ExecOperations import org.jetbrains.compose.desktop.application.dsl.TargetFormat import org.jetbrains.compose.desktop.application.tasks.AbstractJPackageTask import org.jetbrains.compose.internal.de.undercouch.gradle.tasks.download.Download -import java.io.FileOutputStream -import java.util.zip.ZipEntry -import java.util.zip.ZipOutputStream -import javax.inject.Inject +import processing.gradle.SignResourcesTask // TODO: Update to 2.10.20 and add hot-reloading: https://github.com/JetBrains/compose-hot-reload -abstract class SignResourcesTask : DefaultTask() { - @get:Inject - abstract val execOperations: ExecOperations - - @get:InputDirectory - abstract val resourcesPath: DirectoryProperty - - @TaskAction - fun signResources() { - val resourcesDir = resourcesPath.get().asFile - val jars = mutableListOf() - - // Copy Info.plist if present - project.fileTree(resourcesDir) - .matching { include("**/Info.plist") } - .singleOrNull() - ?.let { file -> - project.copy { - from(file) - into(resourcesDir) - } - } - - project.fileTree(resourcesDir) { - include("**/*.jar") - exclude("**/*.jar.tmp/**") - }.forEach { file -> - val tempDir = file.parentFile.resolve("${file.name}.tmp") - project.copy { - from(project.zipTree(file)) - into(tempDir) - } - file.delete() - jars.add(tempDir) - } - - project.fileTree(resourcesDir) { - include("**/bin/**") - include("**/*.jnilib") - include("**/*.dylib") - include("**/*aarch64*") - include("**/*x86_64*") - include("**/*ffmpeg*") - include("**/ffmpeg*/**") - exclude("jdk/**") - exclude("*.jar") - exclude("*.so") - exclude("*.dll") - }.forEach { file -> - execOperations.exec { - commandLine("codesign", "--timestamp", "--force", "--deep", "--options=runtime", "--sign", "Developer ID Application", file) - } - } - - jars.forEach { file -> - FileOutputStream(File(file.parentFile, file.nameWithoutExtension)).use { fos -> - ZipOutputStream(fos).use { zos -> - file.walkTopDown().forEach { fileEntry -> - if (fileEntry.isFile) { - val zipEntryPath = fileEntry.relativeTo(file).path - val entry = ZipEntry(zipEntryPath) - zos.putNextEntry(entry) - fileEntry.inputStream().use { input -> - input.copyTo(zos) - } - zos.closeEntry() - } - } - } - } - file.deleteRecursively() - } - - File(resourcesDir, "Info.plist").delete() - } -} - plugins{ id("java") kotlin("jvm") version libs.versions.kotlin diff --git a/build.gradle.kts b/build.gradle.kts index 06137398a..90920c22e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -12,15 +12,23 @@ plugins { // Can be deleted after the migration to Gradle is complete layout.buildDirectory = file(".build") +val enableWebGPU = findProperty("enableWebGPU")?.toString()?.toBoolean() ?: true + allprojects { tasks.withType().configureEach { - sourceCompatibility = "24" - targetCompatibility = "24" + val javaVersion = if (project.name == "core" && enableWebGPU) "24" else "17" + sourceCompatibility = javaVersion + targetCompatibility = javaVersion } tasks.withType().configureEach { compilerOptions { - jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_24) + val kotlinTarget = if (project.name == "core" && enableWebGPU) { + org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_24 + } else { + org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17 + } + jvmTarget.set(kotlinTarget) } } } diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts new file mode 100644 index 000000000..876c922b2 --- /dev/null +++ b/buildSrc/build.gradle.kts @@ -0,0 +1,7 @@ +plugins { + `kotlin-dsl` +} + +repositories { + mavenCentral() +} diff --git a/buildSrc/src/main/kotlin/processing/gradle/CargoBuildTask.kt b/buildSrc/src/main/kotlin/processing/gradle/CargoBuildTask.kt new file mode 100644 index 000000000..0b73d75ac --- /dev/null +++ b/buildSrc/src/main/kotlin/processing/gradle/CargoBuildTask.kt @@ -0,0 +1,56 @@ +package processing.gradle + +import org.gradle.api.DefaultTask +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.file.RegularFileProperty +import org.gradle.api.provider.Property +import org.gradle.api.tasks.* +import org.gradle.process.ExecOperations +import javax.inject.Inject + +abstract class CargoBuildTask : DefaultTask() { + + @get:Inject + abstract val execOperations: ExecOperations + + @get:InputDirectory + abstract val cargoWorkspaceDir: DirectoryProperty + + @get:Input + abstract val manifestPath: Property + + @get:Input + abstract val release: Property + + @get:Input + abstract val cargoPath: Property + + @get:OutputFile + abstract val outputLibrary: RegularFileProperty + + init { + group = "rust" + description = "Builds Rust library using cargo" + + // release by default + release.convention(true) + } + + @TaskAction + fun build() { + val buildType = if (release.get()) "release" else "debug" + logger.lifecycle("Building Rust library ($buildType mode)...") + + val args = mutableListOf("build") + if (release.get()) { + args.add("--release") + } + args.add("--manifest-path") + args.add(manifestPath.get()) + + execOperations.exec { + workingDir = cargoWorkspaceDir.get().asFile + commandLine = listOf(cargoPath.get()) + args + } + } +} diff --git a/buildSrc/src/main/kotlin/processing/gradle/CargoCleanTask.kt b/buildSrc/src/main/kotlin/processing/gradle/CargoCleanTask.kt new file mode 100644 index 000000000..1caf9133b --- /dev/null +++ b/buildSrc/src/main/kotlin/processing/gradle/CargoCleanTask.kt @@ -0,0 +1,38 @@ +package processing.gradle + +import org.gradle.api.DefaultTask +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.provider.Property +import org.gradle.api.tasks.* +import org.gradle.process.ExecOperations +import javax.inject.Inject + +abstract class CargoCleanTask : DefaultTask() { + + @get:Inject + abstract val execOperations: ExecOperations + + @get:InputDirectory + abstract val cargoWorkspaceDir: DirectoryProperty + + @get:Input + abstract val manifestPath: Property + + @get:Input + abstract val cargoPath: Property + + init { + group = "rust" + description = "Cleans Rust build artifacts" + } + + @TaskAction + fun clean() { + logger.lifecycle("Cleaning Rust build artifacts...") + + execOperations.exec { + workingDir = cargoWorkspaceDir.get().asFile + commandLine(cargoPath.get(), "clean", "--manifest-path", manifestPath.get()) + } + } +} diff --git a/buildSrc/src/main/kotlin/processing/gradle/DownloadJextractTask.kt b/buildSrc/src/main/kotlin/processing/gradle/DownloadJextractTask.kt new file mode 100644 index 000000000..254195a38 --- /dev/null +++ b/buildSrc/src/main/kotlin/processing/gradle/DownloadJextractTask.kt @@ -0,0 +1,60 @@ +package processing.gradle + +import org.gradle.api.DefaultTask +import org.gradle.api.GradleException +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.file.RegularFileProperty +import org.gradle.api.provider.Property +import org.gradle.api.tasks.* +import java.net.URI + +abstract class DownloadJextractTask : DefaultTask() { + + @get:Input + abstract val jextractVersion: Property + + @get:Input + abstract val platform: Property + + @get:OutputDirectory + abstract val jextractDir: DirectoryProperty + + @get:Internal + abstract val downloadTarball: RegularFileProperty + + init { + group = "rust" + description = "Downloads and extracts jextract for the current platform" + } + + @TaskAction + fun download() { + val version = jextractVersion.get() + val plat = platform.get() + val fileName = "openjdk-$version" + "_${plat}_bin.tar.gz" + val downloadUrl = "https://download.java.net/java/early_access/jextract/22/6/$fileName" + val tarFile = downloadTarball.get().asFile + + if (!tarFile.exists()) { + logger.lifecycle("Downloading jextract from $downloadUrl") + try { + tarFile.outputStream().use { output -> + URI.create(downloadUrl).toURL().openStream().use { input -> + input.copyTo(output) + } + } + } catch (e: Exception) { + throw GradleException("Failed to download jextract: ${e.message}", e) + } + } + + val extractDir = jextractDir.get().asFile + logger.lifecycle("Extracting jextract to ${extractDir.parent}") + project.copy { + from(project.tarTree(tarFile)) + into(extractDir.parent) + } + + logger.lifecycle("jextract extracted to: $extractDir") + } +} diff --git a/buildSrc/src/main/kotlin/processing/gradle/GenerateJextractBindingsTask.kt b/buildSrc/src/main/kotlin/processing/gradle/GenerateJextractBindingsTask.kt new file mode 100644 index 000000000..22fc9c240 --- /dev/null +++ b/buildSrc/src/main/kotlin/processing/gradle/GenerateJextractBindingsTask.kt @@ -0,0 +1,49 @@ +package processing.gradle + +import org.gradle.api.DefaultTask +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.file.RegularFileProperty +import org.gradle.api.provider.Property +import org.gradle.api.tasks.* +import org.gradle.process.ExecOperations +import javax.inject.Inject + +abstract class GenerateJextractBindingsTask : DefaultTask() { + + @get:Inject + abstract val execOperations: ExecOperations + + @get:InputFile + abstract val headerFile: RegularFileProperty + + @get:OutputDirectory + abstract val outputDirectory: DirectoryProperty + + @get:Input + abstract val targetPackage: Property + + @get:Input + abstract val jextractPath: Property + + init { + group = "rust" + description = "Generates Java Panama FFM bindings from C headers" + } + + @TaskAction + fun generate() { + val outDir = outputDirectory.get().asFile + outDir.mkdirs() + + logger.lifecycle("Generating Java bindings from ${headerFile.get().asFile}...") + + execOperations.exec { + commandLine( + jextractPath.get(), + "--output", outDir.absolutePath, + "--target-package", targetPackage.get(), + headerFile.get().asFile.absolutePath + ) + } + } +} diff --git a/buildSrc/src/main/kotlin/processing/gradle/JextractUtils.kt b/buildSrc/src/main/kotlin/processing/gradle/JextractUtils.kt new file mode 100644 index 000000000..505a222a5 --- /dev/null +++ b/buildSrc/src/main/kotlin/processing/gradle/JextractUtils.kt @@ -0,0 +1,29 @@ +package processing.gradle + +object JextractUtils { + fun findUserJextract(): String? { + val jextractHome = System.getenv("JEXTRACT_HOME") ?: return null + + val isWindows = System.getProperty("os.name").lowercase().contains("windows") + val path = if (isWindows) { + "$jextractHome/bin/jextract.bat" + } else { + "$jextractHome/bin/jextract" + } + + val file = java.io.File(path) + if (file.exists()) { + return path + } + + return null + } + + fun getExecutableName(): String { + return if (System.getProperty("os.name").lowercase().contains("windows")) { + "jextract.bat" + } else { + "jextract" + } + } +} diff --git a/buildSrc/src/main/kotlin/processing/gradle/PlatformUtils.kt b/buildSrc/src/main/kotlin/processing/gradle/PlatformUtils.kt new file mode 100644 index 000000000..f442dba98 --- /dev/null +++ b/buildSrc/src/main/kotlin/processing/gradle/PlatformUtils.kt @@ -0,0 +1,53 @@ +package processing.gradle + +import org.gradle.api.GradleException + +object PlatformUtils { + data class Platform( + val os: String, + val arch: String, + val libExtension: String, + val target: String + ) { + val libName: String + get() = if (os == "windows") "processing.$libExtension" else "libprocessing.$libExtension" + + val jextractPlatform: String + get() { + val jextractArch = if (arch == "x86_64") "x64" else arch + return "$os-$jextractArch" + } + } + + fun detect(): Platform { + val osName = System.getProperty("os.name").lowercase() + val osArch = System.getProperty("os.arch").lowercase() + + val os = when { + osName.contains("mac") || osName.contains("darwin") -> "macos" + osName.contains("win") -> "windows" + osName.contains("linux") -> "linux" + else -> throw GradleException("Unsupported OS: $osName") + } + + val arch = when { + osArch.contains("aarch64") || osArch.contains("arm") -> "aarch64" + osArch.contains("x86_64") || osArch.contains("amd64") -> "x86_64" + else -> throw GradleException("Unsupported architecture: $osArch") + } + + val libExtension = when (os) { + "macos" -> "dylib" + "windows" -> "dll" + "linux" -> "so" + else -> throw GradleException("Unknown platform: $os") + } + + return Platform(os, arch, libExtension, "$os-$arch") + } + + fun getCargoPath(): String { + return System.getenv("CARGO_HOME")?.let { "$it/bin/cargo" } + ?: "${System.getProperty("user.home")}/.cargo/bin/cargo" + } +} diff --git a/buildSrc/src/main/kotlin/processing/gradle/SignResourcesTask.kt b/buildSrc/src/main/kotlin/processing/gradle/SignResourcesTask.kt new file mode 100644 index 000000000..91be783ea --- /dev/null +++ b/buildSrc/src/main/kotlin/processing/gradle/SignResourcesTask.kt @@ -0,0 +1,108 @@ +package processing.gradle + +import org.gradle.api.DefaultTask +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.tasks.InputDirectory +import org.gradle.api.tasks.TaskAction +import org.gradle.process.ExecOperations +import java.io.File +import java.io.FileOutputStream +import java.util.zip.ZipEntry +import java.util.zip.ZipOutputStream +import javax.inject.Inject + +abstract class SignResourcesTask : DefaultTask() { + + @get:Inject + abstract val execOperations: ExecOperations + + @get:InputDirectory + abstract val resourcesPath: DirectoryProperty + + init { + group = "compose desktop" + description = "Signs macOS resources (binaries and libraries) for distribution" + } + + @TaskAction + fun signResources() { + val resourcesDir = resourcesPath.get().asFile + val jars = mutableListOf() + + // Copy Info.plist if present + project.fileTree(resourcesDir) + .matching { include("**/Info.plist") } + .singleOrNull() + ?.let { file -> + project.copy { + from(file) + into(resourcesDir) + } + } + + // Extract JARs to temporary directories for signing + project.fileTree(resourcesDir) { + include("**/*.jar") + exclude("**/*.jar.tmp/**") + }.forEach { file -> + val tempDir = file.parentFile.resolve("${file.name}.tmp") + project.copy { + from(project.zipTree(file)) + into(tempDir) + } + file.delete() + jars.add(tempDir) + } + + // Sign all binaries and native libraries + project.fileTree(resourcesDir) { + include("**/bin/**") + include("**/*.jnilib") + include("**/*.dylib") + include("**/*aarch64*") + include("**/*x86_64*") + include("**/*ffmpeg*") + include("**/ffmpeg*/**") + exclude("jdk/**") + exclude("*.jar") + exclude("*.so") + exclude("*.dll") + }.forEach { file -> + execOperations.exec { + commandLine( + "codesign", + "--timestamp", + "--force", + "--deep", + "--options=runtime", + "--sign", + "Developer ID Application", + file + ) + } + } + + // Repackage JARs after signing + jars.forEach { file -> + FileOutputStream(File(file.parentFile, file.nameWithoutExtension)).use { fos -> + ZipOutputStream(fos).use { zos -> + file.walkTopDown().forEach { fileEntry -> + if (fileEntry.isFile) { + val zipEntryPath = fileEntry.relativeTo(file).path + val entry = ZipEntry(zipEntryPath) + zos.putNextEntry(entry) + fileEntry.inputStream().use { input -> + input.copyTo(zos) + } + zos.closeEntry() + } + } + } + } + file.deleteRecursively() + } + + // Clean up Info.plist + File(resourcesDir, "Info.plist").delete() + } +} diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 41d3de6bd..30a79fcc4 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -1,4 +1,5 @@ import com.vanniktech.maven.publish.SonatypeHost +import processing.gradle.* plugins { id("java") @@ -11,10 +12,16 @@ repositories { maven { url = uri("https://jogamp.org/deployment/maven") } } +val enableWebGPU = findProperty("enableWebGPU")?.toString()?.toBoolean() ?: true + sourceSets{ main{ java{ srcDirs("src") + if (!enableWebGPU) { + exclude("processing/webgpu/**") + exclude("processing/ffi/**") + } } resources{ srcDirs("src") @@ -35,136 +42,120 @@ dependencies { testImplementation(libs.junit) } -val osName = System.getProperty("os.name").lowercase() -val osArch = System.getProperty("os.arch").lowercase() - -val platformName = when { - osName.contains("mac") || osName.contains("darwin") -> "macos" - osName.contains("win") -> "windows" - osName.contains("linux") -> "linux" - else -> throw GradleException("Unsupported OS: $osName") -} - -val archName = when { - osArch.contains("aarch64") || osArch.contains("arm") -> "aarch64" - osArch.contains("x86_64") || osArch.contains("amd64") -> "x86_64" - else -> throw GradleException("Unsupported architecture: $osArch") -} - -val libExtension = when (platformName) { - "macos" -> "dylib" - "windows" -> "dll" - "linux" -> "so" - else -> throw GradleException("Unknown platform: $platformName") -} - -val libName = when (platformName) { - "windows" -> "processing.$libExtension" - else -> "libprocessing.$libExtension" -} +if (enableWebGPU) { + val currentPlatform = PlatformUtils.detect() + val libProcessingDir = file("${project.rootDir}/libProcessing") + val rustTargetDir = file("$libProcessingDir/target") + val nativeOutputDir = file("${layout.buildDirectory.get()}/native/${currentPlatform.target}") + + val buildRustRelease by tasks.registering(CargoBuildTask::class) { + cargoWorkspaceDir.set(libProcessingDir) + manifestPath.set("ffi/Cargo.toml") + release.set(true) + cargoPath.set(PlatformUtils.getCargoPath()) + outputLibrary.set(file("$rustTargetDir/release/${currentPlatform.libName}")) + + inputs.files(fileTree("$libProcessingDir/ffi/src")) + inputs.file("$libProcessingDir/ffi/Cargo.toml") + inputs.file("$libProcessingDir/ffi/build.rs") + inputs.file("$libProcessingDir/ffi/cbindgen.toml") + inputs.files(fileTree("$libProcessingDir/renderer/src")) + inputs.file("$libProcessingDir/renderer/Cargo.toml") + inputs.file("$libProcessingDir/Cargo.toml") + outputs.file("$libProcessingDir/ffi/include/processing.h") + } -val platformTarget = "$platformName-$archName" -val libProcessingDir = file("${project.rootDir}/libProcessing") -val rustTargetDir = file("$libProcessingDir/target") -val nativeOutputDir = file("${layout.buildDirectory.get()}/native/$platformTarget") + val copyNativeLibs by tasks.registering(Copy::class) { + group = "rust" + description = "Copy processing library to build directory" -val cargoPath = System.getenv("CARGO_HOME")?.let { "$it/bin/cargo" } - ?: "${System.getProperty("user.home")}/.cargo/bin/cargo" + dependsOn(buildRustRelease) -val buildRustRelease by tasks.registering(Exec::class) { - group = "rust" - description = "Build Rust FFI library in release mode for current platform" + from("$rustTargetDir/release") { + include(currentPlatform.libName) + } - workingDir = libProcessingDir - commandLine = listOf(cargoPath, "build", "--release", "--manifest-path", "ffi/Cargo.toml") + into(nativeOutputDir) + } - inputs.files(fileTree("$libProcessingDir/ffi/src")) - inputs.file("$libProcessingDir/ffi/Cargo.toml") - inputs.file("$libProcessingDir/Cargo.toml") - inputs.file("$libProcessingDir/ffi/build.rs") - inputs.file("$libProcessingDir/ffi/cbindgen.toml") + val bundleNativeLibs by tasks.registering(Copy::class) { + group = "rust" + description = "Bundle native library into resources" - outputs.file("$rustTargetDir/release/$libName") - outputs.file("$libProcessingDir/ffi/include/processing.h") + dependsOn(copyNativeLibs) - doFirst { - logger.lifecycle("Building Rust library for $platformTarget...") + from(nativeOutputDir) + into("${sourceSets.main.get().output.resourcesDir}/native/${currentPlatform.target}") } -} -val copyNativeLibs by tasks.registering(Copy::class) { - group = "rust" - description = "Copy processing library to build directory" + val cleanRust by tasks.registering(CargoCleanTask::class) { + cargoWorkspaceDir.set(libProcessingDir) + manifestPath.set("ffi/Cargo.toml") + cargoPath.set(PlatformUtils.getCargoPath()) - dependsOn(buildRustRelease) + mustRunAfter(buildRustRelease) + } - from("$rustTargetDir/release") { - include("libprocessing.a") - include("libprocessing.$libExtension") + tasks.named("clean") { + dependsOn(cleanRust) } - into(nativeOutputDir) + val generatedJavaDir = file("${layout.buildDirectory.get()}/generated/sources/jextract/java") - doFirst { - logger.lifecycle("Copying native libraries to $nativeOutputDir") + sourceSets.main { + java.srcDirs(generatedJavaDir) } -} -val bundleNativeLibs by tasks.registering(Copy::class) { - group = "rust" - description = "Bundle native library into resources" + val jextractVersionString = "22-jextract+6-47" + val jextractDirectory = file("${gradle.gradleUserHomeDir}/jextract-22") + val jextractTarballFile = file("${gradle.gradleUserHomeDir}/jextract-$jextractVersionString.tar.gz") - dependsOn(copyNativeLibs) + val downloadJextract by tasks.registering(DownloadJextractTask::class) { + jextractVersion.set(jextractVersionString) + platform.set(currentPlatform.jextractPlatform) + jextractDir.set(jextractDirectory) + downloadTarball.set(jextractTarballFile) - from(nativeOutputDir) - into("${sourceSets.main.get().output.resourcesDir}/native/$platformTarget") - - doFirst { - logger.lifecycle("Bundling libraries for $platformTarget into resources") + onlyIf { !jextractDirectory.exists() } } -} -val jextractPath = "${System.getProperty("user.home")}/jextract-22/bin/jextract" -val generatedJavaDir = file("${layout.buildDirectory.get()}/generated/sources/jextract/java") -val headerFile = file("$libProcessingDir/ffi/include/processing.h") + val makeJextractExecutable by tasks.registering(Exec::class) { + group = "rust" + description = "Make jextract binary executable on Unix systems" -sourceSets.main { - java.srcDirs(generatedJavaDir) -} + dependsOn(downloadJextract) + onlyIf { !System.getProperty("os.name").lowercase().contains("windows") } -val generateJavaBindings by tasks.registering(Exec::class) { - group = "rust" - description = "Generate Java bindings from libProcessing headers using jextract" + val jextractBin = file("$jextractDirectory/bin/jextract") + commandLine("chmod", "+x", jextractBin.absolutePath) + } - dependsOn(buildRustRelease) + val generateJavaBindings by tasks.registering(GenerateJextractBindingsTask::class) { + dependsOn(buildRustRelease) - inputs.file(headerFile) + val userJextract = JextractUtils.findUserJextract() + if (userJextract == null) { + dependsOn(downloadJextract, makeJextractExecutable) + } - outputs.dir(generatedJavaDir) + headerFile.set(file("$libProcessingDir/ffi/include/processing.h")) + outputDirectory.set(generatedJavaDir) + targetPackage.set("processing.ffi") - doFirst { - generatedJavaDir.mkdirs() - logger.lifecycle("Generating Java bindings from $headerFile...") + jextractPath.set(userJextract ?: "$jextractDirectory/bin/${JextractUtils.getExecutableName()}") } - commandLine = listOf( - jextractPath, - "--output", generatedJavaDir.absolutePath, - "--target-package", "processing.ffi", - headerFile.absolutePath - ) -} - -tasks.named("compileJava") { - dependsOn(generateJavaBindings) -} + tasks.named("compileJava") { + dependsOn(generateJavaBindings) + } -tasks.named("compileKotlin") { - dependsOn(generateJavaBindings) -} + tasks.named("compileKotlin") { + dependsOn(generateJavaBindings) + } -tasks.named("processResources") { - dependsOn(bundleNativeLibs) + tasks.named("processResources") { + dependsOn(bundleNativeLibs) + } } mavenPublishing{ From 0078714a71187632b7485c7ef4967519c181f3b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?charlotte=20=F0=9F=8C=B8?= Date: Thu, 16 Oct 2025 13:10:55 -0700 Subject: [PATCH 07/26] Remove processing.h --- libProcessing/ffi/include/processing.h | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100644 libProcessing/ffi/include/processing.h diff --git a/libProcessing/ffi/include/processing.h b/libProcessing/ffi/include/processing.h deleted file mode 100644 index 32b7ab01e..000000000 --- a/libProcessing/ffi/include/processing.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef PROCESSING_H -#define PROCESSING_H - -#pragma once - -/* Generated with cbindgen:0.29.0 */ - -/* Warning, this file is autogenerated by cbindgen. Don't modify this manually. */ - -#include -#include -#include -#include - -uint64_t processing_add(uint64_t left, uint64_t right); - -#endif /* PROCESSING_H */ From 56627168b6bd80d36da664caf46734b5a7b3b658 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?charlotte=20=F0=9F=8C=B8?= Date: Thu, 16 Oct 2025 13:16:32 -0700 Subject: [PATCH 08/26] Set java version for all projects. --- build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 90920c22e..55e128bfc 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -16,14 +16,14 @@ val enableWebGPU = findProperty("enableWebGPU")?.toString()?.toBoolean() ?: true allprojects { tasks.withType().configureEach { - val javaVersion = if (project.name == "core" && enableWebGPU) "24" else "17" + val javaVersion = if (enableWebGPU) "24" else "17" sourceCompatibility = javaVersion targetCompatibility = javaVersion } tasks.withType().configureEach { compilerOptions { - val kotlinTarget = if (project.name == "core" && enableWebGPU) { + val kotlinTarget = if (enableWebGPU) { org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_24 } else { org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17 From 33b8b5289dc7f94eda45075f0d9cd80d3c3b9d17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?charlotte=20=F0=9F=8C=B8?= Date: Fri, 17 Oct 2025 08:03:21 -0700 Subject: [PATCH 09/26] libprocessing ffi error handling (#1293) * FFI error setup * Clear before init. --- .../processing/webgpu/PGraphicsWebGPU.java | 4 + core/src/processing/webgpu/PWebGPU.java | 32 +- .../processing/webgpu/PWebGPUException.java | 13 + core/test/processing/webgpu/PWebGPUTest.java | 6 +- libProcessing/Cargo.lock | 5200 ++++++++++++++++- libProcessing/Cargo.toml | 5 - libProcessing/ffi/src/error.rs | 49 + libProcessing/ffi/src/lib.rs | 7 +- libProcessing/renderer/Cargo.toml | 6 + libProcessing/renderer/src/error.rs | 12 + libProcessing/renderer/src/lib.rs | 54 +- libProcessing/src/main.rs | 3 - 12 files changed, 5166 insertions(+), 225 deletions(-) create mode 100644 core/src/processing/webgpu/PGraphicsWebGPU.java create mode 100644 core/src/processing/webgpu/PWebGPUException.java create mode 100644 libProcessing/ffi/src/error.rs create mode 100644 libProcessing/renderer/src/error.rs delete mode 100644 libProcessing/src/main.rs diff --git a/core/src/processing/webgpu/PGraphicsWebGPU.java b/core/src/processing/webgpu/PGraphicsWebGPU.java new file mode 100644 index 000000000..d0ffeef0f --- /dev/null +++ b/core/src/processing/webgpu/PGraphicsWebGPU.java @@ -0,0 +1,4 @@ +package processing.webgpu; + +public class PGraphicsWebGPU { +} diff --git a/core/src/processing/webgpu/PWebGPU.java b/core/src/processing/webgpu/PWebGPU.java index 304b5b26d..e16e0fae2 100644 --- a/core/src/processing/webgpu/PWebGPU.java +++ b/core/src/processing/webgpu/PWebGPU.java @@ -1,7 +1,12 @@ package processing.webgpu; import processing.core.NativeLibrary; -import processing.ffi.processing_h; + +import java.lang.foreign.MemorySegment; + +import static java.lang.foreign.MemorySegment.NULL; +import static processing.ffi.processing_h.processing_check_error; +import static processing.ffi.processing_h.processing_init; /** * PWebGPU provides the native interface layer for libProcessing's WebGPU support. @@ -9,7 +14,8 @@ public class PWebGPU { static { - NativeLibrary.ensureLoaded(); + ensureLoaded(); + init(); } /** @@ -20,9 +26,25 @@ public static void ensureLoaded() { } /** - * It's just math, silly! + * Initializes the WebGPU subsystem. Must be called before any other WebGPU methods. + */ + public static void init() { + processing_init(); + checkError(); + } + + /** + * Checks for errors from the native library and throws a PWebGPUException if an error occurred. */ - public static long add(long left, long right) { - return processing_h.processing_add(left, right); + private static void checkError() { + MemorySegment ret = processing_check_error(); + if (ret.equals(NULL)) { + return; + } + + String errorMsg = ret.getString(0); + if (errorMsg != null && !errorMsg.isEmpty()) { + throw new PWebGPUException(errorMsg); + } } } diff --git a/core/src/processing/webgpu/PWebGPUException.java b/core/src/processing/webgpu/PWebGPUException.java new file mode 100644 index 000000000..b3907e065 --- /dev/null +++ b/core/src/processing/webgpu/PWebGPUException.java @@ -0,0 +1,13 @@ +package processing.webgpu; + +/** + * Unchecked exception thrown for WebGPU-related errors. + *

+ * WebGPU operations can fail for various reasons, such as unsupported hardware, but are not + * expected to be recoverable by the Processing application. + */ +public class PWebGPUException extends RuntimeException { + public PWebGPUException(String message) { + super(message); + } +} diff --git a/core/test/processing/webgpu/PWebGPUTest.java b/core/test/processing/webgpu/PWebGPUTest.java index 4b77d7aa7..405e70e1c 100644 --- a/core/test/processing/webgpu/PWebGPUTest.java +++ b/core/test/processing/webgpu/PWebGPUTest.java @@ -1,15 +1,13 @@ package processing.webgpu; import org.junit.Test; -import static org.junit.Assert.*; /** * Tests for the PWebGPU native interface. */ public class PWebGPUTest { @Test - public void testAddFunction() { - long result = PWebGPU.add(2, 2); - assertEquals("2 + 2 should equal 4", 4L, result); + public void itLoads() { + PWebGPU.ensureLoaded(); } } diff --git a/libProcessing/Cargo.lock b/libProcessing/Cargo.lock index 8611d649c..507d667e6 100644 --- a/libProcessing/Cargo.lock +++ b/libProcessing/Cargo.lock @@ -2,6 +2,144 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "accesskit" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "becf0eb5215b6ecb0a739c31c21bd83c4f326524c9b46b7e882d77559b60a529" + +[[package]] +name = "accesskit_consumer" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0bf66a7bf0b7ea4fd7742d50b64782a88f99217cf246b3f93b4162528dde520" +dependencies = [ + "accesskit", + "hashbrown 0.15.5", + "immutable-chunkmap", +] + +[[package]] +name = "accesskit_macos" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09e230718177753b4e4ad9e1d9f6cfc2f4921212d4c1c480b253f526babb258d" +dependencies = [ + "accesskit", + "accesskit_consumer", + "hashbrown 0.15.5", + "objc2", + "objc2-app-kit", + "objc2-foundation", +] + +[[package]] +name = "accesskit_windows" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65178f3df98a51e4238e584fcb255cb1a4f9111820848eeddd37663be40a625f" +dependencies = [ + "accesskit", + "accesskit_consumer", + "hashbrown 0.15.5", + "paste", + "static_assertions", + "windows 0.58.0", + "windows-core 0.58.0", +] + +[[package]] +name = "accesskit_winit" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34d941bb8c414caba6e206de669c7dc0dbeb305640ea890772ee422a40e6b89f" +dependencies = [ + "accesskit", + "accesskit_macos", + "accesskit_windows", + "raw-window-handle", + "winit", +] + +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "alsa" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed7572b7ba83a31e20d1b48970ee402d2e3e0537dcfe0a3ff4d6eb7508617d43" +dependencies = [ + "alsa-sys", + "bitflags 2.9.4", + "cfg-if", + "libc", +] + +[[package]] +name = "alsa-sys" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db8fee663d06c4e303404ef5f40488a53e062f89ba8bfed81f42325aafad1527" +dependencies = [ + "libc", + "pkg-config", +] + +[[package]] +name = "android-activity" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef6978589202a00cd7e118380c448a08b6ed394c3a8df3a430d0898e3a42d046" +dependencies = [ + "android-properties", + "bitflags 2.9.4", + "cc", + "cesu8", + "jni", + "jni-sys", + "libc", + "log", + "ndk 0.9.0", + "ndk-context", + "ndk-sys 0.6.0+11769913", + "num_enum", + "thiserror 1.0.69", +] + +[[package]] +name = "android-properties" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04" + +[[package]] +name = "android_log-sys" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84521a3cf562bc62942e294181d9eef17eb38ceb8c68677bc49f144e4c3d4f8d" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + [[package]] name = "anstream" version = "0.6.21" @@ -53,256 +191,4638 @@ dependencies = [ ] [[package]] -name = "bitflags" -version = "2.9.4" +name = "approx" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394" +checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6" +dependencies = [ + "num-traits", +] [[package]] -name = "cbindgen" -version = "0.29.0" +name = "arrayref" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "975982cdb7ad6a142be15bdf84aea7ec6a9e5d4d797c004d43185b24cfe4e684" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "as-raw-xcb-connection" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "175571dd1d178ced59193a6fc02dde1b972eb0bc56c892cde9beeceac5bf0f6b" + +[[package]] +name = "ash" +version = "0.38.0+1.3.281" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bb44936d800fea8f016d7f2311c6a4f97aebd5dc86f09906139ec848cf3a46f" +dependencies = [ + "libloading", +] + +[[package]] +name = "assert_type_match" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f548ad2c4031f2902e3edc1f29c29e835829437de49562d8eb5dc5584d3a1043" dependencies = [ - "clap", - "heck", - "indexmap", - "log", "proc-macro2", "quote", - "serde", - "serde_json", "syn", - "tempfile", - "toml", ] [[package]] -name = "cfg-if" -version = "1.0.3" +name = "async-broadcast" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" +checksum = "435a87a52755b8f27fcf321ac4f04b2802e337c8c4872923137471ec39c37532" +dependencies = [ + "event-listener", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] [[package]] -name = "clap" -version = "4.5.49" +name = "async-channel" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4512b90fa68d3a9932cea5184017c5d200f5921df706d45e853537dea51508f" +checksum = "924ed96dd52d1b75e9c1a3e6275715fd320f5f9439fb5a4a11fa51f4221158d2" dependencies = [ - "clap_builder", + "concurrent-queue", + "event-listener-strategy", + "futures-core", + "pin-project-lite", ] [[package]] -name = "clap_builder" -version = "4.5.49" +name = "async-executor" +version = "1.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0025e98baa12e766c67ba13ff4695a887a1eba19569aad00a472546795bd6730" +checksum = "497c00e0fd83a72a79a39fcbd8e3e2f055d6f6c7e025f3b3d91f4f8e76527fb8" dependencies = [ - "anstream", - "anstyle", - "clap_lex", - "strsim", + "async-task", + "concurrent-queue", + "fastrand", + "futures-lite", + "pin-project-lite", + "slab", ] [[package]] -name = "clap_lex" -version = "0.7.6" +name = "async-fs" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" +checksum = "8034a681df4aed8b8edbd7fbe472401ecf009251c8b40556b304567052e294c5" +dependencies = [ + "async-lock", + "blocking", + "futures-lite", +] [[package]] -name = "colorchoice" -version = "1.0.4" +name = "async-lock" +version = "3.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" +checksum = "5fd03604047cee9b6ce9de9f70c6cd540a0520c813cbd49bae61f33ab80ed1dc" +dependencies = [ + "event-listener", + "event-listener-strategy", + "pin-project-lite", +] [[package]] -name = "equivalent" -version = "1.0.2" +name = "async-task" +version = "4.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" +checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" +dependencies = [ + "portable-atomic", +] [[package]] -name = "errno" -version = "0.3.14" +name = "atomic-waker" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" dependencies = [ - "libc", - "windows-sys 0.61.2", + "portable-atomic", ] [[package]] -name = "fastrand" -version = "2.3.0" +name = "atomicow" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" +checksum = "f52e8890bb9844440d0c412fa74b67fd2f14e85248b6e00708059b6da9e5f8bf" +dependencies = [ + "portable-atomic", + "portable-atomic-util", +] [[package]] -name = "ffi" -version = "0.1.0" +name = "autocfg" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" + +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "bevy" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b8369c16b7c017437021341521f8b4a0d98e1c70113fb358c3258ae7d661d79" dependencies = [ - "cbindgen", - "renderer", + "bevy_internal", ] [[package]] -name = "getrandom" -version = "0.3.4" +name = "bevy_a11y" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +checksum = "ed3561712cf49074d89e9989bfc2e6c6add5d33288f689db9a0c333300d2d004" dependencies = [ - "cfg-if", - "libc", - "r-efi", - "wasip2", + "accesskit", + "bevy_app", + "bevy_derive", + "bevy_ecs", + "bevy_reflect", ] [[package]] -name = "hashbrown" -version = "0.16.0" +name = "bevy_animation" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" +checksum = "49796627726d0b9a722ad9a0127719e7c1868f474d6575ec0f411e8299c4d7bb" +dependencies = [ + "bevy_app", + "bevy_asset", + "bevy_color", + "bevy_derive", + "bevy_ecs", + "bevy_log", + "bevy_math", + "bevy_mesh", + "bevy_platform", + "bevy_reflect", + "bevy_render", + "bevy_time", + "bevy_transform", + "bevy_utils", + "blake3", + "derive_more", + "downcast-rs", + "either", + "petgraph", + "ron", + "serde", + "smallvec", + "thiserror 2.0.17", + "thread_local", + "tracing", + "uuid", +] [[package]] -name = "heck" -version = "0.5.0" +name = "bevy_app" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +checksum = "4491cc4c718ae76b4c6883df58b94cc88b32dcd894ea8d5b603c7c7da72ca967" +dependencies = [ + "bevy_derive", + "bevy_ecs", + "bevy_platform", + "bevy_reflect", + "bevy_tasks", + "bevy_utils", + "cfg-if", + "console_error_panic_hook", + "ctrlc", + "downcast-rs", + "log", + "thiserror 2.0.17", + "variadics_please", + "wasm-bindgen", + "web-sys", +] [[package]] -name = "indexmap" -version = "2.11.4" +name = "bevy_asset" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5" +checksum = "f56111d9b88d8649f331a667d9d72163fb26bd09518ca16476d238653823db1e" dependencies = [ - "equivalent", - "hashbrown", + "async-broadcast", + "async-fs", + "async-lock", + "atomicow", + "bevy_app", + "bevy_asset_macros", + "bevy_ecs", + "bevy_platform", + "bevy_reflect", + "bevy_tasks", + "bevy_utils", + "bevy_window", + "bitflags 2.9.4", + "blake3", + "crossbeam-channel", + "derive_more", + "disqualified", + "downcast-rs", + "either", + "futures-io", + "futures-lite", + "js-sys", + "parking_lot", + "ron", + "serde", + "stackfuture", + "thiserror 2.0.17", + "tracing", + "uuid", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", ] [[package]] -name = "is_terminal_polyfill" -version = "1.70.1" +name = "bevy_asset_macros" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" +checksum = "a4cca3e67c0ec760d8889d42293d987ce5da92eaf9c592bf5d503728a63b276d" +dependencies = [ + "bevy_macro_utils", + "proc-macro2", + "quote", + "syn", +] [[package]] -name = "itoa" -version = "1.0.15" +name = "bevy_audio" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" +checksum = "f2b4f6f2a5c6c0e7c6825e791d2a061c76c2d6784f114c8f24382163fabbfaaa" +dependencies = [ + "bevy_app", + "bevy_asset", + "bevy_derive", + "bevy_ecs", + "bevy_math", + "bevy_reflect", + "bevy_transform", + "cpal", + "rodio", + "tracing", +] [[package]] -name = "libProcessing" -version = "0.1.0" +name = "bevy_color" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c101cbe1e26b8d701eb77263b14346e2e0cbbd2a6e254b9b1aead814e5ca8d3" +dependencies = [ + "bevy_math", + "bevy_reflect", + "bytemuck", + "derive_more", + "encase", + "serde", + "thiserror 2.0.17", + "wgpu-types", +] [[package]] -name = "libc" -version = "0.2.177" +name = "bevy_core_pipeline" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" +checksum = "59ed46363cad80dc00f08254c3015232bd6f640738403961c6d63e7ecfc61625" +dependencies = [ + "bevy_app", + "bevy_asset", + "bevy_color", + "bevy_derive", + "bevy_diagnostic", + "bevy_ecs", + "bevy_image", + "bevy_math", + "bevy_platform", + "bevy_reflect", + "bevy_render", + "bevy_transform", + "bevy_utils", + "bevy_window", + "bitflags 2.9.4", + "bytemuck", + "nonmax", + "radsort", + "serde", + "smallvec", + "thiserror 2.0.17", + "tracing", +] [[package]] -name = "linux-raw-sys" -version = "0.11.0" +name = "bevy_derive" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" +checksum = "1b837bf6c51806b10ebfa9edf1844ad80a3a0760d6c5fac4e90761df91a8901a" +dependencies = [ + "bevy_macro_utils", + "quote", + "syn", +] [[package]] -name = "log" -version = "0.4.28" +name = "bevy_diagnostic" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" +checksum = "48797366f312a8f31e237d08ce3ee70162591282d2bfe7c5ad8be196fb263e55" +dependencies = [ + "bevy_app", + "bevy_ecs", + "bevy_platform", + "bevy_tasks", + "bevy_time", + "bevy_utils", + "const-fnv1a-hash", + "log", + "serde", + "sysinfo", +] [[package]] -name = "memchr" -version = "2.7.6" +name = "bevy_ecs" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" +checksum = "3c2bf6521aae57a0ec3487c4bfb59e36c4a378e834b626a4bea6a885af2fdfe7" +dependencies = [ + "arrayvec", + "bevy_ecs_macros", + "bevy_platform", + "bevy_ptr", + "bevy_reflect", + "bevy_tasks", + "bevy_utils", + "bitflags 2.9.4", + "bumpalo", + "concurrent-queue", + "derive_more", + "disqualified", + "fixedbitset", + "indexmap", + "log", + "nonmax", + "serde", + "smallvec", + "thiserror 2.0.17", + "variadics_please", +] [[package]] -name = "once_cell" -version = "1.21.3" +name = "bevy_ecs_macros" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +checksum = "38748d6f3339175c582d751f410fb60a93baf2286c3deb7efebb0878dce7f413" +dependencies = [ + "bevy_macro_utils", + "proc-macro2", + "quote", + "syn", +] [[package]] -name = "once_cell_polyfill" -version = "1.70.1" +name = "bevy_encase_derive" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" +checksum = "8148f4edee470a2ea5cad010184c492a4c94c36d7a7158ea28e134ea87f274ab" +dependencies = [ + "bevy_macro_utils", + "encase_derive_impl", +] [[package]] -name = "proc-macro2" -version = "1.0.101" +name = "bevy_gilrs" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" +checksum = "97efef87c631949e67d06bb5d7dfd2a5f936b3b379afb6b1485b08edbb219b87" dependencies = [ - "unicode-ident", + "bevy_app", + "bevy_ecs", + "bevy_input", + "bevy_platform", + "bevy_time", + "bevy_utils", + "gilrs", + "thiserror 2.0.17", + "tracing", ] [[package]] -name = "quote" -version = "1.0.41" +name = "bevy_gizmos" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" +checksum = "7823154a9682128c261d8bddb3a4d7192a188490075c527af04520c2f0f8aad6" dependencies = [ - "proc-macro2", + "bevy_app", + "bevy_asset", + "bevy_color", + "bevy_core_pipeline", + "bevy_ecs", + "bevy_gizmos_macros", + "bevy_image", + "bevy_math", + "bevy_pbr", + "bevy_reflect", + "bevy_render", + "bevy_sprite", + "bevy_time", + "bevy_transform", + "bevy_utils", + "bytemuck", + "tracing", ] [[package]] -name = "r-efi" -version = "5.3.0" +name = "bevy_gizmos_macros" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" +checksum = "f378f3b513218ddc78254bbe76536d9de59c1429ebd0c14f5d8f2a25812131ad" +dependencies = [ + "bevy_macro_utils", + "proc-macro2", + "quote", + "syn", +] [[package]] -name = "renderer" -version = "0.1.0" - +name = "bevy_gltf" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10a080237c0b8842ccc15a06d3379302c68580eeea4497b1c7387e470eda1f07" +dependencies = [ + "base64 0.22.1", + "bevy_animation", + "bevy_app", + "bevy_asset", + "bevy_color", + "bevy_core_pipeline", + "bevy_ecs", + "bevy_image", + "bevy_math", + "bevy_mesh", + "bevy_pbr", + "bevy_platform", + "bevy_reflect", + "bevy_render", + "bevy_scene", + "bevy_tasks", + "bevy_transform", + "bevy_utils", + "fixedbitset", + "gltf", + "itertools 0.14.0", + "percent-encoding", + "serde", + "serde_json", + "smallvec", + "thiserror 2.0.17", + "tracing", +] + +[[package]] +name = "bevy_image" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65e6e900cfecadbc3149953169e36b9e26f922ed8b002d62339d8a9dc6129328" +dependencies = [ + "bevy_app", + "bevy_asset", + "bevy_color", + "bevy_math", + "bevy_platform", + "bevy_reflect", + "bevy_utils", + "bitflags 2.9.4", + "bytemuck", + "futures-lite", + "guillotiere", + "half", + "image", + "ktx2", + "rectangle-pack", + "ruzstd", + "serde", + "thiserror 2.0.17", + "tracing", + "wgpu-types", +] + +[[package]] +name = "bevy_input" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18d6b6516433f6f7d680f648d04eb1866bb3927a1782d52f74831b62042f3cd1" +dependencies = [ + "bevy_app", + "bevy_ecs", + "bevy_math", + "bevy_platform", + "bevy_reflect", + "bevy_utils", + "derive_more", + "log", + "smol_str", + "thiserror 2.0.17", +] + +[[package]] +name = "bevy_input_focus" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e2d079fda74d1416e0a57dac29ea2b79ff77f420cd6b87f833d3aa29a46bc4d" +dependencies = [ + "bevy_app", + "bevy_ecs", + "bevy_input", + "bevy_math", + "bevy_reflect", + "bevy_window", + "log", + "thiserror 2.0.17", +] + +[[package]] +name = "bevy_internal" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "857da8785678fde537d02944cd20dec9cafb7d4c447efe15f898dc60e733cacd" +dependencies = [ + "bevy_a11y", + "bevy_animation", + "bevy_app", + "bevy_asset", + "bevy_audio", + "bevy_color", + "bevy_core_pipeline", + "bevy_derive", + "bevy_diagnostic", + "bevy_ecs", + "bevy_gilrs", + "bevy_gizmos", + "bevy_gltf", + "bevy_image", + "bevy_input", + "bevy_input_focus", + "bevy_log", + "bevy_math", + "bevy_pbr", + "bevy_picking", + "bevy_platform", + "bevy_ptr", + "bevy_reflect", + "bevy_render", + "bevy_scene", + "bevy_sprite", + "bevy_state", + "bevy_tasks", + "bevy_text", + "bevy_time", + "bevy_transform", + "bevy_ui", + "bevy_utils", + "bevy_window", + "bevy_winit", +] + +[[package]] +name = "bevy_log" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7a61ee8aef17a974f5ca481dcedf0c2bd52670e231d4c4bc9ddef58328865f9" +dependencies = [ + "android_log-sys", + "bevy_app", + "bevy_ecs", + "bevy_utils", + "tracing", + "tracing-log", + "tracing-oslog", + "tracing-subscriber", + "tracing-wasm", +] + +[[package]] +name = "bevy_macro_utils" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "052eeebcb8e7e072beea5031b227d9a290f8a7fbbb947573ab6ec81df0fb94be" +dependencies = [ + "parking_lot", + "proc-macro2", + "quote", + "syn", + "toml_edit 0.22.27", +] + +[[package]] +name = "bevy_math" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68553e0090fe9c3ba066c65629f636bd58e4ebd9444fdba097b91af6cd3e243f" +dependencies = [ + "approx", + "bevy_reflect", + "derive_more", + "glam", + "itertools 0.14.0", + "libm", + "rand", + "rand_distr", + "serde", + "smallvec", + "thiserror 2.0.17", + "variadics_please", +] + +[[package]] +name = "bevy_mesh" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b10399c7027001edbc0406d7d0198596b1f07206c1aae715274106ba5bdcac40" +dependencies = [ + "bevy_asset", + "bevy_derive", + "bevy_ecs", + "bevy_image", + "bevy_math", + "bevy_mikktspace", + "bevy_platform", + "bevy_reflect", + "bevy_transform", + "bevy_utils", + "bitflags 2.9.4", + "bytemuck", + "hexasphere", + "serde", + "thiserror 2.0.17", + "tracing", + "wgpu-types", +] + +[[package]] +name = "bevy_mikktspace" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bb60c753b968a2de0fd279b76a3d19517695e771edb4c23575c7f92156315de" +dependencies = [ + "glam", +] + +[[package]] +name = "bevy_pbr" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5e0b4eb871f364a0d217f70f6c41d7fdc6f9f931fa1abbf222180c03d0ae410" +dependencies = [ + "bevy_app", + "bevy_asset", + "bevy_color", + "bevy_core_pipeline", + "bevy_derive", + "bevy_diagnostic", + "bevy_ecs", + "bevy_image", + "bevy_math", + "bevy_platform", + "bevy_reflect", + "bevy_render", + "bevy_transform", + "bevy_utils", + "bevy_window", + "bitflags 2.9.4", + "bytemuck", + "derive_more", + "fixedbitset", + "nonmax", + "offset-allocator", + "radsort", + "smallvec", + "static_assertions", + "thiserror 2.0.17", + "tracing", +] + +[[package]] +name = "bevy_picking" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ed04757938655ed8094ea1efb533f99063a8b22abffc22010c694d291522850" +dependencies = [ + "bevy_app", + "bevy_asset", + "bevy_derive", + "bevy_ecs", + "bevy_input", + "bevy_math", + "bevy_mesh", + "bevy_platform", + "bevy_reflect", + "bevy_render", + "bevy_time", + "bevy_transform", + "bevy_utils", + "bevy_window", + "crossbeam-channel", + "tracing", + "uuid", +] + +[[package]] +name = "bevy_platform" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7573dc824a1b08b4c93fdbe421c53e1e8188e9ca1dd74a414455fe571facb47" +dependencies = [ + "cfg-if", + "critical-section", + "foldhash", + "getrandom 0.2.16", + "hashbrown 0.15.5", + "portable-atomic", + "portable-atomic-util", + "serde", + "spin", + "web-time", +] + +[[package]] +name = "bevy_ptr" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df7370d0e46b60e071917711d0860721f5347bc958bf325975ae6913a5dfcf01" + +[[package]] +name = "bevy_reflect" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daeb91a63a1a4df00aa58da8cc4ddbd4b9f16ab8bb647c5553eb156ce36fa8c2" +dependencies = [ + "assert_type_match", + "bevy_platform", + "bevy_ptr", + "bevy_reflect_derive", + "bevy_utils", + "derive_more", + "disqualified", + "downcast-rs", + "erased-serde", + "foldhash", + "glam", + "petgraph", + "serde", + "smallvec", + "smol_str", + "thiserror 2.0.17", + "uuid", + "variadics_please", + "wgpu-types", +] + +[[package]] +name = "bevy_reflect_derive" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40ddadc55fe16b45faaa54ab2f9cb00548013c74812e8b018aa172387103cce6" +dependencies = [ + "bevy_macro_utils", + "proc-macro2", + "quote", + "syn", + "uuid", +] + +[[package]] +name = "bevy_render" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef91fed1f09405769214b99ebe4390d69c1af5cdd27967deae9135c550eb1667" +dependencies = [ + "async-channel", + "bevy_app", + "bevy_asset", + "bevy_color", + "bevy_derive", + "bevy_diagnostic", + "bevy_ecs", + "bevy_encase_derive", + "bevy_image", + "bevy_math", + "bevy_mesh", + "bevy_platform", + "bevy_reflect", + "bevy_render_macros", + "bevy_tasks", + "bevy_time", + "bevy_transform", + "bevy_utils", + "bevy_window", + "bitflags 2.9.4", + "bytemuck", + "codespan-reporting", + "derive_more", + "downcast-rs", + "encase", + "fixedbitset", + "futures-lite", + "image", + "indexmap", + "js-sys", + "ktx2", + "naga", + "naga_oil", + "nonmax", + "offset-allocator", + "send_wrapper", + "serde", + "smallvec", + "thiserror 2.0.17", + "tracing", + "variadics_please", + "wasm-bindgen", + "web-sys", + "wgpu", +] + +[[package]] +name = "bevy_render_macros" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abd42cf6c875bcf38da859f8e731e119a6aff190d41dd0a1b6000ad57cf2ed3d" +dependencies = [ + "bevy_macro_utils", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "bevy_scene" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c52ca165200995fe8afd2a1a6c03e4ffee49198a1d4653d32240ea7f217d4ab" +dependencies = [ + "bevy_app", + "bevy_asset", + "bevy_derive", + "bevy_ecs", + "bevy_platform", + "bevy_reflect", + "bevy_render", + "bevy_transform", + "bevy_utils", + "derive_more", + "serde", + "thiserror 2.0.17", + "uuid", +] + +[[package]] +name = "bevy_sprite" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ccae7bab2cb956fb0434004c359e432a3a1a074a6ef4eb471f1fb099f0b620b" +dependencies = [ + "bevy_app", + "bevy_asset", + "bevy_color", + "bevy_core_pipeline", + "bevy_derive", + "bevy_ecs", + "bevy_image", + "bevy_math", + "bevy_picking", + "bevy_platform", + "bevy_reflect", + "bevy_render", + "bevy_transform", + "bevy_utils", + "bevy_window", + "bitflags 2.9.4", + "bytemuck", + "derive_more", + "fixedbitset", + "nonmax", + "radsort", + "tracing", +] + +[[package]] +name = "bevy_state" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "155d3cd97b900539008cdcaa702f88b724d94b08977b8e591a32536ce66faa8c" +dependencies = [ + "bevy_app", + "bevy_ecs", + "bevy_platform", + "bevy_reflect", + "bevy_state_macros", + "bevy_utils", + "log", + "variadics_please", +] + +[[package]] +name = "bevy_state_macros" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2481c1304fd2a1851a0d4cb63a1ce6421ae40f3f0117cbc9882963ee4c9bb609" +dependencies = [ + "bevy_macro_utils", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "bevy_tasks" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b674242641cab680688fc3b850243b351c1af49d4f3417a576debd6cca8dcf5" +dependencies = [ + "async-channel", + "async-executor", + "async-task", + "atomic-waker", + "bevy_platform", + "cfg-if", + "concurrent-queue", + "crossbeam-queue", + "derive_more", + "futures-channel", + "futures-lite", + "heapless", + "pin-project", + "wasm-bindgen-futures", +] + +[[package]] +name = "bevy_text" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d76c85366159f5f54110f33321c76d8429cfd8f39638f26793a305dae568b60" +dependencies = [ + "bevy_app", + "bevy_asset", + "bevy_color", + "bevy_derive", + "bevy_ecs", + "bevy_image", + "bevy_log", + "bevy_math", + "bevy_platform", + "bevy_reflect", + "bevy_render", + "bevy_sprite", + "bevy_transform", + "bevy_utils", + "bevy_window", + "cosmic-text", + "serde", + "smallvec", + "sys-locale", + "thiserror 2.0.17", + "tracing", + "unicode-bidi", +] + +[[package]] +name = "bevy_time" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc98eb356c75be04fbbc77bb3d8ffa24c8bacd99f76111cee23d444be6ac8c9c" +dependencies = [ + "bevy_app", + "bevy_ecs", + "bevy_platform", + "bevy_reflect", + "crossbeam-channel", + "log", + "serde", +] + +[[package]] +name = "bevy_transform" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df218e440bb9a19058e1b80a68a031c887bcf7bd3a145b55f361359a2fa3100d" +dependencies = [ + "bevy_app", + "bevy_ecs", + "bevy_log", + "bevy_math", + "bevy_reflect", + "bevy_tasks", + "bevy_utils", + "derive_more", + "serde", + "thiserror 2.0.17", +] + +[[package]] +name = "bevy_ui" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea4a4d2ba51865bc3039af29a26b4f52c48b54cc758369f52004caf4b6f03770" +dependencies = [ + "accesskit", + "bevy_a11y", + "bevy_app", + "bevy_asset", + "bevy_color", + "bevy_core_pipeline", + "bevy_derive", + "bevy_ecs", + "bevy_image", + "bevy_input", + "bevy_math", + "bevy_picking", + "bevy_platform", + "bevy_reflect", + "bevy_render", + "bevy_sprite", + "bevy_text", + "bevy_transform", + "bevy_utils", + "bevy_window", + "bytemuck", + "derive_more", + "nonmax", + "smallvec", + "taffy", + "thiserror 2.0.17", + "tracing", +] + +[[package]] +name = "bevy_utils" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94f7a8905a125d2017e8561beefb7f2f5e67e93ff6324f072ad87c5fd6ec3b99" +dependencies = [ + "bevy_platform", + "thread_local", +] + +[[package]] +name = "bevy_window" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df7e8ad0c17c3cc23ff5566ae2905c255e6986037fb041f74c446216f5c38431" +dependencies = [ + "android-activity", + "bevy_app", + "bevy_ecs", + "bevy_input", + "bevy_math", + "bevy_platform", + "bevy_reflect", + "bevy_utils", + "log", + "raw-window-handle", + "serde", + "smol_str", +] + +[[package]] +name = "bevy_winit" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a5e7f00c6b3b6823df5ec2a5e9067273607208919bc8c211773ebb9643c87f0" +dependencies = [ + "accesskit", + "accesskit_winit", + "approx", + "bevy_a11y", + "bevy_app", + "bevy_asset", + "bevy_derive", + "bevy_ecs", + "bevy_image", + "bevy_input", + "bevy_input_focus", + "bevy_log", + "bevy_math", + "bevy_platform", + "bevy_reflect", + "bevy_tasks", + "bevy_utils", + "bevy_window", + "bytemuck", + "cfg-if", + "crossbeam-channel", + "raw-window-handle", + "tracing", + "wasm-bindgen", + "web-sys", + "wgpu-types", + "winit", +] + +[[package]] +name = "bindgen" +version = "0.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f49d8fed880d473ea71efb9bf597651e77201bdd4893efe54c9e5d65ae04ce6f" +dependencies = [ + "bitflags 2.9.4", + "cexpr", + "clang-sys", + "itertools 0.13.0", + "log", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash 1.1.0", + "shlex", + "syn", +] + +[[package]] +name = "bindgen" +version = "0.72.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895" +dependencies = [ + "bitflags 2.9.4", + "cexpr", + "clang-sys", + "itertools 0.13.0", + "proc-macro2", + "quote", + "regex", + "rustc-hash 2.1.1", + "shlex", + "syn", +] + +[[package]] +name = "bit-set" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +dependencies = [ + "bit-vec 0.6.3", +] + +[[package]] +name = "bit-set" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" +dependencies = [ + "bit-vec 0.8.0", +] + +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" + +[[package]] +name = "bit-vec" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394" +dependencies = [ + "serde", +] + +[[package]] +name = "blake3" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3888aaa89e4b2a40fca9848e400f6a658a5a3978de7be858e209cafa8be9a4a0" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq", +] + +[[package]] +name = "block" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" + +[[package]] +name = "block2" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f" +dependencies = [ + "objc2", +] + +[[package]] +name = "blocking" +version = "1.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e83f8d02be6967315521be875afa792a316e28d57b5a2d401897e2a7921b7f21" +dependencies = [ + "async-channel", + "async-task", + "futures-io", + "futures-lite", + "piper", +] + +[[package]] +name = "bumpalo" +version = "3.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" + +[[package]] +name = "bytemuck" +version = "1.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fbdf580320f38b612e485521afda1ee26d10cc9884efaaa750d383e13e3c5f4" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9abbd1bc6865053c427f7198e6af43bfdedc55ab791faed4fbd361d789575ff" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "byteorder-lite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" + +[[package]] +name = "bytes" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" + +[[package]] +name = "calloop" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b99da2f8558ca23c71f4fd15dc57c906239752dd27ff3c00a1d56b685b7cbfec" +dependencies = [ + "bitflags 2.9.4", + "log", + "polling", + "rustix 0.38.44", + "slab", + "thiserror 1.0.69", +] + +[[package]] +name = "cbindgen" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "975982cdb7ad6a142be15bdf84aea7ec6a9e5d4d797c004d43185b24cfe4e684" +dependencies = [ + "clap", + "heck", + "indexmap", + "log", + "proc-macro2", + "quote", + "serde", + "serde_json", + "syn", + "tempfile", + "toml", +] + +[[package]] +name = "cc" +version = "1.2.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac9fe6cdbb24b6ade63616c0a0688e45bb56732262c158df3c0c4bea4ca47cb7" +dependencies = [ + "find-msvc-tools", + "jobserver", + "libc", + "shlex", +] + +[[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + +[[package]] +name = "cfg-if" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" + +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + +[[package]] +name = "clang-sys" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "clap" +version = "4.5.49" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4512b90fa68d3a9932cea5184017c5d200f5921df706d45e853537dea51508f" +dependencies = [ + "clap_builder", +] + +[[package]] +name = "clap_builder" +version = "4.5.49" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0025e98baa12e766c67ba13ff4695a887a1eba19569aad00a472546795bd6730" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_lex" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" + +[[package]] +name = "codespan-reporting" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "termcolor", + "unicode-width", +] + +[[package]] +name = "colorchoice" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" + +[[package]] +name = "combine" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" +dependencies = [ + "bytes", + "memchr", +] + +[[package]] +name = "concurrent-queue" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils", + "portable-atomic", +] + +[[package]] +name = "console_error_panic_hook" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +dependencies = [ + "cfg-if", + "wasm-bindgen", +] + +[[package]] +name = "const-fnv1a-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32b13ea120a812beba79e34316b3942a857c86ec1593cb34f27bb28272ce2cca" + +[[package]] +name = "const_panic" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e262cdaac42494e3ae34c43969f9cdeb7da178bdb4b66fa6a1ea2edb4c8ae652" +dependencies = [ + "typewit", +] + +[[package]] +name = "const_soft_float" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ca1caa64ef4ed453e68bb3db612e51cf1b2f5b871337f0fcab1c8f87cc3dff" + +[[package]] +name = "constant_time_eq" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" + +[[package]] +name = "constgebra" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1aaf9b65849a68662ac6c0810c8893a765c960b907dd7cfab9c4a50bf764fbc" +dependencies = [ + "const_soft_float", +] + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "core-graphics" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c07782be35f9e1140080c6b96f0d44b739e2278479f64e02fdab4e32dfd8b081" +dependencies = [ + "bitflags 1.3.2", + "core-foundation 0.9.4", + "core-graphics-types", + "foreign-types", + "libc", +] + +[[package]] +name = "core-graphics-types" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" +dependencies = [ + "bitflags 1.3.2", + "core-foundation 0.9.4", + "libc", +] + +[[package]] +name = "coreaudio-rs" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "321077172d79c662f64f5071a03120748d5bb652f5231570141be24cfcd2bace" +dependencies = [ + "bitflags 1.3.2", + "core-foundation-sys", + "coreaudio-sys", +] + +[[package]] +name = "coreaudio-sys" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ceec7a6067e62d6f931a2baf6f3a751f4a892595bcec1461a3c94ef9949864b6" +dependencies = [ + "bindgen 0.72.1", +] + +[[package]] +name = "cosmic-text" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e418dd4f5128c3e93eab12246391c54a20c496811131f85754dc8152ee207892" +dependencies = [ + "bitflags 2.9.4", + "fontdb", + "log", + "rangemap", + "rustc-hash 1.1.0", + "rustybuzz", + "self_cell", + "smol_str", + "swash", + "sys-locale", + "ttf-parser 0.21.1", + "unicode-bidi", + "unicode-linebreak", + "unicode-script", + "unicode-segmentation", +] + +[[package]] +name = "cpal" +version = "0.15.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "873dab07c8f743075e57f524c583985fbaf745602acbe916a01539364369a779" +dependencies = [ + "alsa", + "core-foundation-sys", + "coreaudio-rs", + "dasp_sample", + "jni", + "js-sys", + "libc", + "mach2", + "ndk 0.8.0", + "ndk-context", + "oboe", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "windows 0.54.0", +] + +[[package]] +name = "crc32fast" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "critical-section" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" + +[[package]] +name = "crossbeam-channel" +version = "0.5.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-queue" +version = "0.3.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[package]] +name = "crunchy" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" + +[[package]] +name = "ctrlc" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "881c5d0a13b2f1498e2306e82cbada78390e152d4b1378fb28a84f4dcd0dc4f3" +dependencies = [ + "dispatch", + "nix", + "windows-sys 0.61.2", +] + +[[package]] +name = "cursor-icon" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f27ae1dd37df86211c42e150270f82743308803d90a6f6e6651cd730d5e1732f" + +[[package]] +name = "dasp_sample" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c87e182de0887fd5361989c677c4e8f5000cd9491d6d563161a8f3a5519fc7f" + +[[package]] +name = "data-encoding" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" + +[[package]] +name = "derive_more" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05" +dependencies = [ + "derive_more-impl", +] + +[[package]] +name = "derive_more-impl" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "unicode-xid", +] + +[[package]] +name = "dispatch" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" + +[[package]] +name = "disqualified" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9c272297e804878a2a4b707cfcfc6d2328b5bb936944613b4fdf2b9269afdfd" + +[[package]] +name = "dlib" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412" +dependencies = [ + "libloading", +] + +[[package]] +name = "document-features" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95249b50c6c185bee49034bcb378a49dc2b5dff0be90ff6616d31d64febab05d" +dependencies = [ + "litrs", +] + +[[package]] +name = "downcast-rs" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "117240f60069e65410b3ae1bb213295bd828f707b5bec6596a1afc8793ce0cbc" + +[[package]] +name = "dpi" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8b14ccef22fc6f5a8f4d7d768562a182c04ce9a3b3157b91390b52ddfdf1a76" + +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" + +[[package]] +name = "encase" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0a05902cf601ed11d564128448097b98ebe3c6574bd7b6a653a3d56d54aa020" +dependencies = [ + "const_panic", + "encase_derive", + "glam", + "thiserror 1.0.69", +] + +[[package]] +name = "encase_derive" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "181d475b694e2dd56ae919ce7699d344d1fd259292d590c723a50d1189a2ea85" +dependencies = [ + "encase_derive_impl", +] + +[[package]] +name = "encase_derive_impl" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f97b51c5cc57ef7c5f7a0c57c250251c49ee4c28f819f87ac32f4aceabc36792" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "erased-serde" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "259d404d09818dec19332e31d94558aeb442fea04c817006456c24b5460bbd4b" +dependencies = [ + "serde", + "serde_core", + "typeid", +] + +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + +[[package]] +name = "euclid" +version = "0.22.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad9cdb4b747e485a12abb0e6566612956c7a1bafa3bdb8d682c5b6d403589e48" +dependencies = [ + "num-traits", +] + +[[package]] +name = "event-listener" +version = "5.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" +dependencies = [ + "event-listener", + "pin-project-lite", +] + +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + +[[package]] +name = "fdeflate" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "ffi" +version = "0.1.0" +dependencies = [ + "cbindgen", + "renderer", +] + +[[package]] +name = "find-msvc-tools" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52051878f80a721bb68ebfbc930e07b65ba72f2da88968ea5c06fd6ca3d3a127" + +[[package]] +name = "fixedbitset" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" + +[[package]] +name = "flate2" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc5a4e564e38c699f2880d3fda590bedc2e69f3f84cd48b457bd892ce61d0aa9" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + +[[package]] +name = "font-types" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "511e2c18a516c666d27867d2f9821f76e7d591f762e9fc41dd6cc5c90fe54b0b" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "fontconfig-parser" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbc773e24e02d4ddd8395fd30dc147524273a83e54e0f312d986ea30de5f5646" +dependencies = [ + "roxmltree", +] + +[[package]] +name = "fontdb" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0299020c3ef3f60f526a4f64ab4a3d4ce116b1acbf24cdd22da0068e5d81dc3" +dependencies = [ + "fontconfig-parser", + "log", + "memmap2", + "slotmap", + "tinyvec", + "ttf-parser 0.20.0", +] + +[[package]] +name = "foreign-types" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" +dependencies = [ + "foreign-types-macros", + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-macros" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "foreign-types-shared" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" + +[[package]] +name = "futures-channel" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-io" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + +[[package]] +name = "futures-lite" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f78e10609fe0e0b3f4157ffab1876319b5b0db102a2c60dc4626306dc46b44ad" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "parking", + "pin-project-lite", +] + +[[package]] +name = "gethostname" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bd49230192a3797a9a4d6abe9b3eed6f7fa4c8a8a4947977c6f80025f92cbd8" +dependencies = [ + "rustix 1.1.2", + "windows-link", +] + +[[package]] +name = "getrandom" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasip2", +] + +[[package]] +name = "gilrs" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbb2c998745a3c1ac90f64f4f7b3a54219fd3612d7705e7798212935641ed18f" +dependencies = [ + "fnv", + "gilrs-core", + "log", + "uuid", + "vec_map", +] + +[[package]] +name = "gilrs-core" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be11a71ac3564f6965839e2ed275bf4fcf5ce16d80d396e1dfdb7b2d80bd587e" +dependencies = [ + "core-foundation 0.10.1", + "inotify", + "io-kit-sys", + "js-sys", + "libc", + "libudev-sys", + "log", + "nix", + "uuid", + "vec_map", + "wasm-bindgen", + "web-sys", + "windows 0.62.2", +] + +[[package]] +name = "gl_generator" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a95dfc23a2b4a9a2f5ab41d194f8bfda3cabec42af4e39f08c339eb2a0c124d" +dependencies = [ + "khronos_api", + "log", + "xml-rs", +] + +[[package]] +name = "glam" +version = "0.29.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8babf46d4c1c9d92deac9f7be466f76dfc4482b6452fc5024b5e8daf6ffeb3ee" +dependencies = [ + "bytemuck", + "libm", + "rand", + "serde", +] + +[[package]] +name = "glob" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" + +[[package]] +name = "glow" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5e5ea60d70410161c8bf5da3fdfeaa1c72ed2c15f8bbb9d19fe3a4fad085f08" +dependencies = [ + "js-sys", + "slotmap", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gltf" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3ce1918195723ce6ac74e80542c5a96a40c2b26162c1957a5cd70799b8cacf7" +dependencies = [ + "byteorder", + "gltf-json", + "lazy_static", + "serde_json", +] + +[[package]] +name = "gltf-derive" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14070e711538afba5d6c807edb74bcb84e5dbb9211a3bf5dea0dfab5b24f4c51" +dependencies = [ + "inflections", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "gltf-json" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6176f9d60a7eab0a877e8e96548605dedbde9190a7ae1e80bbcc1c9af03ab14" +dependencies = [ + "gltf-derive", + "serde", + "serde_derive", + "serde_json", +] + +[[package]] +name = "glutin_wgl_sys" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c4ee00b289aba7a9e5306d57c2d05499b2e5dc427f84ac708bd2c090212cf3e" +dependencies = [ + "gl_generator", +] + +[[package]] +name = "gpu-alloc" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbcd2dba93594b227a1f57ee09b8b9da8892c34d55aa332e034a228d0fe6a171" +dependencies = [ + "bitflags 2.9.4", + "gpu-alloc-types", +] + +[[package]] +name = "gpu-alloc-types" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98ff03b468aa837d70984d55f5d3f846f6ec31fe34bbb97c4f85219caeee1ca4" +dependencies = [ + "bitflags 2.9.4", +] + +[[package]] +name = "gpu-allocator" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c151a2a5ef800297b4e79efa4f4bec035c5f51d5ae587287c9b952bdf734cacd" +dependencies = [ + "log", + "presser", + "thiserror 1.0.69", + "windows 0.58.0", +] + +[[package]] +name = "gpu-descriptor" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b89c83349105e3732062a895becfc71a8f921bb71ecbbdd8ff99263e3b53a0ca" +dependencies = [ + "bitflags 2.9.4", + "gpu-descriptor-types", + "hashbrown 0.15.5", +] + +[[package]] +name = "gpu-descriptor-types" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdf242682df893b86f33a73828fb09ca4b2d3bb6cc95249707fc684d27484b91" +dependencies = [ + "bitflags 2.9.4", +] + +[[package]] +name = "grid" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36119f3a540b086b4e436bb2b588cf98a68863470e0e880f4d0842f112a3183a" + +[[package]] +name = "guillotiere" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b62d5865c036cb1393e23c50693df631d3f5d7bcca4c04fe4cc0fd592e74a782" +dependencies = [ + "euclid", + "svg_fmt", +] + +[[package]] +name = "half" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" +dependencies = [ + "cfg-if", + "crunchy", + "zerocopy", +] + +[[package]] +name = "hash32" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606" +dependencies = [ + "byteorder", +] + +[[package]] +name = "hashbrown" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +dependencies = [ + "equivalent", + "foldhash", + "serde", +] + +[[package]] +name = "hashbrown" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" + +[[package]] +name = "heapless" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad" +dependencies = [ + "hash32", + "portable-atomic", + "stable_deref_trait", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hermit-abi" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" + +[[package]] +name = "hexasphere" +version = "15.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c9e718d32b6e6b2b32354e1b0367025efdd0b11d6a740b905ddf5db1074679" +dependencies = [ + "constgebra", + "glam", + "tinyvec", +] + +[[package]] +name = "hexf-parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" + +[[package]] +name = "image" +version = "0.25.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "529feb3e6769d234375c4cf1ee2ce713682b8e76538cb13f9fc23e1400a591e7" +dependencies = [ + "bytemuck", + "byteorder-lite", + "moxcms", + "num-traits", + "png", +] + +[[package]] +name = "immutable-chunkmap" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3e98b1520e49e252237edc238a39869da9f3241f2ec19dc788c1d24694d1e4" +dependencies = [ + "arrayvec", +] + +[[package]] +name = "indexmap" +version = "2.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5" +dependencies = [ + "equivalent", + "hashbrown 0.16.0", + "serde", + "serde_core", +] + +[[package]] +name = "inflections" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a257582fdcde896fd96463bf2d40eefea0580021c0712a0e2b028b60b47a837a" + +[[package]] +name = "inotify" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f37dccff2791ab604f9babef0ba14fbe0be30bd368dc541e2b08d07c8aa908f3" +dependencies = [ + "bitflags 2.9.4", + "inotify-sys", + "libc", +] + +[[package]] +name = "inotify-sys" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb" +dependencies = [ + "libc", +] + +[[package]] +name = "io-kit-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "617ee6cf8e3f66f3b4ea67a4058564628cde41901316e19f559e14c7c72c5e7b" +dependencies = [ + "core-foundation-sys", + "mach2", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" + +[[package]] +name = "jni" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" +dependencies = [ + "cesu8", + "cfg-if", + "combine", + "jni-sys", + "log", + "thiserror 1.0.69", + "walkdir", + "windows-sys 0.45.0", +] + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + +[[package]] +name = "jobserver" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" +dependencies = [ + "getrandom 0.3.4", + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec48937a97411dcb524a265206ccd4c90bb711fca92b2792c407f268825b9305" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "khronos-egl" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6aae1df220ece3c0ada96b8153459b67eebe9ae9212258bb0134ae60416fdf76" +dependencies = [ + "libc", + "libloading", + "pkg-config", +] + +[[package]] +name = "khronos_api" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" + +[[package]] +name = "ktx2" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87d65e08a9ec02e409d27a0139eaa6b9756b4d81fe7cde71f6941a83730ce838" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "lewton" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "777b48df9aaab155475a83a7df3070395ea1ac6902f5cd062b8f2b028075c030" +dependencies = [ + "byteorder", + "ogg", + "tinyvec", +] + +[[package]] +name = "libc" +version = "0.2.177" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" + +[[package]] +name = "libloading" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" +dependencies = [ + "cfg-if", + "windows-link", +] + +[[package]] +name = "libm" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" + +[[package]] +name = "libredox" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb" +dependencies = [ + "bitflags 2.9.4", + "libc", + "redox_syscall 0.5.18", +] + +[[package]] +name = "libudev-sys" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c8469b4a23b962c1396b9b451dda50ef5b283e8dd309d69033475fa9b334324" +dependencies = [ + "libc", + "pkg-config", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" + +[[package]] +name = "linux-raw-sys" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" + +[[package]] +name = "litrs" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5e54036fe321fd421e10d732f155734c4e4afd610dd556d9a82833ab3ee0bed" + +[[package]] +name = "lock_api" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" + +[[package]] +name = "mach2" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d640282b302c0bb0a2a8e0233ead9035e3bed871f0b7e81fe4a1ec829765db44" +dependencies = [ + "libc", +] + +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + +[[package]] +name = "matchers" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" +dependencies = [ + "regex-automata", +] + +[[package]] +name = "memchr" +version = "2.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" + +[[package]] +name = "memmap2" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843a98750cd611cc2965a8213b53b43e715f13c37a9e096c6408e69990961db7" +dependencies = [ + "libc", +] + +[[package]] +name = "metal" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f569fb946490b5743ad69813cb19629130ce9374034abe31614a36402d18f99e" +dependencies = [ + "bitflags 2.9.4", + "block", + "core-graphics-types", + "foreign-types", + "log", + "objc", + "paste", +] + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", + "simd-adler32", +] + +[[package]] +name = "moxcms" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c588e11a3082784af229e23e8e4ecf5bcc6fbe4f69101e0421ce8d79da7f0b40" +dependencies = [ + "num-traits", + "pxfm", +] + +[[package]] +name = "naga" +version = "24.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e380993072e52eef724eddfcde0ed013b0c023c3f0417336ed041aa9f076994e" +dependencies = [ + "arrayvec", + "bit-set 0.8.0", + "bitflags 2.9.4", + "cfg_aliases", + "codespan-reporting", + "hexf-parse", + "indexmap", + "log", + "pp-rs", + "rustc-hash 1.1.0", + "spirv", + "strum", + "termcolor", + "thiserror 2.0.17", + "unicode-xid", +] + +[[package]] +name = "naga_oil" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2464f7395decfd16bb4c33fb0cb3b2c645cc60d051bc7fb652d3720bfb20f18" +dependencies = [ + "bit-set 0.5.3", + "codespan-reporting", + "data-encoding", + "indexmap", + "naga", + "once_cell", + "regex", + "regex-syntax", + "rustc-hash 1.1.0", + "thiserror 1.0.69", + "tracing", + "unicode-ident", +] + +[[package]] +name = "ndk" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2076a31b7010b17a38c01907c45b945e8f11495ee4dd588309718901b1f7a5b7" +dependencies = [ + "bitflags 2.9.4", + "jni-sys", + "log", + "ndk-sys 0.5.0+25.2.9519653", + "num_enum", + "thiserror 1.0.69", +] + +[[package]] +name = "ndk" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" +dependencies = [ + "bitflags 2.9.4", + "jni-sys", + "log", + "ndk-sys 0.6.0+11769913", + "num_enum", + "raw-window-handle", + "thiserror 1.0.69", +] + +[[package]] +name = "ndk-context" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" + +[[package]] +name = "ndk-sys" +version = "0.5.0+25.2.9519653" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c196769dd60fd4f363e11d948139556a344e79d451aeb2fa2fd040738ef7691" +dependencies = [ + "jni-sys", +] + +[[package]] +name = "ndk-sys" +version = "0.6.0+11769913" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee6cda3051665f1fb8d9e08fc35c96d5a244fb1be711a03b71118828afc9a873" +dependencies = [ + "jni-sys", +] + +[[package]] +name = "nix" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" +dependencies = [ + "bitflags 2.9.4", + "cfg-if", + "cfg_aliases", + "libc", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "nonmax" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "610a5acd306ec67f907abe5567859a3c693fb9886eb1f012ab8f2a47bef3db51" + +[[package]] +name = "ntapi" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4" +dependencies = [ + "winapi", +] + +[[package]] +name = "nu-ansi-term" +version = "0.50.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "num-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "num_enum" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a973b4e44ce6cad84ce69d797acf9a044532e4184c4f267913d1b546a0727b7a" +dependencies = [ + "num_enum_derive", + "rustversion", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77e878c846a8abae00dd069496dbe8751b16ac1c3d6bd2a7283a938e8228f90d" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "objc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +dependencies = [ + "malloc_buf", +] + +[[package]] +name = "objc-sys" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310" + +[[package]] +name = "objc2" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46a785d4eeff09c14c487497c162e92766fbb3e4059a71840cecc03d9a50b804" +dependencies = [ + "objc-sys", + "objc2-encode", +] + +[[package]] +name = "objc2-app-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" +dependencies = [ + "bitflags 2.9.4", + "block2", + "libc", + "objc2", + "objc2-core-data", + "objc2-core-image", + "objc2-foundation", + "objc2-quartz-core", +] + +[[package]] +name = "objc2-cloud-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009" +dependencies = [ + "bitflags 2.9.4", + "block2", + "objc2", + "objc2-core-location", + "objc2-foundation", +] + +[[package]] +name = "objc2-contacts" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5ff520e9c33812fd374d8deecef01d4a840e7b41862d849513de77e44aa4889" +dependencies = [ + "block2", + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-core-data" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" +dependencies = [ + "bitflags 2.9.4", + "block2", + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-core-foundation" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" +dependencies = [ + "bitflags 2.9.4", +] + +[[package]] +name = "objc2-core-image" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80" +dependencies = [ + "block2", + "objc2", + "objc2-foundation", + "objc2-metal", +] + +[[package]] +name = "objc2-core-location" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "000cfee34e683244f284252ee206a27953279d370e309649dc3ee317b37e5781" +dependencies = [ + "block2", + "objc2", + "objc2-contacts", + "objc2-foundation", +] + +[[package]] +name = "objc2-encode" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" + +[[package]] +name = "objc2-foundation" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" +dependencies = [ + "bitflags 2.9.4", + "block2", + "dispatch", + "libc", + "objc2", +] + +[[package]] +name = "objc2-link-presentation" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1a1ae721c5e35be65f01a03b6d2ac13a54cb4fa70d8a5da293d7b0020261398" +dependencies = [ + "block2", + "objc2", + "objc2-app-kit", + "objc2-foundation", +] + +[[package]] +name = "objc2-metal" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" +dependencies = [ + "bitflags 2.9.4", + "block2", + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-quartz-core" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" +dependencies = [ + "bitflags 2.9.4", + "block2", + "objc2", + "objc2-foundation", + "objc2-metal", +] + +[[package]] +name = "objc2-symbols" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a684efe3dec1b305badae1a28f6555f6ddd3bb2c2267896782858d5a78404dc" +dependencies = [ + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-ui-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f" +dependencies = [ + "bitflags 2.9.4", + "block2", + "objc2", + "objc2-cloud-kit", + "objc2-core-data", + "objc2-core-image", + "objc2-core-location", + "objc2-foundation", + "objc2-link-presentation", + "objc2-quartz-core", + "objc2-symbols", + "objc2-uniform-type-identifiers", + "objc2-user-notifications", +] + +[[package]] +name = "objc2-uniform-type-identifiers" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44fa5f9748dbfe1ca6c0b79ad20725a11eca7c2218bceb4b005cb1be26273bfe" +dependencies = [ + "block2", + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-user-notifications" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3" +dependencies = [ + "bitflags 2.9.4", + "block2", + "objc2", + "objc2-core-location", + "objc2-foundation", +] + +[[package]] +name = "oboe" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8b61bebd49e5d43f5f8cc7ee2891c16e0f41ec7954d36bcb6c14c5e0de867fb" +dependencies = [ + "jni", + "ndk 0.8.0", + "ndk-context", + "num-derive", + "num-traits", + "oboe-sys", +] + +[[package]] +name = "oboe-sys" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8bb09a4a2b1d668170cfe0a7d5bc103f8999fb316c98099b6a9939c9f2e79d" +dependencies = [ + "cc", +] + +[[package]] +name = "offset-allocator" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e234d535da3521eb95106f40f0b73483d80bfb3aacf27c40d7e2b72f1a3e00a2" +dependencies = [ + "log", + "nonmax", +] + +[[package]] +name = "ogg" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6951b4e8bf21c8193da321bcce9c9dd2e13c858fe078bf9054a288b419ae5d6e" +dependencies = [ + "byteorder", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "once_cell_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" + +[[package]] +name = "orbclient" +version = "0.3.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba0b26cec2e24f08ed8bb31519a9333140a6599b867dac464bb150bdb796fd43" +dependencies = [ + "libredox", +] + +[[package]] +name = "ordered-float" +version = "4.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bb71e1b3fa6ca1c61f383464aaf2bb0e2f8e772a1f01d486832464de363b951" +dependencies = [ + "num-traits", +] + +[[package]] +name = "parking" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" + +[[package]] +name = "parking_lot" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.5.18", + "smallvec", + "windows-link", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "percent-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + +[[package]] +name = "petgraph" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3672b37090dbd86368a4145bc067582552b29c27377cad4e0a306c97f9bd7772" +dependencies = [ + "fixedbitset", + "indexmap", + "serde", + "serde_derive", +] + +[[package]] +name = "pin-project" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + +[[package]] +name = "piper" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" +dependencies = [ + "atomic-waker", + "fastrand", + "futures-io", +] + +[[package]] +name = "pkg-config" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" + +[[package]] +name = "png" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97baced388464909d42d89643fe4361939af9b7ce7a31ee32a168f832a70f2a0" +dependencies = [ + "bitflags 2.9.4", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide", +] + +[[package]] +name = "polling" +version = "3.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0e4f59085d47d8241c88ead0f274e8a0cb551f3625263c05eb8dd897c34218" +dependencies = [ + "cfg-if", + "concurrent-queue", + "hermit-abi", + "pin-project-lite", + "rustix 1.1.2", + "windows-sys 0.61.2", +] + +[[package]] +name = "portable-atomic" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" + +[[package]] +name = "portable-atomic-util" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" +dependencies = [ + "portable-atomic", +] + +[[package]] +name = "pp-rs" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb458bb7f6e250e6eb79d5026badc10a3ebb8f9a15d1fff0f13d17c71f4d6dee" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "presser" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8cf8e6a8aa66ce33f63993ffc4ea4271eb5b0530a9002db8455ea6050c77bfa" + +[[package]] +name = "prettyplease" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" +dependencies = [ + "proc-macro2", + "syn", +] + +[[package]] +name = "proc-macro-crate" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" +dependencies = [ + "toml_edit 0.23.7", +] + +[[package]] +name = "proc-macro2" +version = "1.0.101" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "profiling" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3eb8486b569e12e2c32ad3e204dbaba5e4b5b216e9367044f25f1dba42341773" + +[[package]] +name = "pxfm" +version = "0.1.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3cbdf373972bf78df4d3b518d07003938e2c7d1fb5891e55f9cb6df57009d84" +dependencies = [ + "num-traits", +] + +[[package]] +name = "quote" +version = "1.0.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "radsort" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "019b4b213425016d7d84a153c4c73afb0946fbb4840e4eece7ba8848b9d6da22" + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.16", +] + +[[package]] +name = "rand_distr" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31" +dependencies = [ + "num-traits", + "rand", +] + +[[package]] +name = "range-alloc" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d6831663a5098ea164f89cff59c6284e95f4e3c76ce9848d4529f5ccca9bde" + +[[package]] +name = "rangemap" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f93e7e49bb0bf967717f7bd674458b3d6b0c5f48ec7e3038166026a69fc22223" + +[[package]] +name = "raw-window-handle" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" + +[[package]] +name = "read-fonts" +version = "0.35.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6717cf23b488adf64b9d711329542ba34de147df262370221940dfabc2c91358" +dependencies = [ + "bytemuck", + "font-types", +] + +[[package]] +name = "rectangle-pack" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0d463f2884048e7153449a55166f91028d5b0ea53c79377099ce4e8cf0cf9bb" + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_syscall" +version = "0.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +dependencies = [ + "bitflags 2.9.4", +] + +[[package]] +name = "regex" +version = "1.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" + +[[package]] +name = "renderdoc-sys" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832" + +[[package]] +name = "renderer" +version = "0.1.0" +dependencies = [ + "bevy", + "thiserror 2.0.17", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "rodio" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ceb6607dd738c99bc8cb28eff249b7cd5c8ec88b9db96c0608c1480d140fb1" +dependencies = [ + "cpal", + "lewton", +] + +[[package]] +name = "ron" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94" +dependencies = [ + "base64 0.21.7", + "bitflags 2.9.4", + "serde", + "serde_derive", +] + +[[package]] +name = "roxmltree" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c20b6793b5c2fa6553b250154b78d6d0db37e72700ae35fad9387a46f487c97" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc-hash" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" + +[[package]] +name = "rustix" +version = "0.38.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" +dependencies = [ + "bitflags 2.9.4", + "errno", + "libc", + "linux-raw-sys 0.4.15", + "windows-sys 0.59.0", +] + +[[package]] +name = "rustix" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" +dependencies = [ + "bitflags 2.9.4", + "errno", + "libc", + "linux-raw-sys 0.11.0", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + +[[package]] +name = "rustybuzz" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfb9cf8877777222e4a3bc7eb247e398b56baba500c38c1c46842431adc8b55c" +dependencies = [ + "bitflags 2.9.4", + "bytemuck", + "libm", + "smallvec", + "ttf-parser 0.21.1", + "unicode-bidi-mirroring", + "unicode-ccc", + "unicode-properties", + "unicode-script", +] + +[[package]] +name = "ruzstd" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3640bec8aad418d7d03c72ea2de10d5c646a598f9883c7babc160d91e3c1b26c" +dependencies = [ + "twox-hash", +] + +[[package]] +name = "ryu" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "self_cell" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f7d95a54511e0c7be3f51e8867aa8cf35148d7b9445d44de2f943e2b206e749" + +[[package]] +name = "send_wrapper" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.145" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", + "serde_core", +] + +[[package]] +name = "serde_spanned" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" +dependencies = [ + "serde", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "simd-adler32" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" + +[[package]] +name = "skrifa" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c31071dedf532758ecf3fed987cdb4bd9509f900e026ab684b4ecb81ea49841" +dependencies = [ + "bytemuck", + "read-fonts", +] + +[[package]] +name = "slab" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" + +[[package]] +name = "slotmap" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbff4acf519f630b3a3ddcfaea6c06b42174d9a44bc70c620e9ed1649d58b82a" +dependencies = [ + "version_check", +] + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + +[[package]] +name = "smol_str" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd538fb6910ac1099850255cf94a94df6551fbdd602454387d0adb2d1ca6dead" +dependencies = [ + "serde", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "portable-atomic", +] + +[[package]] +name = "spirv" +version = "0.3.0+sdk-1.3.268.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eda41003dc44290527a59b13432d4a0379379fa074b70174882adfbdfd917844" +dependencies = [ + "bitflags 2.9.4", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" + +[[package]] +name = "stackfuture" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6eae92052b72ef70dafa16eddbabffc77e5ca3574be2f7bc1127b36f0a7ad7f2" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "strum" +version = "0.26.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn", +] + +[[package]] +name = "svg_fmt" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0193cc4331cfd2f3d2011ef287590868599a2f33c3e69bc22c1a3d3acf9e02fb" + +[[package]] +name = "swash" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47846491253e976bdd07d0f9cc24b7daf24720d11309302ccbbc6e6b6e53550a" +dependencies = [ + "skrifa", + "yazi", + "zeno", +] + +[[package]] +name = "syn" +version = "2.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sys-locale" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eab9a99a024a169fe8a903cf9d4a3b3601109bcc13bd9e3c6fff259138626c4" +dependencies = [ + "libc", +] + +[[package]] +name = "sysinfo" +version = "0.34.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4b93974b3d3aeaa036504b8eefd4c039dced109171c1ae973f1dc63b2c7e4b2" +dependencies = [ + "libc", + "memchr", + "ntapi", + "objc2-core-foundation", + "windows 0.57.0", +] + +[[package]] +name = "taffy" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab4f4d046dd956a47a7e1a2947083d7ac3e6aa3cfaaead36173ceaa5ab11878c" +dependencies = [ + "arrayvec", + "grid", + "serde", + "slotmap", +] + +[[package]] +name = "tempfile" +version = "3.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" +dependencies = [ + "fastrand", + "getrandom 0.3.4", + "once_cell", + "rustix 1.1.2", + "windows-sys 0.61.2", +] + +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" +dependencies = [ + "thiserror-impl 2.0.17", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "thread_local" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "tinyvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "toml" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime 0.6.11", + "toml_edit 0.22.27", +] + +[[package]] +name = "toml_datetime" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_datetime" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2cdb639ebbc97961c51720f858597f7f24c4fc295327923af55b74c3c724533" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_edit" +version = "0.22.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime 0.6.11", + "toml_write", + "winnow", +] + +[[package]] +name = "toml_edit" +version = "0.23.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6485ef6d0d9b5d0ec17244ff7eb05310113c3f316f2d14200d4de56b3cb98f8d" +dependencies = [ + "indexmap", + "toml_datetime 0.7.3", + "toml_parser", + "winnow", +] + +[[package]] +name = "toml_parser" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0cbe268d35bdb4bb5a56a2de88d0ad0eb70af5384a99d648cd4b3d04039800e" +dependencies = [ + "winnow", +] + +[[package]] +name = "toml_write" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" + +[[package]] +name = "tracing" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" +dependencies = [ + "once_cell", + "valuable", +] + [[package]] -name = "rustix" -version = "1.1.2" +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-oslog" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "528bdd1f0e27b5dd9a4ededf154e824b0532731e4af73bb531de46276e0aab1e" +dependencies = [ + "bindgen 0.70.1", + "cc", + "cfg-if", + "once_cell", + "parking_lot", + "tracing-core", + "tracing-subscriber", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex-automata", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "tracing-wasm" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4575c663a174420fa2d78f4108ff68f65bf2fbb7dd89f33749b6e826b3626e07" +dependencies = [ + "tracing", + "tracing-subscriber", + "wasm-bindgen", +] + +[[package]] +name = "ttf-parser" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17f77d76d837a7830fe1d4f12b7b4ba4192c1888001c7164257e4bc6d21d96b4" + +[[package]] +name = "ttf-parser" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c591d83f69777866b9126b24c6dd9a18351f177e49d625920d19f989fd31cf8" + +[[package]] +name = "twox-hash" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ea3136b675547379c4bd395ca6b938e5ad3c3d20fad76e7fe85f9e0d011419c" + +[[package]] +name = "typeid" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" + +[[package]] +name = "typewit" +version = "1.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8c1ae7cc0fdb8b842d65d127cb981574b0d2b249b74d1c7a2986863dc134f71" + +[[package]] +name = "unicode-bidi" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" + +[[package]] +name = "unicode-bidi-mirroring" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23cb788ffebc92c5948d0e997106233eeb1d8b9512f93f41651f52b6c5f5af86" + +[[package]] +name = "unicode-ccc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1df77b101bcc4ea3d78dafc5ad7e4f58ceffe0b2b16bf446aeb50b6cb4157656" + +[[package]] +name = "unicode-ident" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d" + +[[package]] +name = "unicode-linebreak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" + +[[package]] +name = "unicode-properties" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0" + +[[package]] +name = "unicode-script" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb421b350c9aff471779e262955939f565ec18b86c15364e6bdf0d662ca7c1f" + +[[package]] +name = "unicode-segmentation" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" + +[[package]] +name = "unicode-width" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" + +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "uuid" +version = "1.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2" +dependencies = [ + "getrandom 0.3.4", + "js-sys", + "serde", + "wasm-bindgen", +] + +[[package]] +name = "valuable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" + +[[package]] +name = "variadics_please" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41b6d82be61465f97d42bd1d15bf20f3b0a3a0905018f38f9d6f6962055b0b5c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasip2" +version = "1.0.1+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" +dependencies = [ + "wit-bindgen", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1da10c01ae9f1ae40cbfac0bac3b1e724b320abfcf52229f80b547c0d250e2d" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "671c9a5a66f49d8a47345ab942e2cb93c7d1d0339065d4f8139c486121b43b19" +dependencies = [ + "bumpalo", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e038d41e478cc73bae0ff9b36c60cff1c98b8f38f8d7e8061e79ee63608ac5c" +dependencies = [ + "cfg-if", + "js-sys", + "once_cell", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ca60477e4c59f5f2986c50191cd972e3a50d8a95603bc9434501cf156a9a119" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f07d2f20d4da7b26400c9f4a0511e6e0345b040694e8a75bd41d578fa4421d7" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bad67dc8b2a1a6e5448428adec4c3e84c43e561d8c9ee8a9e5aabeb193ec41d1" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "web-sys" +version = "0.3.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9367c417a924a74cae129e6a2ae3b47fabb1f8995595ab474029da749a8be120" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "wgpu" +version = "24.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b0b3436f0729f6cdf2e6e9201f3d39dc95813fad61d826c1ed07918b4539353" +dependencies = [ + "arrayvec", + "bitflags 2.9.4", + "cfg_aliases", + "document-features", + "js-sys", + "log", + "naga", + "parking_lot", + "profiling", + "raw-window-handle", + "smallvec", + "static_assertions", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "wgpu-core", + "wgpu-hal", + "wgpu-types", +] + +[[package]] +name = "wgpu-core" +version = "24.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f0aa306497a238d169b9dc70659105b4a096859a34894544ca81719242e1499" +dependencies = [ + "arrayvec", + "bit-vec 0.8.0", + "bitflags 2.9.4", + "cfg_aliases", + "document-features", + "indexmap", + "log", + "naga", + "once_cell", + "parking_lot", + "profiling", + "raw-window-handle", + "rustc-hash 1.1.0", + "smallvec", + "thiserror 2.0.17", + "wgpu-hal", + "wgpu-types", +] + +[[package]] +name = "wgpu-hal" +version = "24.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f112f464674ca69f3533248508ee30cb84c67cf06c25ff6800685f5e0294e259" +dependencies = [ + "android_system_properties", + "arrayvec", + "ash", + "bit-set 0.8.0", + "bitflags 2.9.4", + "block", + "bytemuck", + "cfg_aliases", + "core-graphics-types", + "glow", + "glutin_wgl_sys", + "gpu-alloc", + "gpu-allocator", + "gpu-descriptor", + "js-sys", + "khronos-egl", + "libc", + "libloading", + "log", + "metal", + "naga", + "ndk-sys 0.5.0+25.2.9519653", + "objc", + "once_cell", + "ordered-float", + "parking_lot", + "profiling", + "range-alloc", + "raw-window-handle", + "renderdoc-sys", + "rustc-hash 1.1.0", + "smallvec", + "thiserror 2.0.17", + "wasm-bindgen", + "web-sys", + "wgpu-types", + "windows 0.58.0", + "windows-core 0.58.0", +] + +[[package]] +name = "wgpu-types" +version = "24.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50ac044c0e76c03a0378e7786ac505d010a873665e2d51383dcff8dd227dc69c" +dependencies = [ + "bitflags 2.9.4", + "js-sys", + "log", + "serde", + "web-sys", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.54.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9252e5725dbed82865af151df558e754e4a3c2c30818359eb17465f1346a1b49" +dependencies = [ + "windows-core 0.54.0", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12342cb4d8e3b046f3d80effd474a7a02447231330ef77d71daa6fbc40681143" +dependencies = [ + "windows-core 0.57.0", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" +dependencies = [ + "windows-core 0.58.0", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows" +version = "0.62.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "527fadee13e0c05939a6a05d5bd6eec6cd2e3dbd648b9f8e447c6518133d8580" +dependencies = [ + "windows-collections", + "windows-core 0.62.2", + "windows-future", + "windows-numerics", +] + +[[package]] +name = "windows-collections" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b2d95af1a8a14a3c7367e1ed4fc9c20e0a26e79551b1454d72583c97cc6610" +dependencies = [ + "windows-core 0.62.2", +] + +[[package]] +name = "windows-core" +version = "0.54.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12661b9c89351d684a50a8a643ce5f608e20243b9fb84687800163429f161d65" +dependencies = [ + "windows-result 0.1.2", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-core" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2ed2439a290666cd67ecce2b0ffaad89c2a56b976b736e6ece670297897832d" +dependencies = [ + "windows-implement 0.57.0", + "windows-interface 0.57.0", + "windows-result 0.1.2", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-core" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" +checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" dependencies = [ - "bitflags", - "errno", - "libc", - "linux-raw-sys", - "windows-sys 0.61.2", + "windows-implement 0.58.0", + "windows-interface 0.58.0", + "windows-result 0.2.0", + "windows-strings 0.1.0", + "windows-targets 0.52.6", ] [[package]] -name = "ryu" -version = "1.0.20" +name = "windows-core" +version = "0.62.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" +dependencies = [ + "windows-implement 0.60.2", + "windows-interface 0.59.3", + "windows-link", + "windows-result 0.4.1", + "windows-strings 0.5.1", +] [[package]] -name = "serde" -version = "1.0.228" +name = "windows-future" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +checksum = "e1d6f90251fe18a279739e78025bd6ddc52a7e22f921070ccdc67dde84c605cb" dependencies = [ - "serde_core", - "serde_derive", + "windows-core 0.62.2", + "windows-link", + "windows-threading", ] [[package]] -name = "serde_core" -version = "1.0.228" +name = "windows-implement" +version = "0.57.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7" dependencies = [ - "serde_derive", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "serde_derive" -version = "1.0.228" +name = "windows-implement" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" dependencies = [ "proc-macro2", "quote", @@ -310,124 +4830,137 @@ dependencies = [ ] [[package]] -name = "serde_json" -version = "1.0.145" +name = "windows-implement" +version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ - "itoa", - "memchr", - "ryu", - "serde", - "serde_core", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "serde_spanned" -version = "0.6.9" +name = "windows-interface" +version = "0.57.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" +checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7" dependencies = [ - "serde", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "strsim" -version = "0.11.1" +name = "windows-interface" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] -name = "syn" -version = "2.0.106" +name = "windows-interface" +version = "0.59.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "unicode-ident", + "syn", ] [[package]] -name = "tempfile" -version = "3.23.0" +name = "windows-link" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-numerics" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e2e40844ac143cdb44aead537bbf727de9b044e107a0f1220392177d15b0f26" dependencies = [ - "fastrand", - "getrandom", - "once_cell", - "rustix", - "windows-sys 0.61.2", + "windows-core 0.62.2", + "windows-link", ] [[package]] -name = "toml" -version = "0.8.23" +name = "windows-result" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" +checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8" dependencies = [ - "serde", - "serde_spanned", - "toml_datetime", - "toml_edit", + "windows-targets 0.52.6", ] [[package]] -name = "toml_datetime" -version = "0.6.11" +name = "windows-result" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" dependencies = [ - "serde", + "windows-targets 0.52.6", ] [[package]] -name = "toml_edit" -version = "0.22.27" +name = "windows-result" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" dependencies = [ - "indexmap", - "serde", - "serde_spanned", - "toml_datetime", - "toml_write", - "winnow", + "windows-link", ] [[package]] -name = "toml_write" -version = "0.1.2" +name = "windows-strings" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result 0.2.0", + "windows-targets 0.52.6", +] [[package]] -name = "unicode-ident" -version = "1.0.19" +name = "windows-strings" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" +dependencies = [ + "windows-link", +] [[package]] -name = "utf8parse" -version = "0.2.2" +name = "windows-sys" +version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] [[package]] -name = "wasip2" -version = "1.0.1+wasi-0.2.4" +name = "windows-sys" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "wit-bindgen", + "windows-targets 0.52.6", ] [[package]] -name = "windows-link" -version = "0.2.1" +name = "windows-sys" +version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] [[package]] name = "windows-sys" @@ -435,7 +4968,7 @@ version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" dependencies = [ - "windows-targets", + "windows-targets 0.53.5", ] [[package]] @@ -447,6 +4980,37 @@ dependencies = [ "windows-link", ] +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm 0.52.6", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + [[package]] name = "windows-targets" version = "0.53.5" @@ -454,64 +5018,207 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" dependencies = [ "windows-link", - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.53.1", + "windows_aarch64_msvc 0.53.1", + "windows_i686_gnu 0.53.1", + "windows_i686_gnullvm 0.53.1", + "windows_i686_msvc 0.53.1", + "windows_x86_64_gnu 0.53.1", + "windows_x86_64_gnullvm 0.53.1", + "windows_x86_64_msvc 0.53.1", +] + +[[package]] +name = "windows-threading" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3949bd5b99cafdf1c7ca86b43ca564028dfe27d66958f2470940f73d86d75b37" +dependencies = [ + "windows-link", ] +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + [[package]] name = "windows_aarch64_gnullvm" version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + [[package]] name = "windows_aarch64_msvc" version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + [[package]] name = "windows_i686_gnu" version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + [[package]] name = "windows_i686_gnullvm" version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + [[package]] name = "windows_i686_msvc" version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + [[package]] name = "windows_x86_64_gnu" version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + [[package]] name = "windows_x86_64_gnullvm" version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + [[package]] name = "windows_x86_64_msvc" version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" +[[package]] +name = "winit" +version = "0.30.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c66d4b9ed69c4009f6321f762d6e61ad8a2389cd431b97cb1e146812e9e6c732" +dependencies = [ + "android-activity", + "atomic-waker", + "bitflags 2.9.4", + "block2", + "bytemuck", + "calloop", + "cfg_aliases", + "concurrent-queue", + "core-foundation 0.9.4", + "core-graphics", + "cursor-icon", + "dpi", + "js-sys", + "libc", + "ndk 0.9.0", + "objc2", + "objc2-app-kit", + "objc2-foundation", + "objc2-ui-kit", + "orbclient", + "percent-encoding", + "pin-project", + "raw-window-handle", + "redox_syscall 0.4.1", + "rustix 0.38.44", + "smol_str", + "tracing", + "unicode-segmentation", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "web-time", + "windows-sys 0.52.0", + "x11-dl", + "x11rb", + "xkbcommon-dl", +] + [[package]] name = "winnow" version = "0.7.13" @@ -526,3 +5233,92 @@ name = "wit-bindgen" version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" + +[[package]] +name = "x11-dl" +version = "2.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38735924fedd5314a6e548792904ed8c6de6636285cb9fec04d5b1db85c1516f" +dependencies = [ + "libc", + "once_cell", + "pkg-config", +] + +[[package]] +name = "x11rb" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9993aa5be5a26815fe2c3eacfc1fde061fc1a1f094bf1ad2a18bf9c495dd7414" +dependencies = [ + "as-raw-xcb-connection", + "gethostname", + "libc", + "libloading", + "once_cell", + "rustix 1.1.2", + "x11rb-protocol", +] + +[[package]] +name = "x11rb-protocol" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea6fc2961e4ef194dcbfe56bb845534d0dc8098940c7e5c012a258bfec6701bd" + +[[package]] +name = "xkbcommon-dl" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d039de8032a9a8856a6be89cea3e5d12fdd82306ab7c94d74e6deab2460651c5" +dependencies = [ + "bitflags 2.9.4", + "dlib", + "log", + "once_cell", + "xkeysym", +] + +[[package]] +name = "xkeysym" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9cc00251562a284751c9973bace760d86c0276c471b4be569fe6b068ee97a56" + +[[package]] +name = "xml-rs" +version = "0.8.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fd8403733700263c6eb89f192880191f1b83e332f7a20371ddcf421c4a337c7" + +[[package]] +name = "yazi" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e01738255b5a16e78bbb83e7fbba0a1e7dd506905cfc53f4622d89015a03fbb5" + +[[package]] +name = "zeno" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6df3dc4292935e51816d896edcd52aa30bc297907c26167fec31e2b0c6a32524" + +[[package]] +name = "zerocopy" +version = "0.8.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/libProcessing/Cargo.toml b/libProcessing/Cargo.toml index 614ee9fb0..6684a907f 100644 --- a/libProcessing/Cargo.toml +++ b/libProcessing/Cargo.toml @@ -1,8 +1,3 @@ -[package] -name = "libProcessing" -version = "0.1.0" -edition = "2024" - [workspace] resolver = "3" members = ["ffi","renderer"] diff --git a/libProcessing/ffi/src/error.rs b/libProcessing/ffi/src/error.rs new file mode 100644 index 000000000..0de41a3a2 --- /dev/null +++ b/libProcessing/ffi/src/error.rs @@ -0,0 +1,49 @@ +use std::cell::RefCell; +use std::ffi::{c_char, CString}; +use renderer::error::ProcessingError; + +thread_local! { + static LAST_ERROR: RefCell> = RefCell::new(None); +} + +/// Check if the last operation resulted in an error. Returns a pointer to an error message, or null +/// if there was no error. +#[unsafe(no_mangle)] +pub extern "C" fn processing_check_error() -> *const c_char { + LAST_ERROR.with(|last| { + last.borrow() + .as_ref() + .map(|s| s.as_ptr()) + .unwrap_or(std::ptr::null()) + }) +} + +/// Set the last error message. +pub fn set_error(error_msg: &str) { + LAST_ERROR.with(|last| { + *last.borrow_mut() = Some(CString::new(error_msg).unwrap_or_else(|_| { + CString::new("Failed to allocate error message".to_string()).unwrap() + })); + }); +} + +/// Clear the last error message. +pub fn clear_error() { + LAST_ERROR.with(|last| { + *last.borrow_mut() = None; + }); +} + + +/// Check the result of an operation, setting the last error if there was one. +pub fn check(result: Result) -> Option { + match result { + Ok(value) => { + Some(value) + } + Err(err) => { + set_error(&err.to_string()); + None + } + } +} \ No newline at end of file diff --git a/libProcessing/ffi/src/lib.rs b/libProcessing/ffi/src/lib.rs index 9381e76b5..b24bd1988 100644 --- a/libProcessing/ffi/src/lib.rs +++ b/libProcessing/ffi/src/lib.rs @@ -1,4 +1,7 @@ +mod error; + #[unsafe(no_mangle)] -pub extern "C" fn processing_add(left: u64, right: u64) -> u64 { - renderer::add(left, right) +pub extern "C" fn processing_init() { + error::clear_error(); + error::check(renderer::init()); } \ No newline at end of file diff --git a/libProcessing/renderer/Cargo.toml b/libProcessing/renderer/Cargo.toml index c29f61c72..7a54e54fa 100644 --- a/libProcessing/renderer/Cargo.toml +++ b/libProcessing/renderer/Cargo.toml @@ -4,3 +4,9 @@ version = "0.1.0" edition = "2024" [dependencies] +tracing = "0.1" +tracing-subscriber = "0.3" +bevy = { version = "0.16", no-default-features = true, features = [ + "bevy_render" +] } +thiserror = "2" \ No newline at end of file diff --git a/libProcessing/renderer/src/error.rs b/libProcessing/renderer/src/error.rs new file mode 100644 index 000000000..93ff93001 --- /dev/null +++ b/libProcessing/renderer/src/error.rs @@ -0,0 +1,12 @@ +use thiserror::Error; + +pub type Result = std::result::Result; + + +#[derive(Error, Debug)] +pub enum ProcessingError { + #[error("App was accessed from multiple threads")] + AppAccess, + #[error("Error initializing tracing: {0}")] + Tracing(#[from] tracing::subscriber::SetGlobalDefaultError), +} \ No newline at end of file diff --git a/libProcessing/renderer/src/lib.rs b/libProcessing/renderer/src/lib.rs index 048c97f07..de14da91b 100644 --- a/libProcessing/renderer/src/lib.rs +++ b/libProcessing/renderer/src/lib.rs @@ -1,4 +1,50 @@ -pub fn add(left: u64, right: u64) -> u64 { - println!("Adding {} and {} in Rust", left, right); - left + right -} \ No newline at end of file +pub mod error; + +// Once-cell for our app +use crate::error::Result; +use bevy::app::App; +use bevy::log::tracing_subscriber; +use std::sync::{Arc, Mutex, OnceLock}; +use tracing::{debug, info}; + +static IS_INIT: OnceLock<()> = OnceLock::new(); + +thread_local! { + static APP: OnceLock = OnceLock::default(); +} + +/// Initialize the app, if not already initialized. Must be called from the main thread and cannot +/// be called concurrently from multiple threads. +pub fn init() -> Result<()> { + setup_tracing()?; + info!("Initializing libprocessing"); + + let is_init = IS_INIT.get().is_some(); + let thread_has_app = APP.with(|app_lock| app_lock.get().is_some()); + if is_init && !thread_has_app { + return Err(error::ProcessingError::AppAccess); + } + if is_init && thread_has_app { + debug!("App already initialized"); + return Ok(()); + } + + APP.with(|app_lock| { + app_lock.get_or_init(|| { + IS_INIT.get_or_init(|| ()); + let mut app = App::new(); + + app.add_plugins(bevy::MinimalPlugins); + + app + }); + }); + + Ok(()) +} + +fn setup_tracing() -> Result<()> { + let subscriber = tracing_subscriber::FmtSubscriber::new(); + tracing::subscriber::set_global_default(subscriber)?; + Ok(()) +} diff --git a/libProcessing/src/main.rs b/libProcessing/src/main.rs deleted file mode 100644 index e7a11a969..000000000 --- a/libProcessing/src/main.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - println!("Hello, world!"); -} From bc5a52425d23ecd04f2600307c68ff9bcf943715 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?charlotte=20=F0=9F=8C=B8?= Date: Wed, 22 Oct 2025 17:42:30 -0500 Subject: [PATCH 10/26] Basic app lifecycle / surface creation. --- core/build.gradle.kts | 20 + core/src/processing/core/PApplet.java | 8 +- core/src/processing/core/PConstants.java | 2 + .../processing/webgpu/PGraphicsWebGPU.java | 39 +- core/src/processing/webgpu/PSurfaceGLFW.java | 423 +++++ core/src/processing/webgpu/PWebGPU.java | 48 +- .../processing/mode/java/runner/Runner.java | 10 + libProcessing/Cargo.lock | 1591 ++++++++++++----- libProcessing/ffi/src/error.rs | 33 +- libProcessing/ffi/src/lib.rs | 63 +- libProcessing/renderer/Cargo.toml | 9 +- libProcessing/renderer/src/error.rs | 6 + libProcessing/renderer/src/lib.rs | 215 ++- 13 files changed, 1961 insertions(+), 506 deletions(-) create mode 100644 core/src/processing/webgpu/PSurfaceGLFW.java diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 30a79fcc4..e764f8e1c 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -39,6 +39,26 @@ dependencies { implementation(libs.jogl) implementation(libs.gluegen) + val lwjglVersion = "3.3.6" + val lwjglNatives = when { + System.getProperty("os.name").lowercase().contains("mac") -> { + if (System.getProperty("os.arch").contains("aarch64")) { + "natives-macos-arm64" + } else { + "natives-macos" + } + } + System.getProperty("os.name").lowercase().contains("win") -> "natives-windows" + System.getProperty("os.name").lowercase().contains("linux") -> "natives-linux" + else -> "natives-linux" + } + + implementation(platform("org.lwjgl:lwjgl-bom:$lwjglVersion")) + implementation("org.lwjgl", "lwjgl") + implementation("org.lwjgl", "lwjgl-glfw") + runtimeOnly("org.lwjgl", "lwjgl", classifier = lwjglNatives) + runtimeOnly("org.lwjgl", "lwjgl-glfw", classifier = lwjglNatives) + testImplementation(libs.junit) } diff --git a/core/src/processing/core/PApplet.java b/core/src/processing/core/PApplet.java index 4fccd1a53..9f832d29d 100644 --- a/core/src/processing/core/PApplet.java +++ b/core/src/processing/core/PApplet.java @@ -9981,10 +9981,6 @@ static public void runSketch(final String[] args, } break; - case ARGS_DISABLE_AWT: - disableAWT = true; - break; - case ARGS_WINDOW_COLOR: if (value.charAt(0) == '#' && value.length() == 7) { value = value.substring(1); @@ -10036,6 +10032,10 @@ static public void runSketch(final String[] args, fullScreen = true; break; + case ARGS_DISABLE_AWT: + disableAWT = true; + break; + default: name = args[argIndex]; break label; // because of break, argIndex won't increment again diff --git a/core/src/processing/core/PConstants.java b/core/src/processing/core/PConstants.java index d21a1fa49..d1179984e 100644 --- a/core/src/processing/core/PConstants.java +++ b/core/src/processing/core/PConstants.java @@ -72,6 +72,8 @@ public interface PConstants { // Experimental JavaFX renderer; even better 2D performance String FX2D = "processing.javafx.PGraphicsFX2D"; + String WEBGPU = "processing.webgpu.PGraphicsWebGPU"; + String PDF = "processing.pdf.PGraphicsPDF"; String SVG = "processing.svg.PGraphicsSVG"; String DXF = "processing.dxf.RawDXF"; diff --git a/core/src/processing/webgpu/PGraphicsWebGPU.java b/core/src/processing/webgpu/PGraphicsWebGPU.java index d0ffeef0f..78fb86046 100644 --- a/core/src/processing/webgpu/PGraphicsWebGPU.java +++ b/core/src/processing/webgpu/PGraphicsWebGPU.java @@ -1,4 +1,41 @@ package processing.webgpu; -public class PGraphicsWebGPU { +import processing.core.PGraphics; +import processing.core.PSurface; + +public class PGraphicsWebGPU extends PGraphics { + private long windowId = 0; + + @Override + public PSurface createSurface() { + return surface = new PSurfaceGLFW(this); + } + + protected void initWebGPUSurface(long windowHandle, int width, int height, float scaleFactor) { + windowId = PWebGPU.createSurface(windowHandle, width, height, scaleFactor); + if (windowId == 0) { + System.err.println("Failed to create WebGPU surface"); + } + } + + @Override + public void setSize(int w, int h) { + super.setSize(w, h); + if (windowId != 0) { + PWebGPU.windowResized(windowId, pixelWidth, pixelHeight); + } + } + + @Override + public void endDraw() { + super.endDraw(); + PWebGPU.update(); + } + + @Override + public void dispose() { + super.dispose(); + + PWebGPU.exit(); + } } diff --git a/core/src/processing/webgpu/PSurfaceGLFW.java b/core/src/processing/webgpu/PSurfaceGLFW.java new file mode 100644 index 000000000..16719f6a9 --- /dev/null +++ b/core/src/processing/webgpu/PSurfaceGLFW.java @@ -0,0 +1,423 @@ +package processing.webgpu; + +import org.lwjgl.glfw.GLFW; +import org.lwjgl.glfw.GLFWErrorCallback; +import org.lwjgl.glfw.GLFWFramebufferSizeCallback; +import org.lwjgl.glfw.GLFWNativeCocoa; +import org.lwjgl.glfw.GLFWWindowPosCallback; +import org.lwjgl.system.MemoryUtil; +import org.lwjgl.system.Platform; + +import processing.core.PApplet; +import processing.core.PGraphics; +import processing.core.PImage; +import processing.core.PSurface; + +import java.io.File; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +/** + * GLFW-based surface implementation for WebGPU. + */ +public class PSurfaceGLFW implements PSurface { + + protected PApplet sketch; + protected PGraphics graphics; + + protected long window; + protected boolean running = false; + + protected boolean paused; + private final Lock pauseLock = new ReentrantLock(); + private final Condition pauseCondition = pauseLock.newCondition(); + + protected float frameRateTarget = 60; + protected long frameRatePeriod = 1000000000L / 60L; + + private static final AtomicInteger windowCount = new AtomicInteger(0); + private static AtomicBoolean glfwInitialized = new AtomicBoolean(false); + + private GLFWFramebufferSizeCallback framebufferSizeCallback; + private GLFWWindowPosCallback windowPosCallback; + + public PSurfaceGLFW(PGraphics graphics) { + this.graphics = graphics; + } + + @Override + public void initOffscreen(PApplet sketch) { + throw new IllegalStateException("PSurfaceGLFW does not support offscreen rendering"); + } + + @Override + public void initFrame(PApplet sketch) { + this.sketch = sketch; + + if (glfwInitialized.compareAndSet(false, true)) { + GLFWErrorCallback.createPrint(System.err).set(); + if (!GLFW.glfwInit()) { + glfwInitialized.set(false); + throw new IllegalStateException("Failed to initialize GLFW"); + } + System.out.println("PSurfaceGLFW: GLFW initialized successfully"); + } + + GLFW.glfwDefaultWindowHints(); + GLFW.glfwWindowHint(GLFW.GLFW_CLIENT_API, GLFW.GLFW_NO_API); // no opengl + GLFW.glfwWindowHint(GLFW.GLFW_VISIBLE, GLFW.GLFW_FALSE); + GLFW.glfwWindowHint(GLFW.GLFW_RESIZABLE, GLFW.GLFW_FALSE); + + window = GLFW.glfwCreateWindow(sketch.sketchWidth(), sketch.sketchHeight(), "Processing", + MemoryUtil.NULL, MemoryUtil.NULL); + if (window == MemoryUtil.NULL) { + throw new RuntimeException("Failed to create GLFW window"); + } + + windowCount.incrementAndGet(); + + // event callbacks + initListeners(); + + if (graphics instanceof PGraphicsWebGPU webgpu) { + PWebGPU.init(); + + long windowHandle = getWindowHandle(); + int width = sketch.sketchWidth(); + int height = sketch.sketchHeight(); + float scaleFactor = sketch.sketchPixelDensity(); + + webgpu.initWebGPUSurface(windowHandle, width, height, scaleFactor); + } + } + + protected void initListeners() { + framebufferSizeCallback = GLFW.glfwSetFramebufferSizeCallback(window, + (window, width, height) -> { + if (sketch != null) { + sketch.postWindowResized(width, height); + } + }); + + windowPosCallback = GLFW.glfwSetWindowPosCallback(window, + (window, xpos, ypos) -> { + if (sketch != null) { + sketch.postWindowMoved(xpos, ypos); + } + }); + + // TODO: all the callbacks + } + + @Override + public Object getNative() { + return window; + } + + public long getWindowHandle() { + if (Platform.get() == Platform.MACOSX) { + return GLFWNativeCocoa.glfwGetCocoaWindow(window); + } else { + return window; + } + } + + @Override + public void setTitle(String title) { + if (window != MemoryUtil.NULL) { + GLFW.glfwSetWindowTitle(window, title); + } + } + + @Override + public void setVisible(boolean visible) { + if (window != MemoryUtil.NULL) { + if (visible) { + GLFW.glfwShowWindow(window); + } else { + GLFW.glfwHideWindow(window); + } + } + } + + @Override + public void setResizable(boolean resizable) { + if (window != MemoryUtil.NULL) { + GLFW.glfwSetWindowAttrib(window, GLFW.GLFW_RESIZABLE, + resizable ? GLFW.GLFW_TRUE : GLFW.GLFW_FALSE); + } + } + + @Override + public void setAlwaysOnTop(boolean always) { + if (window != MemoryUtil.NULL) { + GLFW.glfwSetWindowAttrib(window, GLFW.GLFW_FLOATING, + always ? GLFW.GLFW_TRUE : GLFW.GLFW_FALSE); + } + } + + @Override + public void setIcon(PImage icon) { + // TODO: set icon with glfw + } + + @Override + public void placeWindow(int[] location, int[] editorLocation) { + if (window == MemoryUtil.NULL) return; + + int x, y; + if (location != null) { + x = location[0]; + y = location[1]; + } else if (editorLocation != null) { + x = editorLocation[0] - 20; + y = editorLocation[1]; + + if (x - sketch.sketchWidth() < 10) { + // doesn't fit, center on screen instead + long monitor = GLFW.glfwGetPrimaryMonitor(); + var vidmode = GLFW.glfwGetVideoMode(monitor); + if (vidmode != null) { + x = (vidmode.width() - sketch.sketchWidth()) / 2; + y = (vidmode.height() - sketch.sketchHeight()) / 2; + } else { + x = 100; + y = 100; + } + } + } else { + // center on primary monitor + long monitor = GLFW.glfwGetPrimaryMonitor(); + var vidmode = GLFW.glfwGetVideoMode(monitor); + if (vidmode != null) { + x = (vidmode.width() - sketch.sketchWidth()) / 2; + y = (vidmode.height() - sketch.sketchHeight()) / 2; + } else { + x = 100; + y = 100; + } + } + + GLFW.glfwSetWindowPos(window, x, y); + } + + @Override + public void placePresent(int stopColor) { + // TODO: implement present mode support + } + + @Override + public void setLocation(int x, int y) { + if (window != MemoryUtil.NULL) { + GLFW.glfwSetWindowPos(window, x, y); + } + } + + @Override + public void setSize(int width, int height) { + if (width == sketch.width && height == sketch.height) { + return; + } + + sketch.width = width; + sketch.height = height; + graphics.setSize(width, height); + + if (window != MemoryUtil.NULL) { + GLFW.glfwSetWindowSize(window, width, height); + } + } + + @Override + public void setFrameRate(float fps) { + frameRateTarget = fps; + frameRatePeriod = (long) (1000000000.0 / frameRateTarget); + } + + @Override + public void setCursor(int kind) { + // TODO: implement cursor types + } + + @Override + public void setCursor(PImage image, int hotspotX, int hotspotY) { + // TODO: implement custom cursor + } + + @Override + public void showCursor() { + if (window != MemoryUtil.NULL) { + GLFW.glfwSetInputMode(window, GLFW.GLFW_CURSOR, GLFW.GLFW_CURSOR_NORMAL); + } + } + + @Override + public void hideCursor() { + if (window != MemoryUtil.NULL) { + GLFW.glfwSetInputMode(window, GLFW.GLFW_CURSOR, GLFW.GLFW_CURSOR_HIDDEN); + } + } + + @Override + public PImage loadImage(String path, Object... args) { + // TODO: implement image loading without awt + throw new UnsupportedOperationException("Image loading not yet implemented for WebGPU"); + } + + @Override + public boolean openLink(String url) { + // TODO: implement links without awt + return false; + } + + @Override + public void selectInput(String prompt, String callback, File file, Object callbackObject) { + // TODO: select input without awt + throw new UnsupportedOperationException("File dialogs not yet implemented for WebGPU"); + } + + @Override + public void selectOutput(String prompt, String callback, File file, Object callbackObject) { + // TODO: file dialogs without awt + throw new UnsupportedOperationException("File dialogs not yet implemented for WebGPU"); + } + + @Override + public void selectFolder(String prompt, String callback, File file, Object callbackObject) { + // TODO: folder selection without awt + throw new UnsupportedOperationException("Folder selection not yet implemented for WebGPU"); + } + + @Override + public void startThread() { + if (running) { + throw new IllegalStateException("Draw loop already running"); + } + + running = true; + runDrawLoop(); + } + + protected void runDrawLoop() { + GLFW.glfwShowWindow(window); + + long beforeTime = System.nanoTime(); + long overSleepTime = 0L; + + sketch.start(); + + while (running && !sketch.finished) { + checkPause(); + + GLFW.glfwPollEvents(); + + if (GLFW.glfwWindowShouldClose(window)) { + sketch.exit(); + break; + } + + // render! + sketch.handleDraw(); + + // frame pacing + long afterTime = System.nanoTime(); + long timeDiff = afterTime - beforeTime; + long sleepTime = (frameRatePeriod - timeDiff) - overSleepTime; + + if (sleepTime > 0) { + try { + Thread.sleep(sleepTime / 1000000L, (int) (sleepTime % 1000000L)); + } catch (InterruptedException ex) { + Thread.currentThread().interrupt(); + } + overSleepTime = (System.nanoTime() - afterTime) - sleepTime; + } else { + overSleepTime = 0L; + } + + beforeTime = System.nanoTime(); + } + + // cleanup + sketch.dispose(); + } + + @Override + public void pauseThread() { + paused = true; + } + + protected void checkPause() { + if (paused) { + pauseLock.lock(); + try { + while (paused) { + pauseCondition.await(); + } + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } finally { + pauseLock.unlock(); + } + } + } + + @Override + public void resumeThread() { + pauseLock.lock(); + try { + paused = false; + pauseCondition.signalAll(); + } finally { + pauseLock.unlock(); + } + } + + @Override + public boolean stopThread() { + if (!running) { + return false; + } + + running = false; + + try { + if (window != MemoryUtil.NULL) { + GLFW.glfwDestroyWindow(window); + window = MemoryUtil.NULL; + + if (windowCount.decrementAndGet() == 0) { + if (glfwInitialized.compareAndSet(true, false)) { + GLFW.glfwTerminate(); + System.out.println("PSurfaceGLFW: GLFW terminated"); + } + } + } + } finally { + // run destructors always + freeCallbacks(); + } + + return true; + } + + private void freeCallbacks() { + if (framebufferSizeCallback != null) { + framebufferSizeCallback.free(); + framebufferSizeCallback = null; + } + if (windowPosCallback != null) { + windowPosCallback.free(); + windowPosCallback = null; + } + } + + + @Override + public boolean isStopped() { + return !running; + } +} diff --git a/core/src/processing/webgpu/PWebGPU.java b/core/src/processing/webgpu/PWebGPU.java index e16e0fae2..b0e76b203 100644 --- a/core/src/processing/webgpu/PWebGPU.java +++ b/core/src/processing/webgpu/PWebGPU.java @@ -5,8 +5,7 @@ import java.lang.foreign.MemorySegment; import static java.lang.foreign.MemorySegment.NULL; -import static processing.ffi.processing_h.processing_check_error; -import static processing.ffi.processing_h.processing_init; +import static processing.ffi.processing_h.*; /** * PWebGPU provides the native interface layer for libProcessing's WebGPU support. @@ -15,7 +14,6 @@ public class PWebGPU { static { ensureLoaded(); - init(); } /** @@ -27,12 +25,56 @@ public static void ensureLoaded() { /** * Initializes the WebGPU subsystem. Must be called before any other WebGPU methods. + * This should be called from the same thread that will call update(). */ public static void init() { processing_init(); checkError(); } + /** + * Creates a WebGPU surface from a native window handle. + * + * @param windowHandle The native window handle + * @param width Window width in physical pixels + * @param height Window height in phsyical pixels + * @param scaleFactor os provided scale factor + * @return Window ID to use for subsequent operations + */ + public static long createSurface(long windowHandle, int width, int height, float scaleFactor) { + long windowId = processing_create_surface(windowHandle, width, height, scaleFactor); + checkError(); + return windowId; + } + + /** + * Updates a window's size. + * + * @param windowId The window ID returned from createSurface + * @param width New physical window width in pixels + * @param height New physical window height in pixels + */ + public static void windowResized(long windowId, int width, int height) { + processing_window_resized(windowId, width, height); + checkError(); + } + + /** + * Updates the WebGPU subsystem. Should be called once per frame after all drawing is complete. + */ + public static void update() { + processing_update(); + checkError(); + } + + /** + * Cleans up the WebGPU subsystem. Should be called on application exit. + */ + public static void exit() { + processing_exit((byte) 0); + checkError(); + } + /** * Checks for errors from the native library and throws a PWebGPUException if an error occurred. */ diff --git a/java/src/processing/mode/java/runner/Runner.java b/java/src/processing/mode/java/runner/Runner.java index a9baf1ea6..de8ef2857 100644 --- a/java/src/processing/mode/java/runner/Runner.java +++ b/java/src/processing/mode/java/runner/Runner.java @@ -342,6 +342,9 @@ protected StringList getMachineParams() { // No longer needed / doesn't seem to do anything differently //params.append("-Dcom.apple.mrj.application.apple.menu.about.name=" + // build.getSketchClassName()); + + // required for GLFW and Metal when using WebGPU + params.append("-XstartOnFirstThread"); } /* if (Platform.isWindows()) { @@ -380,6 +383,10 @@ protected StringList getMachineParams() { // http://processing.org/bugs/bugzilla/1188.html params.append("-ea"); + // we need to open up access to internal jdk modules for libraries that use reflection + // this will break at some point in the future when these modules are removed from the jdk :( + params.append("--enable-native-access=ALL-UNNAMED"); + return params; } @@ -508,6 +515,9 @@ protected StringList getSketchParams(boolean present, String[] args) { } */ + // TODO: excise AWT to make webgpu work properly + params.append(PApplet.ARGS_DISABLE_AWT); + params.append(build.getSketchClassName()); } // Add command-line arguments to be given to the sketch itself diff --git a/libProcessing/Cargo.lock b/libProcessing/Cargo.lock index 507d667e6..cd58b5248 100644 --- a/libProcessing/Cargo.lock +++ b/libProcessing/Cargo.lock @@ -2,57 +2,71 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "ab_glyph" +version = "0.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01c0457472c38ea5bd1c3b5ada5e368271cb550be7a4ca4a0b4634e9913f6cc2" +dependencies = [ + "ab_glyph_rasterizer", + "owned_ttf_parser", +] + +[[package]] +name = "ab_glyph_rasterizer" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "366ffbaa4442f4684d91e2cd7c5ea7c4ed8add41959a31447066e279e432b618" + [[package]] name = "accesskit" -version = "0.18.0" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "becf0eb5215b6ecb0a739c31c21bd83c4f326524c9b46b7e882d77559b60a529" +checksum = "cf203f9d3bd8f29f98833d1fbef628df18f759248a547e7e01cfbf63cda36a99" [[package]] name = "accesskit_consumer" -version = "0.27.0" +version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0bf66a7bf0b7ea4fd7742d50b64782a88f99217cf246b3f93b4162528dde520" +checksum = "bdd06f5fea9819250fffd4debf926709f3593ac22f8c1541a2573e5ee0ca01cd" dependencies = [ "accesskit", "hashbrown 0.15.5", - "immutable-chunkmap", ] [[package]] name = "accesskit_macos" -version = "0.19.0" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09e230718177753b4e4ad9e1d9f6cfc2f4921212d4c1c480b253f526babb258d" +checksum = "93fbaf15815f39084e0cb24950c232f0e3634702c2dfbf182ae3b4919a4a1d45" dependencies = [ "accesskit", "accesskit_consumer", "hashbrown 0.15.5", - "objc2", - "objc2-app-kit", - "objc2-foundation", + "objc2 0.5.2", + "objc2-app-kit 0.2.2", + "objc2-foundation 0.2.2", ] [[package]] name = "accesskit_windows" -version = "0.25.0" +version = "0.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65178f3df98a51e4238e584fcb255cb1a4f9111820848eeddd37663be40a625f" +checksum = "792991159fa9ba57459de59e12e918bb90c5346fea7d40ac1a11f8632b41e63a" dependencies = [ "accesskit", "accesskit_consumer", "hashbrown 0.15.5", - "paste", "static_assertions", - "windows 0.58.0", - "windows-core 0.58.0", + "windows 0.61.3", + "windows-core 0.61.2", ] [[package]] name = "accesskit_winit" -version = "0.25.0" +version = "0.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34d941bb8c414caba6e206de669c7dc0dbeb305640ea890772ee422a40e6b89f" +checksum = "cd9db0ea66997e3f4eae4a5f2c6b6486cf206642639ee629dbbb860ace1dec87" dependencies = [ "accesskit", "accesskit_macos", @@ -67,6 +81,19 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" +[[package]] +name = "ahash" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" +dependencies = [ + "cfg-if", + "getrandom", + "once_cell", + "version_check", + "zerocopy", +] + [[package]] name = "aho-corasick" version = "1.1.3" @@ -331,12 +358,6 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" -[[package]] -name = "base64" -version = "0.21.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" - [[package]] name = "base64" version = "0.22.1" @@ -345,18 +366,18 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "bevy" -version = "0.16.1" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b8369c16b7c017437021341521f8b4a0d98e1c70113fb358c3258ae7d661d79" +checksum = "342f7e9335416dc98642d5747c4ed8a6ad9f7244a36d5b2b7a1b7910e4d8f524" dependencies = [ "bevy_internal", ] [[package]] name = "bevy_a11y" -version = "0.16.1" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed3561712cf49074d89e9989bfc2e6c6add5d33288f689db9a0c333300d2d004" +checksum = "3917cd35096fb2fe176632740b68a4b53cb61006cfff13d66ef47ee2c2478d53" dependencies = [ "accesskit", "bevy_app", @@ -365,29 +386,37 @@ dependencies = [ "bevy_reflect", ] +[[package]] +name = "bevy_android" +version = "0.17.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a9dd9488c77fa2ea31b5da2f978aab7f1cc82e6d2c3be0adf637d9fd7cb6c8" +dependencies = [ + "android-activity", +] + [[package]] name = "bevy_animation" -version = "0.16.1" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49796627726d0b9a722ad9a0127719e7c1868f474d6575ec0f411e8299c4d7bb" +checksum = "00d2eadb9c20d87ab3a5528a8df483492d5b8102d3f2d61c7b1ed23f40a79166" dependencies = [ + "bevy_animation_macros", "bevy_app", "bevy_asset", "bevy_color", "bevy_derive", "bevy_ecs", - "bevy_log", "bevy_math", "bevy_mesh", "bevy_platform", "bevy_reflect", - "bevy_render", "bevy_time", "bevy_transform", "bevy_utils", "blake3", "derive_more", - "downcast-rs", + "downcast-rs 2.0.2", "either", "petgraph", "ron", @@ -399,11 +428,44 @@ dependencies = [ "uuid", ] +[[package]] +name = "bevy_animation_macros" +version = "0.17.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aec80b84926f730f6df81b9bc07255c120f57aaf7ac577f38d12dd8e1a0268ad" +dependencies = [ + "bevy_macro_utils", + "quote", + "syn", +] + +[[package]] +name = "bevy_anti_alias" +version = "0.17.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38c1adb85fe0956d6c3b6f90777b829785bb7e29a48f58febeeefd2bad317713" +dependencies = [ + "bevy_app", + "bevy_asset", + "bevy_camera", + "bevy_core_pipeline", + "bevy_derive", + "bevy_diagnostic", + "bevy_ecs", + "bevy_image", + "bevy_math", + "bevy_reflect", + "bevy_render", + "bevy_shader", + "bevy_utils", + "tracing", +] + [[package]] name = "bevy_app" -version = "0.16.1" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4491cc4c718ae76b4c6883df58b94cc88b32dcd894ea8d5b603c7c7da72ca967" +checksum = "9f582409b4ed3850d9b66ee94e71a0e2c20e7068121d372530060c4dfcba66fa" dependencies = [ "bevy_derive", "bevy_ecs", @@ -414,7 +476,7 @@ dependencies = [ "cfg-if", "console_error_panic_hook", "ctrlc", - "downcast-rs", + "downcast-rs 2.0.2", "log", "thiserror 2.0.17", "variadics_please", @@ -424,14 +486,15 @@ dependencies = [ [[package]] name = "bevy_asset" -version = "0.16.1" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f56111d9b88d8649f331a667d9d72163fb26bd09518ca16476d238653823db1e" +checksum = "9e6ee42e74a64a46ab91bd1c0155f8abe5b732bdb948a9b26e541456cc7940e5" dependencies = [ "async-broadcast", "async-fs", "async-lock", "atomicow", + "bevy_android", "bevy_app", "bevy_asset_macros", "bevy_ecs", @@ -439,13 +502,12 @@ dependencies = [ "bevy_reflect", "bevy_tasks", "bevy_utils", - "bevy_window", "bitflags 2.9.4", "blake3", "crossbeam-channel", "derive_more", "disqualified", - "downcast-rs", + "downcast-rs 2.0.2", "either", "futures-io", "futures-lite", @@ -464,9 +526,9 @@ dependencies = [ [[package]] name = "bevy_asset_macros" -version = "0.16.1" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4cca3e67c0ec760d8889d42293d987ce5da92eaf9c592bf5d503728a63b276d" +checksum = "d03711d2c087227f64ba85dd38a99d4d6893f80d2475c2e77fb90a883760a055" dependencies = [ "bevy_macro_utils", "proc-macro2", @@ -476,27 +538,53 @@ dependencies = [ [[package]] name = "bevy_audio" -version = "0.16.1" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2b4f6f2a5c6c0e7c6825e791d2a061c76c2d6784f114c8f24382163fabbfaaa" +checksum = "f83620c82f281848c02ed4b65133a0364512b4eca2b39cd21a171e50e2986d89" dependencies = [ "bevy_app", "bevy_asset", - "bevy_derive", "bevy_ecs", "bevy_math", "bevy_reflect", "bevy_transform", + "coreaudio-sys", "cpal", "rodio", "tracing", ] +[[package]] +name = "bevy_camera" +version = "0.17.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b70d79ccbd8bfefc79f33a104dfd82ae2f5276ce04d6df75787bfa3edc4c4c1a" +dependencies = [ + "bevy_app", + "bevy_asset", + "bevy_color", + "bevy_derive", + "bevy_ecs", + "bevy_image", + "bevy_math", + "bevy_mesh", + "bevy_reflect", + "bevy_transform", + "bevy_utils", + "bevy_window", + "derive_more", + "downcast-rs 2.0.2", + "serde", + "smallvec", + "thiserror 2.0.17", + "wgpu-types", +] + [[package]] name = "bevy_color" -version = "0.16.2" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c101cbe1e26b8d701eb77263b14346e2e0cbbd2a6e254b9b1aead814e5ca8d3" +checksum = "94dc78477c1c208c0cd221c64e907aba8ba165f39bebb72adc6180e1a13e8938" dependencies = [ "bevy_math", "bevy_reflect", @@ -510,29 +598,28 @@ dependencies = [ [[package]] name = "bevy_core_pipeline" -version = "0.16.1" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ed46363cad80dc00f08254c3015232bd6f640738403961c6d63e7ecfc61625" +checksum = "0c866a2fe33ec27a612d883223d30f1857aa852766b21a9603628735dace632f" dependencies = [ "bevy_app", "bevy_asset", + "bevy_camera", "bevy_color", "bevy_derive", - "bevy_diagnostic", "bevy_ecs", "bevy_image", "bevy_math", "bevy_platform", "bevy_reflect", "bevy_render", + "bevy_shader", "bevy_transform", "bevy_utils", "bevy_window", "bitflags 2.9.4", - "bytemuck", "nonmax", "radsort", - "serde", "smallvec", "thiserror 2.0.17", "tracing", @@ -540,9 +627,9 @@ dependencies = [ [[package]] name = "bevy_derive" -version = "0.16.1" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b837bf6c51806b10ebfa9edf1844ad80a3a0760d6c5fac4e90761df91a8901a" +checksum = "b8c733807158f8fcac68e23222e69ed91a6492ae9410fc2c145b9bb182cfd63e" dependencies = [ "bevy_macro_utils", "quote", @@ -551,16 +638,16 @@ dependencies = [ [[package]] name = "bevy_diagnostic" -version = "0.16.1" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48797366f312a8f31e237d08ce3ee70162591282d2bfe7c5ad8be196fb263e55" +checksum = "f12fa32312818c08aa4035bebe9fb3f62aaf7efae33688e718dd6ee6c0147493" dependencies = [ + "atomic-waker", "bevy_app", "bevy_ecs", "bevy_platform", "bevy_tasks", "bevy_time", - "bevy_utils", "const-fnv1a-hash", "log", "serde", @@ -569,9 +656,9 @@ dependencies = [ [[package]] name = "bevy_ecs" -version = "0.16.1" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c2bf6521aae57a0ec3487c4bfb59e36c4a378e834b626a4bea6a885af2fdfe7" +checksum = "69d929d32190cfcde6efd2df493601c4dbc18a691fd9775a544c951c3c112e1a" dependencies = [ "arrayvec", "bevy_ecs_macros", @@ -584,12 +671,12 @@ dependencies = [ "bumpalo", "concurrent-queue", "derive_more", - "disqualified", "fixedbitset", "indexmap", "log", "nonmax", "serde", + "slotmap", "smallvec", "thiserror 2.0.17", "variadics_please", @@ -597,9 +684,9 @@ dependencies = [ [[package]] name = "bevy_ecs_macros" -version = "0.16.1" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38748d6f3339175c582d751f410fb60a93baf2286c3deb7efebb0878dce7f413" +checksum = "6eeddfb80a2e000663e87be9229c26b4da92bddbc06c8776bc0d1f4a7f679079" dependencies = [ "bevy_macro_utils", "proc-macro2", @@ -609,9 +696,9 @@ dependencies = [ [[package]] name = "bevy_encase_derive" -version = "0.16.1" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8148f4edee470a2ea5cad010184c492a4c94c36d7a7158ea28e134ea87f274ab" +checksum = "7449e5903594a00f007732ba232af0c527ad4e6e3d29bc3e195ec78dbd20c8b2" dependencies = [ "bevy_macro_utils", "encase_derive_impl", @@ -619,16 +706,15 @@ dependencies = [ [[package]] name = "bevy_gilrs" -version = "0.16.1" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97efef87c631949e67d06bb5d7dfd2a5f936b3b379afb6b1485b08edbb219b87" +checksum = "28ff35087f25406006338e6d57f31f313a60f3a5e09990ab7c7b5203b0b55077" dependencies = [ "bevy_app", "bevy_ecs", "bevy_input", "bevy_platform", "bevy_time", - "bevy_utils", "gilrs", "thiserror 2.0.17", "tracing", @@ -636,22 +722,26 @@ dependencies = [ [[package]] name = "bevy_gizmos" -version = "0.16.1" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7823154a9682128c261d8bddb3a4d7192a188490075c527af04520c2f0f8aad6" +checksum = "0d3f174faa13041634060dd99f6f59c29997fd62f40252f0466c2ebea8603d4d" dependencies = [ "bevy_app", "bevy_asset", + "bevy_camera", "bevy_color", "bevy_core_pipeline", "bevy_ecs", "bevy_gizmos_macros", "bevy_image", + "bevy_light", "bevy_math", + "bevy_mesh", "bevy_pbr", "bevy_reflect", "bevy_render", - "bevy_sprite", + "bevy_shader", + "bevy_sprite_render", "bevy_time", "bevy_transform", "bevy_utils", @@ -661,30 +751,30 @@ dependencies = [ [[package]] name = "bevy_gizmos_macros" -version = "0.16.1" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f378f3b513218ddc78254bbe76536d9de59c1429ebd0c14f5d8f2a25812131ad" +checksum = "714273aa7f285c0aaa874b7fbe37fe4e6e45355e3e6f3321aefa1b78cda259e0" dependencies = [ "bevy_macro_utils", - "proc-macro2", "quote", "syn", ] [[package]] name = "bevy_gltf" -version = "0.16.1" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10a080237c0b8842ccc15a06d3379302c68580eeea4497b1c7387e470eda1f07" +checksum = "13d67e954b20551818f7cdb33f169ab4db64506ada66eb4d60d3cb8861103411" dependencies = [ - "base64 0.22.1", + "base64", "bevy_animation", "bevy_app", "bevy_asset", + "bevy_camera", "bevy_color", - "bevy_core_pipeline", "bevy_ecs", "bevy_image", + "bevy_light", "bevy_math", "bevy_mesh", "bevy_pbr", @@ -694,7 +784,6 @@ dependencies = [ "bevy_scene", "bevy_tasks", "bevy_transform", - "bevy_utils", "fixedbitset", "gltf", "itertools 0.14.0", @@ -708,13 +797,14 @@ dependencies = [ [[package]] name = "bevy_image" -version = "0.16.1" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65e6e900cfecadbc3149953169e36b9e26f922ed8b002d62339d8a9dc6129328" +checksum = "168de8239b2aedd2eeef9f76ae1909b2fdf859b11dcdb4d4d01b93f5f2c771be" dependencies = [ "bevy_app", "bevy_asset", "bevy_color", + "bevy_ecs", "bevy_math", "bevy_platform", "bevy_reflect", @@ -736,16 +826,15 @@ dependencies = [ [[package]] name = "bevy_input" -version = "0.16.1" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18d6b6516433f6f7d680f648d04eb1866bb3927a1782d52f74831b62042f3cd1" +checksum = "3cf4074b2d0d6680b4deb308ded7b4e8b1b99181c0502e2632e78af815b26f01" dependencies = [ "bevy_app", "bevy_ecs", "bevy_math", "bevy_platform", "bevy_reflect", - "bevy_utils", "derive_more", "log", "smol_str", @@ -754,14 +843,15 @@ dependencies = [ [[package]] name = "bevy_input_focus" -version = "0.16.1" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e2d079fda74d1416e0a57dac29ea2b79ff77f420cd6b87f833d3aa29a46bc4d" +checksum = "70761eba0f616a1caa761457bff2b8ae80c9916f39d167fab8c2d5c98d2b8951" dependencies = [ "bevy_app", "bevy_ecs", "bevy_input", "bevy_math", + "bevy_picking", "bevy_reflect", "bevy_window", "log", @@ -770,15 +860,18 @@ dependencies = [ [[package]] name = "bevy_internal" -version = "0.16.1" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "857da8785678fde537d02944cd20dec9cafb7d4c447efe15f898dc60e733cacd" +checksum = "f43985739584f3a5d43026aa1edd772f064830be46c497518f05f7dfbc886bba" dependencies = [ "bevy_a11y", + "bevy_android", "bevy_animation", + "bevy_anti_alias", "bevy_app", "bevy_asset", "bevy_audio", + "bevy_camera", "bevy_color", "bevy_core_pipeline", "bevy_derive", @@ -790,36 +883,64 @@ dependencies = [ "bevy_image", "bevy_input", "bevy_input_focus", + "bevy_light", "bevy_log", "bevy_math", + "bevy_mesh", "bevy_pbr", "bevy_picking", "bevy_platform", + "bevy_post_process", "bevy_ptr", "bevy_reflect", "bevy_render", "bevy_scene", + "bevy_shader", "bevy_sprite", + "bevy_sprite_render", "bevy_state", "bevy_tasks", "bevy_text", "bevy_time", "bevy_transform", "bevy_ui", + "bevy_ui_render", "bevy_utils", "bevy_window", "bevy_winit", ] +[[package]] +name = "bevy_light" +version = "0.17.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cad00ab66d1e93edb928be66606a71066f3b1cbc9f414720e290ef5361eb6237" +dependencies = [ + "bevy_app", + "bevy_asset", + "bevy_camera", + "bevy_color", + "bevy_ecs", + "bevy_image", + "bevy_math", + "bevy_mesh", + "bevy_platform", + "bevy_reflect", + "bevy_transform", + "bevy_utils", + "tracing", +] + [[package]] name = "bevy_log" -version = "0.16.1" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7a61ee8aef17a974f5ca481dcedf0c2bd52670e231d4c4bc9ddef58328865f9" +checksum = "4ae217a035714a37b779487f82edc4c7c1223f7088d7ad94054f29f524d61c51" dependencies = [ "android_log-sys", "bevy_app", "bevy_ecs", + "bevy_platform", "bevy_utils", "tracing", "tracing-log", @@ -830,22 +951,22 @@ dependencies = [ [[package]] name = "bevy_macro_utils" -version = "0.16.1" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "052eeebcb8e7e072beea5031b227d9a290f8a7fbbb947573ab6ec81df0fb94be" +checksum = "17dbc3f8948da58b3c17767d20fd3cd35fe4721ed19a9a3204a6f1d6c9951bdd" dependencies = [ "parking_lot", "proc-macro2", "quote", "syn", - "toml_edit 0.22.27", + "toml_edit 0.23.7", ] [[package]] name = "bevy_math" -version = "0.16.1" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68553e0090fe9c3ba066c65629f636bd58e4ebd9444fdba097b91af6cd3e243f" +checksum = "f7a41e368ffa95ae2a353197d1ae3993f4d3d471444d80b65c932db667ea7b9e" dependencies = [ "approx", "bevy_reflect", @@ -863,10 +984,11 @@ dependencies = [ [[package]] name = "bevy_mesh" -version = "0.16.1" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b10399c7027001edbc0406d7d0198596b1f07206c1aae715274106ba5bdcac40" +checksum = "b6255244b71153b305fddb4e6f827cb97ed51f276b6e632f5fc46538647948f6" dependencies = [ + "bevy_app", "bevy_asset", "bevy_derive", "bevy_ecs", @@ -876,11 +998,10 @@ dependencies = [ "bevy_platform", "bevy_reflect", "bevy_transform", - "bevy_utils", "bitflags 2.9.4", "bytemuck", + "derive_more", "hexasphere", - "serde", "thiserror 2.0.17", "tracing", "wgpu-types", @@ -888,41 +1009,40 @@ dependencies = [ [[package]] name = "bevy_mikktspace" -version = "0.16.1" +version = "0.17.0-dev" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bb60c753b968a2de0fd279b76a3d19517695e771edb4c23575c7f92156315de" -dependencies = [ - "glam", -] +checksum = "7ef8e4b7e61dfe7719bb03c884dc270cd46a82efb40f93e9933b990c5c190c59" [[package]] name = "bevy_pbr" -version = "0.16.1" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5e0b4eb871f364a0d217f70f6c41d7fdc6f9f931fa1abbf222180c03d0ae410" +checksum = "cf8c76337a6ae9d73d50be168aeee974d05fdeda9129a413eaff719e3b7b5fea" dependencies = [ "bevy_app", "bevy_asset", + "bevy_camera", "bevy_color", "bevy_core_pipeline", "bevy_derive", "bevy_diagnostic", "bevy_ecs", "bevy_image", + "bevy_light", "bevy_math", + "bevy_mesh", "bevy_platform", "bevy_reflect", "bevy_render", + "bevy_shader", "bevy_transform", "bevy_utils", - "bevy_window", "bitflags 2.9.4", "bytemuck", "derive_more", "fixedbitset", "nonmax", "offset-allocator", - "radsort", "smallvec", "static_assertions", "thiserror 2.0.17", @@ -931,12 +1051,13 @@ dependencies = [ [[package]] name = "bevy_picking" -version = "0.16.1" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ed04757938655ed8094ea1efb533f99063a8b22abffc22010c694d291522850" +checksum = "3a232a8ea4dc9b83c08226f56b868acb1ead06946a95d8b9c8cbbcc860cd8090" dependencies = [ "bevy_app", "bevy_asset", + "bevy_camera", "bevy_derive", "bevy_ecs", "bevy_input", @@ -944,10 +1065,8 @@ dependencies = [ "bevy_mesh", "bevy_platform", "bevy_reflect", - "bevy_render", "bevy_time", "bevy_transform", - "bevy_utils", "bevy_window", "crossbeam-channel", "tracing", @@ -956,33 +1075,66 @@ dependencies = [ [[package]] name = "bevy_platform" -version = "0.16.1" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7573dc824a1b08b4c93fdbe421c53e1e8188e9ca1dd74a414455fe571facb47" +checksum = "10cf8cda162688c95250e74cffaa1c3a04597f105d4ca35554106f107308ea57" dependencies = [ - "cfg-if", "critical-section", - "foldhash", - "getrandom 0.2.16", - "hashbrown 0.15.5", + "foldhash 0.2.0", + "futures-channel", + "getrandom", + "hashbrown 0.16.0", + "js-sys", "portable-atomic", "portable-atomic-util", "serde", "spin", + "wasm-bindgen", + "wasm-bindgen-futures", "web-time", ] +[[package]] +name = "bevy_post_process" +version = "0.17.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26ee8ab6043f8bbe43e9c16bbdde0c5e7289b99e62cd8aad1a2a4166a7f2bce6" +dependencies = [ + "bevy_app", + "bevy_asset", + "bevy_camera", + "bevy_color", + "bevy_core_pipeline", + "bevy_derive", + "bevy_ecs", + "bevy_image", + "bevy_math", + "bevy_platform", + "bevy_reflect", + "bevy_render", + "bevy_shader", + "bevy_transform", + "bevy_utils", + "bevy_window", + "bitflags 2.9.4", + "nonmax", + "radsort", + "smallvec", + "thiserror 2.0.17", + "tracing", +] + [[package]] name = "bevy_ptr" -version = "0.16.1" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df7370d0e46b60e071917711d0860721f5347bc958bf325975ae6913a5dfcf01" +checksum = "28ab4074e7b781bab84e9b0a41ede245d673d1f75646ce0db27643aedcfb3a85" [[package]] name = "bevy_reflect" -version = "0.16.1" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daeb91a63a1a4df00aa58da8cc4ddbd4b9f16ab8bb647c5553eb156ce36fa8c2" +checksum = "333df3f5947b7e62728eb5c0b51d679716b16c7c5283118fed4563f13230954e" dependencies = [ "assert_type_match", "bevy_platform", @@ -991,10 +1143,11 @@ dependencies = [ "bevy_utils", "derive_more", "disqualified", - "downcast-rs", + "downcast-rs 2.0.2", "erased-serde", - "foldhash", + "foldhash 0.2.0", "glam", + "inventory", "petgraph", "serde", "smallvec", @@ -1007,11 +1160,12 @@ dependencies = [ [[package]] name = "bevy_reflect_derive" -version = "0.16.1" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ddadc55fe16b45faaa54ab2f9cb00548013c74812e8b018aa172387103cce6" +checksum = "0205dce9c5a4d8d041b263bcfd96e9d9d6f3d49416e12db347ab5778b3071fe1" dependencies = [ "bevy_macro_utils", + "indexmap", "proc-macro2", "quote", "syn", @@ -1020,13 +1174,14 @@ dependencies = [ [[package]] name = "bevy_render" -version = "0.16.1" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef91fed1f09405769214b99ebe4390d69c1af5cdd27967deae9135c550eb1667" +checksum = "70d6a5d47ebb247e4ecaaf4a3b0310b7c518728ff2362c69f4220d0d3228e17d" dependencies = [ "async-channel", "bevy_app", "bevy_asset", + "bevy_camera", "bevy_color", "bevy_derive", "bevy_diagnostic", @@ -1038,6 +1193,7 @@ dependencies = [ "bevy_platform", "bevy_reflect", "bevy_render_macros", + "bevy_shader", "bevy_tasks", "bevy_time", "bevy_transform", @@ -1045,22 +1201,17 @@ dependencies = [ "bevy_window", "bitflags 2.9.4", "bytemuck", - "codespan-reporting", "derive_more", - "downcast-rs", + "downcast-rs 2.0.2", "encase", "fixedbitset", - "futures-lite", "image", "indexmap", "js-sys", - "ktx2", "naga", - "naga_oil", "nonmax", "offset-allocator", "send_wrapper", - "serde", "smallvec", "thiserror 2.0.17", "tracing", @@ -1072,9 +1223,9 @@ dependencies = [ [[package]] name = "bevy_render_macros" -version = "0.16.1" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abd42cf6c875bcf38da859f8e731e119a6aff190d41dd0a1b6000ad57cf2ed3d" +checksum = "a7e8b553adf0a4f9f059c5c2dcb52d9ac09abede1c322a92b43b9f4bb11c3843" dependencies = [ "bevy_macro_utils", "proc-macro2", @@ -1084,17 +1235,17 @@ dependencies = [ [[package]] name = "bevy_scene" -version = "0.16.1" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c52ca165200995fe8afd2a1a6c03e4ffee49198a1d4653d32240ea7f217d4ab" +checksum = "e601ffeebbdaba1193f823dbdc9fc8787a24cf83225a72fee4def5c27a18778a" dependencies = [ "bevy_app", "bevy_asset", + "bevy_camera", "bevy_derive", "bevy_ecs", "bevy_platform", "bevy_reflect", - "bevy_render", "bevy_transform", "bevy_utils", "derive_more", @@ -1103,41 +1254,85 @@ dependencies = [ "uuid", ] +[[package]] +name = "bevy_shader" +version = "0.17.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cef8f8e53776d286eb62bb60164f30671f07005ff407e94ec1176e9426d1477" +dependencies = [ + "bevy_asset", + "bevy_platform", + "bevy_reflect", + "naga", + "naga_oil", + "serde", + "thiserror 2.0.17", + "tracing", + "wgpu-types", +] + [[package]] name = "bevy_sprite" -version = "0.16.1" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ccae7bab2cb956fb0434004c359e432a3a1a074a6ef4eb471f1fb099f0b620b" +checksum = "74bb52fa52caa1cc8d95acf45e52efc0c72b59755c2f0801a30fdab367921db0" dependencies = [ "bevy_app", "bevy_asset", + "bevy_camera", "bevy_color", - "bevy_core_pipeline", "bevy_derive", "bevy_ecs", "bevy_image", "bevy_math", + "bevy_mesh", "bevy_picking", + "bevy_reflect", + "bevy_text", + "bevy_transform", + "bevy_window", + "radsort", + "tracing", + "wgpu-types", +] + +[[package]] +name = "bevy_sprite_render" +version = "0.17.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31bb90a9139b04568bd30b2492ba61234092d95a7f7e3c84b55369b16d7e261b" +dependencies = [ + "bevy_app", + "bevy_asset", + "bevy_camera", + "bevy_color", + "bevy_core_pipeline", + "bevy_derive", + "bevy_ecs", + "bevy_image", + "bevy_math", + "bevy_mesh", "bevy_platform", "bevy_reflect", "bevy_render", + "bevy_shader", + "bevy_sprite", + "bevy_text", "bevy_transform", "bevy_utils", - "bevy_window", "bitflags 2.9.4", "bytemuck", "derive_more", "fixedbitset", "nonmax", - "radsort", "tracing", ] [[package]] name = "bevy_state" -version = "0.16.1" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "155d3cd97b900539008cdcaa702f88b724d94b08977b8e591a32536ce66faa8c" +checksum = "fe4e955f36cdc7b31556e4619a653dcf65d46967d90d36fb788f746c8e89257e" dependencies = [ "bevy_app", "bevy_ecs", @@ -1151,43 +1346,39 @@ dependencies = [ [[package]] name = "bevy_state_macros" -version = "0.16.1" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2481c1304fd2a1851a0d4cb63a1ce6421ae40f3f0117cbc9882963ee4c9bb609" +checksum = "5c3e4e32b1b96585740a2b447661af7db1b9d688db5e4d96da50461cd8f5ce63" dependencies = [ "bevy_macro_utils", - "proc-macro2", "quote", "syn", ] [[package]] name = "bevy_tasks" -version = "0.16.1" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b674242641cab680688fc3b850243b351c1af49d4f3417a576debd6cca8dcf5" +checksum = "18839182775f30d26f0f84d9de85d25361bb593c99517a80b64ede6cbaf41adc" dependencies = [ "async-channel", "async-executor", "async-task", "atomic-waker", "bevy_platform", - "cfg-if", "concurrent-queue", "crossbeam-queue", "derive_more", - "futures-channel", "futures-lite", "heapless", "pin-project", - "wasm-bindgen-futures", ] [[package]] name = "bevy_text" -version = "0.16.1" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d76c85366159f5f54110f33321c76d8429cfd8f39638f26793a305dae568b60" +checksum = "cc1b759cf2ed8992132bd541ebb9ffcfa777d2faf3596d418fb25984bc6677d8" dependencies = [ "bevy_app", "bevy_asset", @@ -1199,25 +1390,21 @@ dependencies = [ "bevy_math", "bevy_platform", "bevy_reflect", - "bevy_render", - "bevy_sprite", - "bevy_transform", "bevy_utils", - "bevy_window", "cosmic-text", "serde", "smallvec", "sys-locale", "thiserror 2.0.17", "tracing", - "unicode-bidi", + "wgpu-types", ] [[package]] name = "bevy_time" -version = "0.16.1" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc98eb356c75be04fbbc77bb3d8ffa24c8bacd99f76111cee23d444be6ac8c9c" +checksum = "1a52edd3d30ed94074f646ba1c9914e407af9abe5b6fb7a4322c855341a536cc" dependencies = [ "bevy_app", "bevy_ecs", @@ -1230,9 +1417,9 @@ dependencies = [ [[package]] name = "bevy_transform" -version = "0.16.1" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df218e440bb9a19058e1b80a68a031c887bcf7bd3a145b55f361359a2fa3100d" +checksum = "7995ae14430b1a268d1e4f098ab770e8af880d2df5e4e37161b47d8d9e9625bd" dependencies = [ "bevy_app", "bevy_ecs", @@ -1248,16 +1435,16 @@ dependencies = [ [[package]] name = "bevy_ui" -version = "0.16.1" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea4a4d2ba51865bc3039af29a26b4f52c48b54cc758369f52004caf4b6f03770" +checksum = "cc999815a67a6b2fc911df9eea27af703ff656aed6fd31d8606dced701f07fd6" dependencies = [ "accesskit", "bevy_a11y", "bevy_app", "bevy_asset", + "bevy_camera", "bevy_color", - "bevy_core_pipeline", "bevy_derive", "bevy_ecs", "bevy_image", @@ -1266,61 +1453,91 @@ dependencies = [ "bevy_picking", "bevy_platform", "bevy_reflect", - "bevy_render", "bevy_sprite", "bevy_text", "bevy_transform", "bevy_utils", "bevy_window", - "bytemuck", "derive_more", - "nonmax", "smallvec", "taffy", "thiserror 2.0.17", "tracing", + "uuid", +] + +[[package]] +name = "bevy_ui_render" +version = "0.17.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adae9770089e04339d003afe7abe7153fe71600d81c828f964c7ac329b04d5b9" +dependencies = [ + "bevy_app", + "bevy_asset", + "bevy_camera", + "bevy_color", + "bevy_core_pipeline", + "bevy_derive", + "bevy_ecs", + "bevy_image", + "bevy_math", + "bevy_mesh", + "bevy_platform", + "bevy_reflect", + "bevy_render", + "bevy_shader", + "bevy_sprite", + "bevy_sprite_render", + "bevy_text", + "bevy_transform", + "bevy_ui", + "bevy_utils", + "bytemuck", + "derive_more", + "tracing", ] [[package]] name = "bevy_utils" -version = "0.16.1" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94f7a8905a125d2017e8561beefb7f2f5e67e93ff6324f072ad87c5fd6ec3b99" +checksum = "080254083c74d5f6eb0649d7cd6181bda277e8fe3c509ec68990a5d56ec23f24" dependencies = [ "bevy_platform", + "disqualified", "thread_local", ] [[package]] name = "bevy_window" -version = "0.16.1" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df7e8ad0c17c3cc23ff5566ae2905c255e6986037fb041f74c446216f5c38431" +checksum = "f582478606d6b6e5c53befbe7612f038fdfb73f8a27f7aae644406637347acd4" dependencies = [ - "android-activity", "bevy_app", + "bevy_asset", "bevy_ecs", + "bevy_image", "bevy_input", "bevy_math", "bevy_platform", "bevy_reflect", - "bevy_utils", "log", "raw-window-handle", "serde", - "smol_str", ] [[package]] name = "bevy_winit" -version = "0.16.1" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a5e7f00c6b3b6823df5ec2a5e9067273607208919bc8c211773ebb9643c87f0" +checksum = "eb0ccf2faca4b4c156a26284d1bbf90a8cac8568a273adcd6c1a270c1342f3df" dependencies = [ "accesskit", "accesskit_winit", "approx", "bevy_a11y", + "bevy_android", "bevy_app", "bevy_asset", "bevy_derive", @@ -1333,37 +1550,14 @@ dependencies = [ "bevy_platform", "bevy_reflect", "bevy_tasks", - "bevy_utils", "bevy_window", "bytemuck", "cfg-if", - "crossbeam-channel", - "raw-window-handle", "tracing", "wasm-bindgen", - "web-sys", - "wgpu-types", - "winit", -] - -[[package]] -name = "bindgen" -version = "0.70.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f49d8fed880d473ea71efb9bf597651e77201bdd4893efe54c9e5d65ae04ce6f" -dependencies = [ - "bitflags 2.9.4", - "cexpr", - "clang-sys", - "itertools 0.13.0", - "log", - "prettyplease", - "proc-macro2", - "quote", - "regex", - "rustc-hash 1.1.0", - "shlex", - "syn", + "web-sys", + "wgpu-types", + "winit", ] [[package]] @@ -1384,30 +1578,15 @@ dependencies = [ "syn", ] -[[package]] -name = "bit-set" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" -dependencies = [ - "bit-vec 0.6.3", -] - [[package]] name = "bit-set" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" dependencies = [ - "bit-vec 0.8.0", + "bit-vec", ] -[[package]] -name = "bit-vec" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" - [[package]] name = "bit-vec" version = "0.8.0" @@ -1426,6 +1605,7 @@ version = "2.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394" dependencies = [ + "bytemuck", "serde", ] @@ -1454,7 +1634,16 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f" dependencies = [ - "objc2", + "objc2 0.5.2", +] + +[[package]] +name = "block2" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdeb9d870516001442e364c5220d3574d2da8dc765554b4a617230d33fa58ef5" +dependencies = [ + "objc2 0.6.3", ] [[package]] @@ -1528,6 +1717,18 @@ dependencies = [ "thiserror 1.0.69", ] +[[package]] +name = "calloop-wayland-source" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95a66a987056935f7efce4ab5668920b5d0dac4a7c99991a67395f13702ddd20" +dependencies = [ + "calloop", + "rustix 0.38.44", + "wayland-backend", + "wayland-client", +] + [[package]] name = "cbindgen" version = "0.29.0" @@ -1626,10 +1827,11 @@ checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" [[package]] name = "codespan-reporting" -version = "0.11.1" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +checksum = "fe6d2e5af09e8c8ad56c969f2157a3d4238cebc7c55f0a517728c38f7b200f81" dependencies = [ + "serde", "termcolor", "unicode-width", ] @@ -1740,7 +1942,7 @@ checksum = "c07782be35f9e1140080c6b96f0d44b739e2278479f64e02fdab4e32dfd8b081" dependencies = [ "bitflags 1.3.2", "core-foundation 0.9.4", - "core-graphics-types", + "core-graphics-types 0.1.3", "foreign-types", "libc", ] @@ -1756,6 +1958,17 @@ dependencies = [ "libc", ] +[[package]] +name = "core-graphics-types" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d44a101f213f6c4cdc1853d4b78aef6db6bdfa3468798cc1d9912f4735013eb" +dependencies = [ + "bitflags 2.9.4", + "core-foundation 0.10.1", + "libc", +] + [[package]] name = "coreaudio-rs" version = "0.11.3" @@ -1773,14 +1986,14 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ceec7a6067e62d6f931a2baf6f3a751f4a892595bcec1461a3c94ef9949864b6" dependencies = [ - "bindgen 0.72.1", + "bindgen", ] [[package]] name = "cosmic-text" -version = "0.13.2" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e418dd4f5128c3e93eab12246391c54a20c496811131f85754dc8152ee207892" +checksum = "da46a9d5a8905cc538a4a5bceb6a4510de7a51049c5588c0114efce102bcbbe8" dependencies = [ "bitflags 2.9.4", "fontdb", @@ -1898,18 +2111,18 @@ checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" [[package]] name = "derive_more" -version = "1.0.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05" +checksum = "093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678" dependencies = [ "derive_more-impl", ] [[package]] name = "derive_more-impl" -version = "1.0.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" +checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3" dependencies = [ "proc-macro2", "quote", @@ -1923,6 +2136,16 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" +[[package]] +name = "dispatch2" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec" +dependencies = [ + "bitflags 2.9.4", + "objc2 0.6.3", +] + [[package]] name = "disqualified" version = "1.0.0" @@ -1947,6 +2170,12 @@ dependencies = [ "litrs", ] +[[package]] +name = "downcast-rs" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" + [[package]] name = "downcast-rs" version = "2.0.2" @@ -1967,30 +2196,30 @@ checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" [[package]] name = "encase" -version = "0.10.0" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0a05902cf601ed11d564128448097b98ebe3c6574bd7b6a653a3d56d54aa020" +checksum = "02ba239319a4f60905966390f5e52799d868103a533bb7e27822792332504ddd" dependencies = [ "const_panic", "encase_derive", "glam", - "thiserror 1.0.69", + "thiserror 2.0.17", ] [[package]] name = "encase_derive" -version = "0.10.0" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "181d475b694e2dd56ae919ce7699d344d1fd259292d590c723a50d1189a2ea85" +checksum = "5223d6c647f09870553224f6e37261fe5567bc5a4f4cf13ed337476e79990f2f" dependencies = [ "encase_derive_impl", ] [[package]] name = "encase_derive_impl" -version = "0.10.0" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f97b51c5cc57ef7c5f7a0c57c250251c49ee4c28f819f87ac32f4aceabc36792" +checksum = "1796db3d892515842ca2dfb11124c4bb4a9e58d9f2c5c1072e5bca1b2334507b" dependencies = [ "proc-macro2", "quote", @@ -2111,6 +2340,12 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + [[package]] name = "font-types" version = "0.10.0" @@ -2211,20 +2446,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bd49230192a3797a9a4d6abe9b3eed6f7fa4c8a8a4947977c6f80025f92cbd8" dependencies = [ "rustix 1.1.2", - "windows-link", -] - -[[package]] -name = "getrandom" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" -dependencies = [ - "cfg-if", - "js-sys", - "libc", - "wasi", - "wasm-bindgen", + "windows-link 0.2.1", ] [[package]] @@ -2234,9 +2456,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", + "js-sys", "libc", "r-efi", "wasip2", + "wasm-bindgen", ] [[package]] @@ -2286,14 +2510,14 @@ dependencies = [ [[package]] name = "glam" -version = "0.29.3" +version = "0.30.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8babf46d4c1c9d92deac9f7be466f76dfc4482b6452fc5024b5e8daf6ffeb3ee" +checksum = "e12d847aeb25f41be4c0ec9587d624e9cd631bc007a8fd7ce3f5851e064c6460" dependencies = [ "bytemuck", "libm", "rand", - "serde", + "serde_core", ] [[package]] @@ -2434,6 +2658,7 @@ checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" dependencies = [ "cfg-if", "crunchy", + "num-traits", "zerocopy", ] @@ -2452,9 +2677,7 @@ version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" dependencies = [ - "equivalent", - "foldhash", - "serde", + "foldhash 0.1.5", ] [[package]] @@ -2462,6 +2685,10 @@ name = "hashbrown" version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" +dependencies = [ + "equivalent", + "serde", +] [[package]] name = "heapless" @@ -2488,9 +2715,9 @@ checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" [[package]] name = "hexasphere" -version = "15.1.0" +version = "16.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9c9e718d32b6e6b2b32354e1b0367025efdd0b11d6a740b905ddf5db1074679" +checksum = "29a164ceff4500f2a72b1d21beaa8aa8ad83aec2b641844c659b190cb3ea2e0b" dependencies = [ "constgebra", "glam", @@ -2516,15 +2743,6 @@ dependencies = [ "png", ] -[[package]] -name = "immutable-chunkmap" -version = "2.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3e98b1520e49e252237edc238a39869da9f3241f2ec19dc788c1d24694d1e4" -dependencies = [ - "arrayvec", -] - [[package]] name = "indexmap" version = "2.11.4" @@ -2563,6 +2781,15 @@ dependencies = [ "libc", ] +[[package]] +name = "inventory" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc61209c082fbeb19919bee74b176221b27223e27b65d781eb91af24eb1fb46e" +dependencies = [ + "rustversion", +] + [[package]] name = "io-kit-sys" version = "0.4.1" @@ -2631,7 +2858,7 @@ version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" dependencies = [ - "getrandom 0.3.4", + "getrandom", "libc", ] @@ -2664,11 +2891,11 @@ checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" [[package]] name = "ktx2" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87d65e08a9ec02e409d27a0139eaa6b9756b4d81fe7cde71f6941a83730ce838" +checksum = "ff7f53bdf698e7aa7ec916411bbdc8078135da11b66db5182675b2227f6c0d07" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.9.4", ] [[package]] @@ -2701,7 +2928,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" dependencies = [ "cfg-if", - "windows-link", + "windows-link 0.2.1", ] [[package]] @@ -2808,13 +3035,13 @@ dependencies = [ [[package]] name = "metal" -version = "0.31.0" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f569fb946490b5743ad69813cb19629130ce9374034abe31614a36402d18f99e" +checksum = "00c15a6f673ff72ddcc22394663290f870fb224c1bfce55734a75c414150e605" dependencies = [ "bitflags 2.9.4", "block", - "core-graphics-types", + "core-graphics-types 0.2.0", "foreign-types", "log", "objc", @@ -2849,43 +3076,44 @@ dependencies = [ [[package]] name = "naga" -version = "24.0.0" +version = "26.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e380993072e52eef724eddfcde0ed013b0c023c3f0417336ed041aa9f076994e" +checksum = "916cbc7cb27db60be930a4e2da243cf4bc39569195f22fd8ee419cd31d5b662c" dependencies = [ "arrayvec", - "bit-set 0.8.0", + "bit-set", "bitflags 2.9.4", + "cfg-if", "cfg_aliases", "codespan-reporting", + "half", + "hashbrown 0.15.5", "hexf-parse", "indexmap", + "libm", "log", + "num-traits", + "once_cell", "pp-rs", "rustc-hash 1.1.0", "spirv", - "strum", - "termcolor", "thiserror 2.0.17", - "unicode-xid", + "unicode-ident", ] [[package]] name = "naga_oil" -version = "0.17.1" +version = "0.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2464f7395decfd16bb4c33fb0cb3b2c645cc60d051bc7fb652d3720bfb20f18" +checksum = "1b586d3cf5c9b7e13fe2af6e114406ff70773fd80881960378933b63e76f37dd" dependencies = [ - "bit-set 0.5.3", "codespan-reporting", "data-encoding", "indexmap", "naga", - "once_cell", "regex", - "regex-syntax", "rustc-hash 1.1.0", - "thiserror 1.0.69", + "thiserror 2.0.17", "tracing", "unicode-ident", ] @@ -3057,6 +3285,15 @@ dependencies = [ "objc2-encode", ] +[[package]] +name = "objc2" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c2599ce0ec54857b29ce62166b0ed9b4f6f1a70ccc9a71165b6154caca8c05" +dependencies = [ + "objc2-encode", +] + [[package]] name = "objc2-app-kit" version = "0.2.2" @@ -3064,13 +3301,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" dependencies = [ "bitflags 2.9.4", - "block2", + "block2 0.5.1", + "libc", + "objc2 0.5.2", + "objc2-core-data 0.2.2", + "objc2-core-image 0.2.2", + "objc2-foundation 0.2.2", + "objc2-quartz-core 0.2.2", +] + +[[package]] +name = "objc2-app-kit" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d49e936b501e5c5bf01fda3a9452ff86dc3ea98ad5f283e1455153142d97518c" +dependencies = [ + "bitflags 2.9.4", + "block2 0.6.2", "libc", - "objc2", - "objc2-core-data", - "objc2-core-image", - "objc2-foundation", - "objc2-quartz-core", + "objc2 0.6.3", + "objc2-cloud-kit 0.3.2", + "objc2-core-data 0.3.2", + "objc2-core-foundation", + "objc2-core-graphics", + "objc2-core-image 0.3.2", + "objc2-core-text", + "objc2-core-video", + "objc2-foundation 0.3.2", + "objc2-quartz-core 0.3.2", ] [[package]] @@ -3080,10 +3338,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009" dependencies = [ "bitflags 2.9.4", - "block2", - "objc2", + "block2 0.5.1", + "objc2 0.5.2", "objc2-core-location", - "objc2-foundation", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-cloud-kit" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73ad74d880bb43877038da939b7427bba67e9dd42004a18b809ba7d87cee241c" +dependencies = [ + "bitflags 2.9.4", + "objc2 0.6.3", + "objc2-foundation 0.3.2", ] [[package]] @@ -3092,9 +3361,9 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a5ff520e9c33812fd374d8deecef01d4a840e7b41862d849513de77e44aa4889" dependencies = [ - "block2", - "objc2", - "objc2-foundation", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation 0.2.2", ] [[package]] @@ -3104,9 +3373,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" dependencies = [ "bitflags 2.9.4", - "block2", - "objc2", - "objc2-foundation", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-core-data" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b402a653efbb5e82ce4df10683b6b28027616a2715e90009947d50b8dd298fa" +dependencies = [ + "bitflags 2.9.4", + "objc2 0.6.3", + "objc2-foundation 0.3.2", ] [[package]] @@ -3116,6 +3396,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" dependencies = [ "bitflags 2.9.4", + "dispatch2", + "objc2 0.6.3", +] + +[[package]] +name = "objc2-core-graphics" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e022c9d066895efa1345f8e33e584b9f958da2fd4cd116792e15e07e4720a807" +dependencies = [ + "bitflags 2.9.4", + "dispatch2", + "objc2 0.6.3", + "objc2-core-foundation", + "objc2-io-surface", ] [[package]] @@ -3124,22 +3419,57 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80" dependencies = [ - "block2", - "objc2", - "objc2-foundation", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation 0.2.2", "objc2-metal", ] +[[package]] +name = "objc2-core-image" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5d563b38d2b97209f8e861173de434bd0214cf020e3423a52624cd1d989f006" +dependencies = [ + "objc2 0.6.3", + "objc2-foundation 0.3.2", +] + [[package]] name = "objc2-core-location" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "000cfee34e683244f284252ee206a27953279d370e309649dc3ee317b37e5781" dependencies = [ - "block2", - "objc2", + "block2 0.5.1", + "objc2 0.5.2", "objc2-contacts", - "objc2-foundation", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-core-text" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cde0dfb48d25d2b4862161a4d5fcc0e3c24367869ad306b0c9ec0073bfed92d" +dependencies = [ + "bitflags 2.9.4", + "objc2 0.6.3", + "objc2-core-foundation", + "objc2-core-graphics", +] + +[[package]] +name = "objc2-core-video" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d425caf1df73233f29fd8a5c3e5edbc30d2d4307870f802d18f00d83dc5141a6" +dependencies = [ + "bitflags 2.9.4", + "objc2 0.6.3", + "objc2-core-foundation", + "objc2-core-graphics", + "objc2-io-surface", ] [[package]] @@ -3155,10 +3485,42 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" dependencies = [ "bitflags 2.9.4", - "block2", + "block2 0.5.1", "dispatch", "libc", - "objc2", + "objc2 0.5.2", +] + +[[package]] +name = "objc2-foundation" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272" +dependencies = [ + "bitflags 2.9.4", + "objc2 0.6.3", + "objc2-core-foundation", +] + +[[package]] +name = "objc2-io-kit" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33fafba39597d6dc1fb709123dfa8289d39406734be322956a69f0931c73bb15" +dependencies = [ + "libc", + "objc2-core-foundation", +] + +[[package]] +name = "objc2-io-surface" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180788110936d59bab6bd83b6060ffdfffb3b922ba1396b312ae795e1de9d81d" +dependencies = [ + "bitflags 2.9.4", + "objc2 0.6.3", + "objc2-core-foundation", ] [[package]] @@ -3167,10 +3529,10 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1a1ae721c5e35be65f01a03b6d2ac13a54cb4fa70d8a5da293d7b0020261398" dependencies = [ - "block2", - "objc2", - "objc2-app-kit", - "objc2-foundation", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-app-kit 0.2.2", + "objc2-foundation 0.2.2", ] [[package]] @@ -3180,9 +3542,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" dependencies = [ "bitflags 2.9.4", - "block2", - "objc2", - "objc2-foundation", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation 0.2.2", ] [[package]] @@ -3192,20 +3554,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" dependencies = [ "bitflags 2.9.4", - "block2", - "objc2", - "objc2-foundation", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation 0.2.2", "objc2-metal", ] +[[package]] +name = "objc2-quartz-core" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96c1358452b371bf9f104e21ec536d37a650eb10f7ee379fff67d2e08d537f1f" +dependencies = [ + "bitflags 2.9.4", + "objc2 0.6.3", + "objc2-foundation 0.3.2", +] + [[package]] name = "objc2-symbols" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0a684efe3dec1b305badae1a28f6555f6ddd3bb2c2267896782858d5a78404dc" dependencies = [ - "objc2", - "objc2-foundation", + "objc2 0.5.2", + "objc2-foundation 0.2.2", ] [[package]] @@ -3215,15 +3588,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f" dependencies = [ "bitflags 2.9.4", - "block2", - "objc2", - "objc2-cloud-kit", - "objc2-core-data", - "objc2-core-image", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-cloud-kit 0.2.2", + "objc2-core-data 0.2.2", + "objc2-core-image 0.2.2", "objc2-core-location", - "objc2-foundation", + "objc2-foundation 0.2.2", "objc2-link-presentation", - "objc2-quartz-core", + "objc2-quartz-core 0.2.2", "objc2-symbols", "objc2-uniform-type-identifiers", "objc2-user-notifications", @@ -3235,9 +3608,9 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44fa5f9748dbfe1ca6c0b79ad20725a11eca7c2218bceb4b005cb1be26273bfe" dependencies = [ - "block2", - "objc2", - "objc2-foundation", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation 0.2.2", ] [[package]] @@ -3247,10 +3620,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3" dependencies = [ "bitflags 2.9.4", - "block2", - "objc2", + "block2 0.5.1", + "objc2 0.5.2", "objc2-core-location", - "objc2-foundation", + "objc2-foundation 0.2.2", ] [[package]] @@ -3325,6 +3698,15 @@ dependencies = [ "num-traits", ] +[[package]] +name = "owned_ttf_parser" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36820e9051aca1014ddc75770aab4d68bc1e9e632f0f5627c4086bc216fb583b" +dependencies = [ + "ttf-parser 0.25.1", +] + [[package]] name = "parking" version = "2.2.1" @@ -3351,7 +3733,7 @@ dependencies = [ "libc", "redox_syscall 0.5.18", "smallvec", - "windows-link", + "windows-link 0.2.1", ] [[package]] @@ -3368,11 +3750,12 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "petgraph" -version = "0.7.1" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3672b37090dbd86368a4145bc067582552b29c27377cad4e0a306c97f9bd7772" +checksum = "8701b58ea97060d5e5b155d383a69952a60943f0e6dfe30b04c287beb0b27455" dependencies = [ "fixedbitset", + "hashbrown 0.15.5", "indexmap", "serde", "serde_derive", @@ -3487,16 +3870,6 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8cf8e6a8aa66ce33f63993ffc4ea4271eb5b0530a9002db8455ea6050c77bfa" -[[package]] -name = "prettyplease" -version = "0.2.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" -dependencies = [ - "proc-macro2", - "syn", -] - [[package]] name = "proc-macro-crate" version = "3.4.0" @@ -3530,6 +3903,15 @@ dependencies = [ "num-traits", ] +[[package]] +name = "quick-xml" +version = "0.37.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "331e97a1af0bf59823e6eadffe373d7b27f485be8748f71471c662c1f269b7fb" +dependencies = [ + "memchr", +] + [[package]] name = "quote" version = "1.0.41" @@ -3553,20 +3935,19 @@ checksum = "019b4b213425016d7d84a153c4c73afb0946fbb4840e4eece7ba8848b9d6da22" [[package]] name = "rand" -version = "0.8.5" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" dependencies = [ - "libc", "rand_chacha", "rand_core", ] [[package]] name = "rand_chacha" -version = "0.3.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" dependencies = [ "ppv-lite86", "rand_core", @@ -3574,18 +3955,18 @@ dependencies = [ [[package]] name = "rand_core" -version = "0.6.4" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" dependencies = [ - "getrandom 0.2.16", + "getrandom", ] [[package]] name = "rand_distr" -version = "0.4.3" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31" +checksum = "6a8615d50dcf34fa31f7ab52692afec947c4dd0ab803cc87cb3b0b4570ff7463" dependencies = [ "num-traits", "rand", @@ -3683,6 +4064,9 @@ name = "renderer" version = "0.1.0" dependencies = [ "bevy", + "objc2 0.6.3", + "objc2-app-kit 0.3.2", + "raw-window-handle", "thiserror 2.0.17", "tracing", "tracing-subscriber", @@ -3700,14 +4084,15 @@ dependencies = [ [[package]] name = "ron" -version = "0.8.1" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94" +checksum = "beceb6f7bf81c73e73aeef6dd1356d9a1b2b4909e1f0fc3e59b034f9572d7b7f" dependencies = [ - "base64 0.21.7", + "base64", "bitflags 2.9.4", "serde", "serde_derive", + "unicode-ident", ] [[package]] @@ -3801,11 +4186,30 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + [[package]] name = "scopeguard" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "sctk-adwaita" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6277f0217056f77f1d8f49f2950ac6c278c0d607c45f5ee99328d792ede24ec" +dependencies = [ + "ab_glyph", + "log", + "memmap2", + "smithay-client-toolkit", + "tiny-skia", +] [[package]] name = "self_cell" @@ -3923,6 +4327,31 @@ version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +[[package]] +name = "smithay-client-toolkit" +version = "0.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3457dea1f0eb631b4034d61d4d8c32074caa6cd1ab2d59f2327bd8461e2c0016" +dependencies = [ + "bitflags 2.9.4", + "calloop", + "calloop-wayland-source", + "cursor-icon", + "libc", + "log", + "memmap2", + "rustix 0.38.44", + "thiserror 1.0.69", + "wayland-backend", + "wayland-client", + "wayland-csd-frame", + "wayland-cursor", + "wayland-protocols", + "wayland-protocols-wlr", + "wayland-scanner", + "xkeysym", +] + [[package]] name = "smol_str" version = "0.2.2" @@ -3934,9 +4363,9 @@ dependencies = [ [[package]] name = "spin" -version = "0.9.8" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +checksum = "d5fe4ccb98d9c292d56fec89a5e07da7fc4cf0dc11e156b41793132775d3e591" dependencies = [ "portable-atomic", ] @@ -3969,32 +4398,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] -name = "strsim" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" - -[[package]] -name = "strum" -version = "0.26.3" +name = "strict-num" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" -dependencies = [ - "strum_macros", -] +checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731" [[package]] -name = "strum_macros" -version = "0.26.4" +name = "strsim" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "rustversion", - "syn", -] +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "svg_fmt" @@ -4035,15 +4448,16 @@ dependencies = [ [[package]] name = "sysinfo" -version = "0.34.2" +version = "0.37.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4b93974b3d3aeaa036504b8eefd4c039dced109171c1ae973f1dc63b2c7e4b2" +checksum = "16607d5caffd1c07ce073528f9ed972d88db15dd44023fa57142963be3feb11f" dependencies = [ "libc", "memchr", "ntapi", "objc2-core-foundation", - "windows 0.57.0", + "objc2-io-kit", + "windows 0.61.3", ] [[package]] @@ -4065,7 +4479,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" dependencies = [ "fastrand", - "getrandom 0.3.4", + "getrandom", "once_cell", "rustix 1.1.2", "windows-sys 0.61.2", @@ -4129,6 +4543,31 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "tiny-skia" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83d13394d44dae3207b52a326c0c85a8bf87f1541f23b0d143811088497b09ab" +dependencies = [ + "arrayref", + "arrayvec", + "bytemuck", + "cfg-if", + "log", + "tiny-skia-path", +] + +[[package]] +name = "tiny-skia-path" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c9e7fc0c2e86a30b117d0462aa261b72b7a99b7ebd7deb3a14ceda95c5bdc93" +dependencies = [ + "arrayref", + "bytemuck", + "strict-num", +] + [[package]] name = "tinyvec" version = "1.10.0" @@ -4260,15 +4699,12 @@ dependencies = [ [[package]] name = "tracing-oslog" -version = "0.2.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "528bdd1f0e27b5dd9a4ededf154e824b0532731e4af73bb531de46276e0aab1e" +checksum = "d76902d2a8d5f9f55a81155c08971734071968c90f2d9bfe645fe700579b2950" dependencies = [ - "bindgen 0.70.1", "cc", "cfg-if", - "once_cell", - "parking_lot", "tracing-core", "tracing-subscriber", ] @@ -4314,6 +4750,12 @@ version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c591d83f69777866b9126b24c6dd9a18351f177e49d625920d19f989fd31cf8" +[[package]] +name = "ttf-parser" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2df906b07856748fa3f6e0ad0cbaa047052d4a7dd609e231c4f72cee8c36f31" + [[package]] name = "twox-hash" version = "2.1.2" @@ -4404,7 +4846,7 @@ version = "1.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2" dependencies = [ - "getrandom 0.3.4", + "getrandom", "js-sys", "serde", "wasm-bindgen", @@ -4449,12 +4891,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "wasi" -version = "0.11.1+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" - [[package]] name = "wasip2" version = "1.0.1+wasi-0.2.4" @@ -4536,6 +4972,114 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "wayland-backend" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "673a33c33048a5ade91a6b139580fa174e19fb0d23f396dca9fa15f2e1e49b35" +dependencies = [ + "cc", + "downcast-rs 1.2.1", + "rustix 1.1.2", + "scoped-tls", + "smallvec", + "wayland-sys", +] + +[[package]] +name = "wayland-client" +version = "0.31.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c66a47e840dc20793f2264eb4b3e4ecb4b75d91c0dd4af04b456128e0bdd449d" +dependencies = [ + "bitflags 2.9.4", + "rustix 1.1.2", + "wayland-backend", + "wayland-scanner", +] + +[[package]] +name = "wayland-csd-frame" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "625c5029dbd43d25e6aa9615e88b829a5cad13b2819c4ae129fdbb7c31ab4c7e" +dependencies = [ + "bitflags 2.9.4", + "cursor-icon", + "wayland-backend", +] + +[[package]] +name = "wayland-cursor" +version = "0.31.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "447ccc440a881271b19e9989f75726d60faa09b95b0200a9b7eb5cc47c3eeb29" +dependencies = [ + "rustix 1.1.2", + "wayland-client", + "xcursor", +] + +[[package]] +name = "wayland-protocols" +version = "0.32.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efa790ed75fbfd71283bd2521a1cfdc022aabcc28bdcff00851f9e4ae88d9901" +dependencies = [ + "bitflags 2.9.4", + "wayland-backend", + "wayland-client", + "wayland-scanner", +] + +[[package]] +name = "wayland-protocols-plasma" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a07a14257c077ab3279987c4f8bb987851bf57081b93710381daea94f2c2c032" +dependencies = [ + "bitflags 2.9.4", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-scanner", +] + +[[package]] +name = "wayland-protocols-wlr" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efd94963ed43cf9938a090ca4f7da58eb55325ec8200c3848963e98dc25b78ec" +dependencies = [ + "bitflags 2.9.4", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-scanner", +] + +[[package]] +name = "wayland-scanner" +version = "0.31.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54cb1e9dc49da91950bdfd8b848c49330536d9d1fb03d4bfec8cae50caa50ae3" +dependencies = [ + "proc-macro2", + "quick-xml", + "quote", +] + +[[package]] +name = "wayland-sys" +version = "0.31.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34949b42822155826b41db8e5d0c1be3a2bd296c747577a43a3e6daefc296142" +dependencies = [ + "dlib", + "log", + "pkg-config", +] + [[package]] name = "web-sys" version = "0.3.81" @@ -4558,24 +5102,25 @@ dependencies = [ [[package]] name = "wgpu" -version = "24.0.5" +version = "26.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b0b3436f0729f6cdf2e6e9201f3d39dc95813fad61d826c1ed07918b4539353" +checksum = "70b6ff82bbf6e9206828e1a3178e851f8c20f1c9028e74dd3a8090741ccd5798" dependencies = [ "arrayvec", "bitflags 2.9.4", + "cfg-if", "cfg_aliases", "document-features", + "hashbrown 0.15.5", "js-sys", "log", "naga", - "parking_lot", + "portable-atomic", "profiling", "raw-window-handle", "smallvec", "static_assertions", "wasm-bindgen", - "wasm-bindgen-futures", "web-sys", "wgpu-core", "wgpu-hal", @@ -4584,49 +5129,84 @@ dependencies = [ [[package]] name = "wgpu-core" -version = "24.0.5" +version = "26.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f0aa306497a238d169b9dc70659105b4a096859a34894544ca81719242e1499" +checksum = "d5f62f1053bd28c2268f42916f31588f81f64796e2ff91b81293515017ca8bd9" dependencies = [ "arrayvec", - "bit-vec 0.8.0", + "bit-set", + "bit-vec", "bitflags 2.9.4", "cfg_aliases", "document-features", + "hashbrown 0.15.5", "indexmap", "log", "naga", "once_cell", "parking_lot", + "portable-atomic", "profiling", "raw-window-handle", "rustc-hash 1.1.0", "smallvec", "thiserror 2.0.17", + "wgpu-core-deps-apple", + "wgpu-core-deps-wasm", + "wgpu-core-deps-windows-linux-android", "wgpu-hal", "wgpu-types", ] +[[package]] +name = "wgpu-core-deps-apple" +version = "26.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18ae5fbde6a4cbebae38358aa73fcd6e0f15c6144b67ef5dc91ded0db125dbdf" +dependencies = [ + "wgpu-hal", +] + +[[package]] +name = "wgpu-core-deps-wasm" +version = "26.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c03b9f9e1a50686d315fc6debe4980cc45cd37b0e919351917df494e8fdc8885" +dependencies = [ + "wgpu-hal", +] + +[[package]] +name = "wgpu-core-deps-windows-linux-android" +version = "26.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "720a5cb9d12b3d337c15ff0e24d3e97ed11490ff3f7506e7f3d98c68fa5d6f14" +dependencies = [ + "wgpu-hal", +] + [[package]] name = "wgpu-hal" -version = "24.0.4" +version = "26.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f112f464674ca69f3533248508ee30cb84c67cf06c25ff6800685f5e0294e259" +checksum = "7df2c64ac282a91ad7662c90bc4a77d4a2135bc0b2a2da5a4d4e267afc034b9e" dependencies = [ "android_system_properties", "arrayvec", "ash", - "bit-set 0.8.0", + "bit-set", "bitflags 2.9.4", "block", "bytemuck", + "cfg-if", "cfg_aliases", - "core-graphics-types", + "core-graphics-types 0.2.0", "glow", "glutin_wgl_sys", "gpu-alloc", "gpu-allocator", "gpu-descriptor", + "hashbrown 0.15.5", "js-sys", "khronos-egl", "libc", @@ -4634,16 +5214,16 @@ dependencies = [ "log", "metal", "naga", - "ndk-sys 0.5.0+25.2.9519653", + "ndk-sys 0.6.0+11769913", "objc", - "once_cell", "ordered-float", "parking_lot", + "portable-atomic", + "portable-atomic-util", "profiling", "range-alloc", "raw-window-handle", "renderdoc-sys", - "rustc-hash 1.1.0", "smallvec", "thiserror 2.0.17", "wasm-bindgen", @@ -4655,14 +5235,16 @@ dependencies = [ [[package]] name = "wgpu-types" -version = "24.0.0" +version = "26.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50ac044c0e76c03a0378e7786ac505d010a873665e2d51383dcff8dd227dc69c" +checksum = "eca7a8d8af57c18f57d393601a1fb159ace8b2328f1b6b5f80893f7d672c9ae2" dependencies = [ "bitflags 2.9.4", + "bytemuck", "js-sys", "log", "serde", + "thiserror 2.0.17", "web-sys", ] @@ -4709,22 +5291,25 @@ dependencies = [ [[package]] name = "windows" -version = "0.57.0" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12342cb4d8e3b046f3d80effd474a7a02447231330ef77d71daa6fbc40681143" +checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" dependencies = [ - "windows-core 0.57.0", + "windows-core 0.58.0", "windows-targets 0.52.6", ] [[package]] name = "windows" -version = "0.58.0" +version = "0.61.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" +checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893" dependencies = [ - "windows-core 0.58.0", - "windows-targets 0.52.6", + "windows-collections 0.2.0", + "windows-core 0.61.2", + "windows-future 0.2.1", + "windows-link 0.1.3", + "windows-numerics 0.2.0", ] [[package]] @@ -4733,39 +5318,36 @@ version = "0.62.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "527fadee13e0c05939a6a05d5bd6eec6cd2e3dbd648b9f8e447c6518133d8580" dependencies = [ - "windows-collections", + "windows-collections 0.3.2", "windows-core 0.62.2", - "windows-future", - "windows-numerics", + "windows-future 0.3.2", + "windows-numerics 0.3.1", ] [[package]] name = "windows-collections" -version = "0.3.2" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23b2d95af1a8a14a3c7367e1ed4fc9c20e0a26e79551b1454d72583c97cc6610" +checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8" dependencies = [ - "windows-core 0.62.2", + "windows-core 0.61.2", ] [[package]] -name = "windows-core" -version = "0.54.0" +name = "windows-collections" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12661b9c89351d684a50a8a643ce5f608e20243b9fb84687800163429f161d65" +checksum = "23b2d95af1a8a14a3c7367e1ed4fc9c20e0a26e79551b1454d72583c97cc6610" dependencies = [ - "windows-result 0.1.2", - "windows-targets 0.52.6", + "windows-core 0.62.2", ] [[package]] name = "windows-core" -version = "0.57.0" +version = "0.54.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2ed2439a290666cd67ecce2b0ffaad89c2a56b976b736e6ece670297897832d" +checksum = "12661b9c89351d684a50a8a643ce5f608e20243b9fb84687800163429f161d65" dependencies = [ - "windows-implement 0.57.0", - "windows-interface 0.57.0", "windows-result 0.1.2", "windows-targets 0.52.6", ] @@ -4783,6 +5365,19 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-core" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" +dependencies = [ + "windows-implement 0.60.2", + "windows-interface 0.59.3", + "windows-link 0.1.3", + "windows-result 0.3.4", + "windows-strings 0.4.2", +] + [[package]] name = "windows-core" version = "0.62.2" @@ -4791,31 +5386,31 @@ checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" dependencies = [ "windows-implement 0.60.2", "windows-interface 0.59.3", - "windows-link", + "windows-link 0.2.1", "windows-result 0.4.1", "windows-strings 0.5.1", ] [[package]] name = "windows-future" -version = "0.3.2" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1d6f90251fe18a279739e78025bd6ddc52a7e22f921070ccdc67dde84c605cb" +checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e" dependencies = [ - "windows-core 0.62.2", - "windows-link", - "windows-threading", + "windows-core 0.61.2", + "windows-link 0.1.3", + "windows-threading 0.1.0", ] [[package]] -name = "windows-implement" -version = "0.57.0" +name = "windows-future" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7" +checksum = "e1d6f90251fe18a279739e78025bd6ddc52a7e22f921070ccdc67dde84c605cb" dependencies = [ - "proc-macro2", - "quote", - "syn", + "windows-core 0.62.2", + "windows-link 0.2.1", + "windows-threading 0.2.1", ] [[package]] @@ -4840,17 +5435,6 @@ dependencies = [ "syn", ] -[[package]] -name = "windows-interface" -version = "0.57.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "windows-interface" version = "0.58.0" @@ -4873,12 +5457,28 @@ dependencies = [ "syn", ] +[[package]] +name = "windows-link" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" + [[package]] name = "windows-link" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" +[[package]] +name = "windows-numerics" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1" +dependencies = [ + "windows-core 0.61.2", + "windows-link 0.1.3", +] + [[package]] name = "windows-numerics" version = "0.3.1" @@ -4886,7 +5486,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e2e40844ac143cdb44aead537bbf727de9b044e107a0f1220392177d15b0f26" dependencies = [ "windows-core 0.62.2", - "windows-link", + "windows-link 0.2.1", ] [[package]] @@ -4907,13 +5507,22 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-result" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" +dependencies = [ + "windows-link 0.1.3", +] + [[package]] name = "windows-result" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" dependencies = [ - "windows-link", + "windows-link 0.2.1", ] [[package]] @@ -4926,13 +5535,22 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-strings" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" +dependencies = [ + "windows-link 0.1.3", +] + [[package]] name = "windows-strings" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" dependencies = [ - "windows-link", + "windows-link 0.2.1", ] [[package]] @@ -4977,7 +5595,7 @@ version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" dependencies = [ - "windows-link", + "windows-link 0.2.1", ] [[package]] @@ -5017,7 +5635,7 @@ version = "0.53.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" dependencies = [ - "windows-link", + "windows-link 0.2.1", "windows_aarch64_gnullvm 0.53.1", "windows_aarch64_msvc 0.53.1", "windows_i686_gnu 0.53.1", @@ -5028,13 +5646,22 @@ dependencies = [ "windows_x86_64_msvc 0.53.1", ] +[[package]] +name = "windows-threading" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6" +dependencies = [ + "windows-link 0.1.3", +] + [[package]] name = "windows-threading" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3949bd5b99cafdf1c7ca86b43ca564028dfe27d66958f2470940f73d86d75b37" dependencies = [ - "windows-link", + "windows-link 0.2.1", ] [[package]] @@ -5181,10 +5808,11 @@ version = "0.30.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c66d4b9ed69c4009f6321f762d6e61ad8a2389cd431b97cb1e146812e9e6c732" dependencies = [ + "ahash", "android-activity", "atomic-waker", "bitflags 2.9.4", - "block2", + "block2 0.5.1", "bytemuck", "calloop", "cfg_aliases", @@ -5195,10 +5823,11 @@ dependencies = [ "dpi", "js-sys", "libc", + "memmap2", "ndk 0.9.0", - "objc2", - "objc2-app-kit", - "objc2-foundation", + "objc2 0.5.2", + "objc2-app-kit 0.2.2", + "objc2-foundation 0.2.2", "objc2-ui-kit", "orbclient", "percent-encoding", @@ -5206,11 +5835,17 @@ dependencies = [ "raw-window-handle", "redox_syscall 0.4.1", "rustix 0.38.44", + "sctk-adwaita", + "smithay-client-toolkit", "smol_str", "tracing", "unicode-segmentation", "wasm-bindgen", "wasm-bindgen-futures", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-protocols-plasma", "web-sys", "web-time", "windows-sys 0.52.0", @@ -5266,6 +5901,12 @@ version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea6fc2961e4ef194dcbfe56bb845534d0dc8098940c7e5c012a258bfec6701bd" +[[package]] +name = "xcursor" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bec9e4a500ca8864c5b47b8b482a73d62e4237670e5b5f1d6b9e3cae50f28f2b" + [[package]] name = "xkbcommon-dl" version = "0.4.2" diff --git a/libProcessing/ffi/src/error.rs b/libProcessing/ffi/src/error.rs index 0de41a3a2..1f235580e 100644 --- a/libProcessing/ffi/src/error.rs +++ b/libProcessing/ffi/src/error.rs @@ -1,6 +1,7 @@ -use std::cell::RefCell; -use std::ffi::{c_char, CString}; use renderer::error::ProcessingError; +use std::cell::RefCell; +use std::ffi::{CString, c_char}; +use std::panic; thread_local! { static LAST_ERROR: RefCell> = RefCell::new(None); @@ -34,16 +35,28 @@ pub fn clear_error() { }); } - /// Check the result of an operation, setting the last error if there was one. -pub fn check(result: Result) -> Option { - match result { - Ok(value) => { - Some(value) - } +pub fn check(f: F) -> Option +where + F: FnOnce() -> Result + panic::UnwindSafe, +{ + // we'll catch panics here to prevent unwinding across the FFI boundary + panic::catch_unwind(|| match f() { + Ok(value) => Some(value), Err(err) => { set_error(&err.to_string()); None } - } -} \ No newline at end of file + }) + .unwrap_or_else(|e| { + let msg = if let Some(s) = e.downcast_ref::() { + s.clone() + } else if let Some(s) = e.downcast_ref::<&'static str>() { + s.to_string() + } else { + "Unknown panic payload".to_string() + }; + set_error(&format!("Panic occurred: {}", msg)); + None + }) +} diff --git a/libProcessing/ffi/src/lib.rs b/libProcessing/ffi/src/lib.rs index b24bd1988..4059b404d 100644 --- a/libProcessing/ffi/src/lib.rs +++ b/libProcessing/ffi/src/lib.rs @@ -1,7 +1,66 @@ mod error; +/// Initialize libProcessing. +/// +/// SAFETY: +/// - This is called from the main thread if the platform requires it. +/// - This can only be called once. #[unsafe(no_mangle)] pub extern "C" fn processing_init() { error::clear_error(); - error::check(renderer::init()); -} \ No newline at end of file + error::check(|| renderer::init()); +} + +/// Create a WebGPU surface from a native window handle. +/// Returns a window ID (entity ID) that should be used for subsequent operations. +/// Returns 0 on failure. +/// +/// SAFETY: +/// - Init has been called. +/// - window_handle is a valid GLFW window pointer. +/// - This is called from the same thread as init. +#[unsafe(no_mangle)] +pub extern "C" fn processing_create_surface( + window_handle: u64, + width: u32, + height: u32, + scale_factor: f32, +) -> u64 { + error::clear_error(); + error::check(|| renderer::create_surface(window_handle, width, height, scale_factor)) + .unwrap_or(0) +} + +/// Update window size when resized. +/// +/// SAFETY: +/// - Init and create_surface have been called. +/// - window_id is a valid ID returned from create_surface. +/// - This is called from the same thread as init. +#[unsafe(no_mangle)] +pub extern "C" fn processing_window_resized(window_id: u64, width: u32, height: u32) { + error::clear_error(); + error::check(|| renderer::window_resized(window_id, width, height)); +} + +/// Step the application forward. +/// +/// SAFETY: +/// - Init has been called and exit has not been called. +/// - This is called from the same thread as init. +#[unsafe(no_mangle)] +pub extern "C" fn processing_update() { + error::clear_error(); + error::check(|| renderer::update()); +} + +/// Shuts down internal resources with given exit code, but does *not* terminate the process. +/// +/// SAFETY: +/// - This is called from the same thread as init. +/// - Caller ensures that update is never called again after exit. +#[unsafe(no_mangle)] +pub extern "C" fn processing_exit(exit_code: u8) { + error::clear_error(); + error::check(|| renderer::exit(exit_code)); +} diff --git a/libProcessing/renderer/Cargo.toml b/libProcessing/renderer/Cargo.toml index 7a54e54fa..4dea5a618 100644 --- a/libProcessing/renderer/Cargo.toml +++ b/libProcessing/renderer/Cargo.toml @@ -6,7 +6,12 @@ edition = "2024" [dependencies] tracing = "0.1" tracing-subscriber = "0.3" -bevy = { version = "0.16", no-default-features = true, features = [ +bevy = { version = "0.17", no-default-features = true, features = [ "bevy_render" ] } -thiserror = "2" \ No newline at end of file +thiserror = "2" +raw-window-handle = "0.6" + +[target.'cfg(target_os = "macos")'.dependencies] +objc2 = { version = "0.6", default-features = false } +objc2-app-kit = { version = "0.3", features = ["NSWindow", "NSView"] } \ No newline at end of file diff --git a/libProcessing/renderer/src/error.rs b/libProcessing/renderer/src/error.rs index 93ff93001..aae0092ab 100644 --- a/libProcessing/renderer/src/error.rs +++ b/libProcessing/renderer/src/error.rs @@ -9,4 +9,10 @@ pub enum ProcessingError { AppAccess, #[error("Error initializing tracing: {0}")] Tracing(#[from] tracing::subscriber::SetGlobalDefaultError), + #[error("Window not found")] + WindowNotFound, + #[error("Handle error: {0}")] + HandleError(#[from] raw_window_handle::HandleError), + #[error("Invalid window handle provided")] + InvalidWindowHandle, } \ No newline at end of file diff --git a/libProcessing/renderer/src/lib.rs b/libProcessing/renderer/src/lib.rs index de14da91b..ddbd5729c 100644 --- a/libProcessing/renderer/src/lib.rs +++ b/libProcessing/renderer/src/lib.rs @@ -1,24 +1,186 @@ pub mod error; -// Once-cell for our app use crate::error::Result; -use bevy::app::App; +use bevy::app::{App, AppExit}; use bevy::log::tracing_subscriber; -use std::sync::{Arc, Mutex, OnceLock}; -use tracing::{debug, info}; +use bevy::prelude::*; +use bevy::window::{ + RawHandleWrapper, Window, WindowResolution, WindowWrapper, +}; +use raw_window_handle::{ + DisplayHandle, HandleError, HasDisplayHandle, HasWindowHandle, RawDisplayHandle, + RawWindowHandle, WindowHandle, +}; +use std::cell::RefCell; +use std::num::NonZero; +use std::sync::OnceLock; +use tracing::debug; static IS_INIT: OnceLock<()> = OnceLock::new(); thread_local! { - static APP: OnceLock = OnceLock::default(); + static APP: OnceLock> = OnceLock::default(); +} + +fn app(cb: impl FnOnce(&App) -> Result) -> Result { + let res = APP.with(|app_lock| { + let app = app_lock + .get() + .ok_or_else(|| error::ProcessingError::AppAccess)? + .borrow(); + cb(&app) + })?; + Ok(res) +} + +fn app_mut(cb: impl FnOnce(&mut App) -> Result) -> Result { + let res = APP.with(|app_lock| { + let mut app = app_lock + .get() + .ok_or_else(|| error::ProcessingError::AppAccess)? + .borrow_mut(); + cb(&mut app) + })?; + Ok(res) +} + +struct GlfwWindow { + window_handle: RawWindowHandle, + display_handle: RawDisplayHandle, +} + +// SAFETY: +// - RawWindowHandle and RawDisplayHandle are just pointers +// - The actual window is managed by Java and outlives this struct +// - GLFW is thread-safe-ish, see https://www.glfw.org/faq#29---is-glfw-thread-safe +// +// Note: we enforce that all calls to init/update/exit happen on the main thread, so +// there should be no concurrent access to the window from multiple threads anyway. +unsafe impl Send for GlfwWindow {} +unsafe impl Sync for GlfwWindow {} + +impl HasWindowHandle for GlfwWindow { + fn window_handle(&self) -> core::result::Result, HandleError> { + // SAFETY: + // - Handles passed from Java are valid + Ok(unsafe { WindowHandle::borrow_raw(self.window_handle) }) + } +} + +impl HasDisplayHandle for GlfwWindow { + fn display_handle(&self) -> core::result::Result, HandleError> { + // SAFETY: + // - Handles passed from Java are valid + Ok(unsafe { DisplayHandle::borrow_raw(self.display_handle) }) + } +} + +/// Create a WebGPU surface from a native window handle. +/// +/// Currently, this just creates a bevy window with the given parameters and +/// stores the raw window handle for later use by the renderer, which will +/// actually create the surface. +pub fn create_surface( + window_handle: u64, + width: u32, + height: u32, + scale_factor: f32, +) -> Result { + #[cfg(target_os = "macos")] + let (raw_window_handle, raw_display_handle) = { + use raw_window_handle::{AppKitDisplayHandle, AppKitWindowHandle}; + + // GLFW gives us NSWindow*, but AppKitWindowHandle needs NSView* + // so we have to do some objc magic to grab the right pointer + let ns_view_ptr = { + use objc2::rc::Retained; + use objc2_app_kit::{NSView, NSWindow}; + + // SAFETY: + // - window_handle is a valid NSWindow pointer from the GLFW window + let ns_window = window_handle as *mut NSWindow; + if ns_window.is_null() { + return Err(error::ProcessingError::InvalidWindowHandle); + } + + // SAFETY: + // - The contentView is owned by NSWindow and remains valid as long as the window exists + let ns_window_ref = unsafe { &*ns_window }; + let content_view: Option> = ns_window_ref.contentView(); + + match content_view { + Some(view) => { + let view_ptr = Retained::as_ptr(&view) as *mut std::ffi::c_void; + view_ptr + } + None => { + return Err(error::ProcessingError::InvalidWindowHandle); + } + } + }; + + let window = AppKitWindowHandle::new(std::ptr::NonNull::new(ns_view_ptr).unwrap()); + let display = AppKitDisplayHandle::new(); + ( + RawWindowHandle::AppKit(window), + RawDisplayHandle::AppKit(display), + ) + }; + + #[cfg(target_os = "windows")] + let (raw_window_handle, raw_display_handle) = + { todo!("implemnt windows raw window handle conversion") }; + + #[cfg(target_os = "linux")] + let (raw_window_handle, raw_display_handle) = + { todo!("implement linux raw window handle conversion") }; + + let glfw_window = GlfwWindow { + window_handle: raw_window_handle, + display_handle: raw_display_handle, + }; + + let window_wrapper = WindowWrapper::new(glfw_window); + let handle_wrapper = RawHandleWrapper::new(&window_wrapper)?; + + let entity_id = app_mut(|app| { + let entity = app + .world_mut() + .spawn(( + Window { + resolution: WindowResolution::new(width, height) + .with_scale_factor_override(scale_factor), + ..default() + }, + handle_wrapper, + )) + .id(); + + // TODO: spawn a camera for this window with a render target of this window + + Ok(entity.to_bits()) + })?; + + Ok(entity_id) +} + +/// Update window size when resized. +pub fn window_resized(window_id: u64, width: u32, height: u32) -> Result<()> { + app_mut(|app| { + let entity = Entity::from_bits(window_id); + if let Some(mut window) = app.world_mut().get_mut::(entity) { + window.resolution.set_physical_resolution(width, height); + Ok(()) + } else { + Err(error::ProcessingError::WindowNotFound) + } + }) } /// Initialize the app, if not already initialized. Must be called from the main thread and cannot /// be called concurrently from multiple threads. pub fn init() -> Result<()> { setup_tracing()?; - info!("Initializing libprocessing"); - let is_init = IS_INIT.get().is_some(); let thread_has_app = APP.with(|app_lock| app_lock.get().is_some()); if is_init && !thread_has_app { @@ -34,14 +196,49 @@ pub fn init() -> Result<()> { IS_INIT.get_or_init(|| ()); let mut app = App::new(); - app.add_plugins(bevy::MinimalPlugins); + app.add_plugins( + DefaultPlugins + .build() + .disable::() + .disable::() + .disable::() + .set(WindowPlugin { + primary_window: None, + exit_condition: bevy::window::ExitCondition::DontExit, + ..default() + }), + ); - app + // this does not mean, as one might imagine, that the app is "done", but rather is part + // of bevy's plugin lifecycle prior to "starting" the app. we are manually driving the app + // so we don't need to call `app.run()` + app.finish(); + app.cleanup(); + RefCell::new(app) }); }); Ok(()) } +pub fn update() -> Result<()> { + app_mut(|app| { + app.update(); + Ok(()) + }) +} + +pub fn exit(exit_code: u8) -> Result<()> { + app_mut(|app| { + app.world_mut().write_message(match exit_code { + 0 => AppExit::Success, + _ => AppExit::Error(NonZero::new(exit_code).unwrap()), + }); + + // one final update to process the exit message + app.update(); + Ok(()) + }) +} fn setup_tracing() -> Result<()> { let subscriber = tracing_subscriber::FmtSubscriber::new(); From fa83874d2012d442176e560dca0aac6c18f9b8ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?charlotte=20=F0=9F=8C=B8?= Date: Wed, 22 Oct 2025 18:33:38 -0500 Subject: [PATCH 11/26] Throw when not on macos. --- core/src/processing/webgpu/PSurfaceGLFW.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/processing/webgpu/PSurfaceGLFW.java b/core/src/processing/webgpu/PSurfaceGLFW.java index 16719f6a9..49f42230a 100644 --- a/core/src/processing/webgpu/PSurfaceGLFW.java +++ b/core/src/processing/webgpu/PSurfaceGLFW.java @@ -121,7 +121,7 @@ public long getWindowHandle() { if (Platform.get() == Platform.MACOSX) { return GLFWNativeCocoa.glfwGetCocoaWindow(window); } else { - return window; + throw new UnsupportedOperationException("Window handle retrieval not implemented for this platform"); } } From 89f8a657681e0e9489e5e2e1a751ed23b41a776a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?charlotte=20=F0=9F=8C=B8?= Date: Mon, 10 Nov 2025 14:46:41 -0800 Subject: [PATCH 12/26] Implement `background` method (#1308) * Implement background. * Install wayland deps. --- .github/workflows/build-gradle.yml | 9 +++ .github/workflows/pull_request-gradle.yml | 9 +++ .../processing/webgpu/PGraphicsWebGPU.java | 19 +++++- core/src/processing/webgpu/PWebGPU.java | 28 ++++++++- libProcessing/Cargo.lock | 1 + libProcessing/Cargo.toml | 6 ++ libProcessing/ffi/Cargo.toml | 1 + libProcessing/ffi/src/color.rs | 14 +++++ libProcessing/ffi/src/lib.rs | 33 ++++++++++- libProcessing/renderer/Cargo.toml | 4 +- libProcessing/renderer/src/lib.rs | 59 +++++++++++++++---- 11 files changed, 165 insertions(+), 18 deletions(-) create mode 100644 libProcessing/ffi/src/color.rs diff --git a/.github/workflows/build-gradle.yml b/.github/workflows/build-gradle.yml index 254433edd..252e1c805 100644 --- a/.github/workflows/build-gradle.yml +++ b/.github/workflows/build-gradle.yml @@ -17,6 +17,10 @@ jobs: with: java-version: '17' distribution: 'temurin' + - name: Install Wayland Dependencies + run: | + sudo apt-get update + sudo apt-get install -y libwayland-dev libxkbcommon-dev - name: Setup Gradle uses: gradle/actions/setup-gradle@v4 @@ -66,6 +70,11 @@ jobs: java-version: '17' distribution: 'temurin' architecture: ${{ matrix.arch }} + - name: Install Wayland Dependencies + if: runner.os == 'Linux' + run: | + sudo apt-get update + sudo apt-get install -y libwayland-dev libxkbcommon-dev - name: Setup Gradle uses: gradle/actions/setup-gradle@v4 diff --git a/.github/workflows/pull_request-gradle.yml b/.github/workflows/pull_request-gradle.yml index 4ea0bcc9d..e543205de 100644 --- a/.github/workflows/pull_request-gradle.yml +++ b/.github/workflows/pull_request-gradle.yml @@ -18,6 +18,10 @@ jobs: with: java-version: '17' distribution: 'temurin' + - name: Install Wayland Dependencies + run: | + sudo apt-get update + sudo apt-get install -y libwayland-dev libxkbcommon-dev - name: Setup Gradle uses: gradle/actions/setup-gradle@v4 @@ -67,6 +71,11 @@ jobs: java-version: '17' distribution: 'temurin' architecture: ${{ matrix.arch }} + - name: Install Wayland Dependencies + if: runner.os == 'Linux' + run: | + sudo apt-get update + sudo apt-get install -y libwayland-dev libxkbcommon-dev - name: Setup Gradle uses: gradle/actions/setup-gradle@v4 diff --git a/core/src/processing/webgpu/PGraphicsWebGPU.java b/core/src/processing/webgpu/PGraphicsWebGPU.java index 78fb86046..914f73683 100644 --- a/core/src/processing/webgpu/PGraphicsWebGPU.java +++ b/core/src/processing/webgpu/PGraphicsWebGPU.java @@ -26,6 +26,12 @@ public void setSize(int w, int h) { } } + @Override + public void beginDraw() { + super.beginDraw(); + checkSettings(); + } + @Override public void endDraw() { super.endDraw(); @@ -35,7 +41,18 @@ public void endDraw() { @Override public void dispose() { super.dispose(); - + if (windowId != 0) { + PWebGPU.destroySurface(windowId); + windowId = 0; + } PWebGPU.exit(); } + + @Override + protected void backgroundImpl() { + if (windowId == 0) { + return; + } + PWebGPU.backgroundColor(windowId, backgroundR, backgroundG, backgroundB, backgroundA); + } } diff --git a/core/src/processing/webgpu/PWebGPU.java b/core/src/processing/webgpu/PWebGPU.java index b0e76b203..2fde44f71 100644 --- a/core/src/processing/webgpu/PWebGPU.java +++ b/core/src/processing/webgpu/PWebGPU.java @@ -2,10 +2,12 @@ import processing.core.NativeLibrary; +import java.lang.foreign.Arena; import java.lang.foreign.MemorySegment; import static java.lang.foreign.MemorySegment.NULL; import static processing.ffi.processing_h.*; +import processing.ffi.Color; /** * PWebGPU provides the native interface layer for libProcessing's WebGPU support. @@ -47,6 +49,16 @@ public static long createSurface(long windowHandle, int width, int height, float return windowId; } + /** + * Destroys a WebGPU surface. + * + * @param windowId The window ID returned from createSurface + */ + public static void destroySurface(long windowId) { + processing_destroy_surface(windowId); + checkError(); + } + /** * Updates a window's size. * @@ -55,7 +67,7 @@ public static long createSurface(long windowHandle, int width, int height, float * @param height New physical window height in pixels */ public static void windowResized(long windowId, int width, int height) { - processing_window_resized(windowId, width, height); + processing_resize_surface(windowId, width, height); checkError(); } @@ -75,6 +87,20 @@ public static void exit() { checkError(); } + public static void backgroundColor(long windowId, float r, float g, float b, float a) { + try (Arena arena = Arena.ofConfined()) { + MemorySegment color = Color.allocate(arena); + + Color.r(color, r); + Color.g(color, g); + Color.b(color, b); + Color.a(color, a); + + processing_background_color(windowId, color); + checkError(); + } + } + /** * Checks for errors from the native library and throws a PWebGPUException if an error occurred. */ diff --git a/libProcessing/Cargo.lock b/libProcessing/Cargo.lock index cd58b5248..585c43934 100644 --- a/libProcessing/Cargo.lock +++ b/libProcessing/Cargo.lock @@ -2302,6 +2302,7 @@ dependencies = [ name = "ffi" version = "0.1.0" dependencies = [ + "bevy", "cbindgen", "renderer", ] diff --git a/libProcessing/Cargo.toml b/libProcessing/Cargo.toml index 6684a907f..8b8a1ccc7 100644 --- a/libProcessing/Cargo.toml +++ b/libProcessing/Cargo.toml @@ -1,3 +1,9 @@ [workspace] resolver = "3" members = ["ffi","renderer"] + +[workspace.dependencies] +bevy = { version = "0.17", no-default-features = true, features = [ + "bevy_render", + "bevy_color", +] } \ No newline at end of file diff --git a/libProcessing/ffi/Cargo.toml b/libProcessing/ffi/Cargo.toml index 243f499d1..9ea189563 100644 --- a/libProcessing/ffi/Cargo.toml +++ b/libProcessing/ffi/Cargo.toml @@ -9,6 +9,7 @@ crate-type = ["cdylib"] [dependencies] renderer = { path = "../renderer" } +bevy = { workspace = true } [build-dependencies] cbindgen = "0.29" diff --git a/libProcessing/ffi/src/color.rs b/libProcessing/ffi/src/color.rs new file mode 100644 index 000000000..25735675d --- /dev/null +++ b/libProcessing/ffi/src/color.rs @@ -0,0 +1,14 @@ +/// A sRGB (?) color +#[repr(C)] +pub struct Color { + pub r: f32, + pub g: f32, + pub b: f32, + pub a: f32, +} + +impl From for bevy::color::Color { + fn from(color: Color) -> Self { + bevy::color::Color::srgba(color.r, color.g, color.b, color.a) + } +} \ No newline at end of file diff --git a/libProcessing/ffi/src/lib.rs b/libProcessing/ffi/src/lib.rs index 4059b404d..ff62d0361 100644 --- a/libProcessing/ffi/src/lib.rs +++ b/libProcessing/ffi/src/lib.rs @@ -1,3 +1,7 @@ +use crate::color::Color; +use bevy::prelude::Entity; + +mod color; mod error; /// Initialize libProcessing. @@ -31,6 +35,19 @@ pub extern "C" fn processing_create_surface( .unwrap_or(0) } +/// Destroy the surface associated with the given window ID. +/// +/// SAFETY: +/// - Init and create_surface have been called. +/// - window_id is a valid ID returned from create_surface. +/// - This is called from the same thread as init. +#[unsafe(no_mangle)] +pub extern "C" fn processing_destroy_surface(window_id: u64) { + error::clear_error(); + let window_entity = Entity::from_bits(window_id); + error::check(|| renderer::destroy_surface(window_entity)); +} + /// Update window size when resized. /// /// SAFETY: @@ -38,9 +55,21 @@ pub extern "C" fn processing_create_surface( /// - window_id is a valid ID returned from create_surface. /// - This is called from the same thread as init. #[unsafe(no_mangle)] -pub extern "C" fn processing_window_resized(window_id: u64, width: u32, height: u32) { +pub extern "C" fn processing_resize_surface(window_id: u64, width: u32, height: u32) { + error::clear_error(); + let window_entity = Entity::from_bits(window_id); + error::check(|| renderer::resize_surface(window_entity, width, height)); +} + +/// Set the background color for the given window. +/// +/// SAFETY: +/// - This is called from the same thread as init. +#[unsafe(no_mangle)] +pub extern "C" fn processing_background_color(window_id: u64, color: Color) { error::clear_error(); - error::check(|| renderer::window_resized(window_id, width, height)); + let window_entity = Entity::from_bits(window_id); + error::check(|| renderer::background_color(window_entity, color.into())); } /// Step the application forward. diff --git a/libProcessing/renderer/Cargo.toml b/libProcessing/renderer/Cargo.toml index 4dea5a618..8e78f41b1 100644 --- a/libProcessing/renderer/Cargo.toml +++ b/libProcessing/renderer/Cargo.toml @@ -6,9 +6,7 @@ edition = "2024" [dependencies] tracing = "0.1" tracing-subscriber = "0.3" -bevy = { version = "0.17", no-default-features = true, features = [ - "bevy_render" -] } +bevy = { workspace = true } thiserror = "2" raw-window-handle = "0.6" diff --git a/libProcessing/renderer/src/lib.rs b/libProcessing/renderer/src/lib.rs index ddbd5729c..2ccda0288 100644 --- a/libProcessing/renderer/src/lib.rs +++ b/libProcessing/renderer/src/lib.rs @@ -4,24 +4,27 @@ use crate::error::Result; use bevy::app::{App, AppExit}; use bevy::log::tracing_subscriber; use bevy::prelude::*; -use bevy::window::{ - RawHandleWrapper, Window, WindowResolution, WindowWrapper, -}; +use bevy::window::{RawHandleWrapper, Window, WindowRef, WindowResolution, WindowWrapper}; use raw_window_handle::{ DisplayHandle, HandleError, HasDisplayHandle, HasWindowHandle, RawDisplayHandle, RawWindowHandle, WindowHandle, }; use std::cell::RefCell; use std::num::NonZero; +use std::sync::atomic::AtomicU32; use std::sync::OnceLock; +use bevy::camera::RenderTarget; +use bevy::camera::visibility::RenderLayers; use tracing::debug; static IS_INIT: OnceLock<()> = OnceLock::new(); +static WINDOW_COUNT: AtomicU32 = AtomicU32::new(0); thread_local! { static APP: OnceLock> = OnceLock::default(); } + fn app(cb: impl FnOnce(&App) -> Result) -> Result { let res = APP.with(|app_lock| { let app = app_lock @@ -144,7 +147,7 @@ pub fn create_surface( let handle_wrapper = RawHandleWrapper::new(&window_wrapper)?; let entity_id = app_mut(|app| { - let entity = app + let mut window = app .world_mut() .spawn(( Window { @@ -153,22 +156,44 @@ pub fn create_surface( ..default() }, handle_wrapper, - )) - .id(); + )); + + let count = WINDOW_COUNT.fetch_add(1, std::sync::atomic::Ordering::SeqCst); + let render_layer = RenderLayers::none().with(count as usize); - // TODO: spawn a camera for this window with a render target of this window + let window_entity = window.id(); + window.with_children(|parent| { + parent.spawn(( + Camera3d::default(), + Camera { + target: RenderTarget::Window(WindowRef::Entity(window_entity)), + ..default() + }, + Projection::Orthographic(OrthographicProjection::default_3d()), + render_layer, + )); + }); - Ok(entity.to_bits()) + Ok(window_entity.to_bits()) })?; Ok(entity_id) } +pub fn destroy_surface(window_entity: Entity) -> Result<()>{ + app_mut(|app| { + if app.world_mut().get::(window_entity).is_some() { + app.world_mut().despawn(window_entity); + WINDOW_COUNT.fetch_sub(1, std::sync::atomic::Ordering::SeqCst); + } + Ok(()) + }) +} + /// Update window size when resized. -pub fn window_resized(window_id: u64, width: u32, height: u32) -> Result<()> { +pub fn resize_surface(window_entity: Entity, width: u32, height: u32) -> Result<()> { app_mut(|app| { - let entity = Entity::from_bits(window_id); - if let Some(mut window) = app.world_mut().get_mut::(entity) { + if let Some(mut window) = app.world_mut().get_mut::(window_entity) { window.resolution.set_physical_resolution(width, height); Ok(()) } else { @@ -240,6 +265,18 @@ pub fn exit(exit_code: u8) -> Result<()> { }) } +pub fn background_color(window_entity: Entity, color: Color) -> Result<()> { + app_mut(|app| { + let mut camera_query = app.world_mut().query::<(&mut Camera, &ChildOf)>(); + for (mut camera, parent) in camera_query.iter_mut(&mut app.world_mut()) { + if parent.parent() == window_entity { + camera.clear_color = ClearColorConfig::Custom(color); + } + } + Ok(()) + }) +} + fn setup_tracing() -> Result<()> { let subscriber = tracing_subscriber::FmtSubscriber::new(); tracing::subscriber::set_global_default(subscriber)?; From 1ee012e7942f0cfa9029151c6d7a1b992c044d0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?charlotte=20=F0=9F=8C=B8?= Date: Mon, 10 Nov 2025 15:46:49 -0800 Subject: [PATCH 13/26] Support for windows surfaces. (#1310) --- core/src/processing/core/NativeLibrary.java | 4 ++- core/src/processing/webgpu/PSurfaceGLFW.java | 3 ++ libProcessing/Cargo.lock | 1 + libProcessing/renderer/Cargo.toml | 5 ++- libProcessing/renderer/src/lib.rs | 37 ++++++++++++++++++-- 5 files changed, 46 insertions(+), 4 deletions(-) diff --git a/core/src/processing/core/NativeLibrary.java b/core/src/processing/core/NativeLibrary.java index 15b7331c2..208eeedd0 100644 --- a/core/src/processing/core/NativeLibrary.java +++ b/core/src/processing/core/NativeLibrary.java @@ -82,7 +82,9 @@ public static String getPlatform() { */ private static void loadNativeLibrary() throws IOException { String platformTarget = platform + "-" + architecture; - String libraryFileName = "lib" + LIBRARY_NAME + "." + libraryExtension; + String libraryFileName = platform.equals("windows") + ? LIBRARY_NAME + "." + libraryExtension + : "lib" + LIBRARY_NAME + "." + libraryExtension; String resourcePath = "/native/" + platformTarget + "/" + libraryFileName; // check classloader for resource in jar diff --git a/core/src/processing/webgpu/PSurfaceGLFW.java b/core/src/processing/webgpu/PSurfaceGLFW.java index 49f42230a..d9591d10e 100644 --- a/core/src/processing/webgpu/PSurfaceGLFW.java +++ b/core/src/processing/webgpu/PSurfaceGLFW.java @@ -4,6 +4,7 @@ import org.lwjgl.glfw.GLFWErrorCallback; import org.lwjgl.glfw.GLFWFramebufferSizeCallback; import org.lwjgl.glfw.GLFWNativeCocoa; +import org.lwjgl.glfw.GLFWNativeWin32; import org.lwjgl.glfw.GLFWWindowPosCallback; import org.lwjgl.system.MemoryUtil; import org.lwjgl.system.Platform; @@ -120,6 +121,8 @@ public Object getNative() { public long getWindowHandle() { if (Platform.get() == Platform.MACOSX) { return GLFWNativeCocoa.glfwGetCocoaWindow(window); + } else if (Platform.get() == Platform.WINDOWS) { + return GLFWNativeWin32.glfwGetWin32Window(window); } else { throw new UnsupportedOperationException("Window handle retrieval not implemented for this platform"); } diff --git a/libProcessing/Cargo.lock b/libProcessing/Cargo.lock index 585c43934..aaee0a5a0 100644 --- a/libProcessing/Cargo.lock +++ b/libProcessing/Cargo.lock @@ -4071,6 +4071,7 @@ dependencies = [ "thiserror 2.0.17", "tracing", "tracing-subscriber", + "windows 0.58.0", ] [[package]] diff --git a/libProcessing/renderer/Cargo.toml b/libProcessing/renderer/Cargo.toml index 8e78f41b1..afda9a5da 100644 --- a/libProcessing/renderer/Cargo.toml +++ b/libProcessing/renderer/Cargo.toml @@ -12,4 +12,7 @@ raw-window-handle = "0.6" [target.'cfg(target_os = "macos")'.dependencies] objc2 = { version = "0.6", default-features = false } -objc2-app-kit = { version = "0.3", features = ["NSWindow", "NSView"] } \ No newline at end of file +objc2-app-kit = { version = "0.3", features = ["NSWindow", "NSView"] } + +[target.'cfg(target_os = "windows")'.dependencies] +windows = { version = "0.58", features = ["Win32_Foundation", "Win32_System_LibraryLoader"] } \ No newline at end of file diff --git a/libProcessing/renderer/src/lib.rs b/libProcessing/renderer/src/lib.rs index 2ccda0288..2536a3529 100644 --- a/libProcessing/renderer/src/lib.rs +++ b/libProcessing/renderer/src/lib.rs @@ -131,8 +131,41 @@ pub fn create_surface( }; #[cfg(target_os = "windows")] - let (raw_window_handle, raw_display_handle) = - { todo!("implemnt windows raw window handle conversion") }; + let (raw_window_handle, raw_display_handle) = { + use raw_window_handle::{Win32WindowHandle, WindowsDisplayHandle}; + use std::num::NonZeroIsize; + use windows::Win32::Foundation::HINSTANCE; + use windows::Win32::System::LibraryLoader::GetModuleHandleW; + + if window_handle == 0 { + return Err(error::ProcessingError::InvalidWindowHandle); + } + + // HWND is isize, so cast it + let hwnd_isize = window_handle as isize; + let hwnd_nonzero = match NonZeroIsize::new(hwnd_isize) { + Some(nz) => nz, + None => return Err(error::ProcessingError::InvalidWindowHandle), + }; + + let mut window = Win32WindowHandle::new(hwnd_nonzero); + + // VK_KHR_win32_surface requires hinstance *and* hwnd + // SAFETY: GetModuleHandleW(NULL) is safe + let hinstance = unsafe { GetModuleHandleW(None) } + .map_err(|_| error::ProcessingError::InvalidWindowHandle)?; + + let hinstance_nonzero = NonZeroIsize::new(hinstance.0 as isize) + .ok_or(error::ProcessingError::InvalidWindowHandle)?; + window.hinstance = Some(hinstance_nonzero); + + let display = WindowsDisplayHandle::new(); + + ( + RawWindowHandle::Win32(window), + RawDisplayHandle::Windows(display), + ) + }; #[cfg(target_os = "linux")] let (raw_window_handle, raw_display_handle) = From 351737c7075278252b5bdb1dcee42efa90bfea04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?charlotte=20=F0=9F=8C=B8?= Date: Thu, 20 Nov 2025 06:59:28 -0800 Subject: [PATCH 14/26] Implement basic rendering flow (#1322) * Implement basic rendering flow * Fix naming. * Actually fix rename. --- core/examples/src/main/java/WebGPU.java | 58 +++++ .../processing/webgpu/PGraphicsWebGPU.java | 98 +++++++- core/src/processing/webgpu/PWebGPU.java | 87 +++++-- libProcessing/Cargo.lock | 195 +++++++++----- libProcessing/ffi/build.rs | 12 +- libProcessing/ffi/src/color.rs | 3 +- libProcessing/ffi/src/error.rs | 9 +- libProcessing/ffi/src/lib.rs | 136 +++++++++- libProcessing/renderer/Cargo.toml | 7 +- libProcessing/renderer/src/error.rs | 3 +- libProcessing/renderer/src/lib.rs | 166 +++++++++--- libProcessing/renderer/src/render/command.rs | 38 +++ libProcessing/renderer/src/render/material.rs | 22 ++ .../renderer/src/render/mesh_builder.rs | 101 ++++++++ libProcessing/renderer/src/render/mod.rs | 238 ++++++++++++++++++ .../renderer/src/render/primitive/mod.rs | 58 +++++ .../renderer/src/render/primitive/rect.rs | 112 +++++++++ 17 files changed, 1204 insertions(+), 139 deletions(-) create mode 100644 core/examples/src/main/java/WebGPU.java create mode 100644 libProcessing/renderer/src/render/command.rs create mode 100644 libProcessing/renderer/src/render/material.rs create mode 100644 libProcessing/renderer/src/render/mesh_builder.rs create mode 100644 libProcessing/renderer/src/render/mod.rs create mode 100644 libProcessing/renderer/src/render/primitive/mod.rs create mode 100644 libProcessing/renderer/src/render/primitive/rect.rs diff --git a/core/examples/src/main/java/WebGPU.java b/core/examples/src/main/java/WebGPU.java new file mode 100644 index 000000000..71ce807ff --- /dev/null +++ b/core/examples/src/main/java/WebGPU.java @@ -0,0 +1,58 @@ +import processing.core.PApplet; + +public class WebGPU extends PApplet { + public void settings() { + size(600, 400, WEBGPU); + } + + public void draw() { + background(200); + + noStroke(); + fill(255, 0, 0); + rect(50, 50, 80, 80); + + fill(0, 255, 0); + rect(150, 50, 80, 80); + + fill(0, 0, 255); + rect(250, 50, 80, 80); + + fill(255, 0, 0, 128); + rect(50, 150, 80, 80); + + fill(0, 255, 0, 128); + rect(150, 150, 80, 80); + + fill(0, 0, 255, 128); + rect(250, 150, 80, 80); + + stroke(0); + strokeWeight(4); + fill(255, 200, 0); + rect(50, 250, 80, 80); + + fill(200, 0, 255); + rect(150, 250, 80, 80); + + noFill(); + stroke(255, 0, 255); + strokeWeight(6); + rect(250, 250, 80, 80); + + noStroke(); + fill(255, 0, 0, 100); + rect(400, 100, 100, 100); + + fill(0, 255, 0, 100); + rect(440, 140, 100, 100); + + fill(0, 0, 255, 100); + rect(420, 180, 100, 100); + } + + public static void main(String[] args) { + PApplet.disableAWT = true; + PApplet.main(WebGPU.class.getName()); + } +} diff --git a/core/src/processing/webgpu/PGraphicsWebGPU.java b/core/src/processing/webgpu/PGraphicsWebGPU.java index 914f73683..3e27967c4 100644 --- a/core/src/processing/webgpu/PGraphicsWebGPU.java +++ b/core/src/processing/webgpu/PGraphicsWebGPU.java @@ -4,7 +4,7 @@ import processing.core.PSurface; public class PGraphicsWebGPU extends PGraphics { - private long windowId = 0; + private long surfaceId = 0; @Override public PSurface createSurface() { @@ -12,8 +12,8 @@ public PSurface createSurface() { } protected void initWebGPUSurface(long windowHandle, int width, int height, float scaleFactor) { - windowId = PWebGPU.createSurface(windowHandle, width, height, scaleFactor); - if (windowId == 0) { + surfaceId = PWebGPU.createSurface(windowHandle, width, height, scaleFactor); + if (surfaceId == 0) { System.err.println("Failed to create WebGPU surface"); } } @@ -21,8 +21,8 @@ protected void initWebGPUSurface(long windowHandle, int width, int height, float @Override public void setSize(int w, int h) { super.setSize(w, h); - if (windowId != 0) { - PWebGPU.windowResized(windowId, pixelWidth, pixelHeight); + if (surfaceId != 0) { + PWebGPU.windowResized(surfaceId, pixelWidth, pixelHeight); } } @@ -30,29 +30,105 @@ public void setSize(int w, int h) { public void beginDraw() { super.beginDraw(); checkSettings(); + System.out.println("Beginning draw on surfaceId: " + surfaceId); + PWebGPU.beginDraw(surfaceId); + } + + @Override + public void flush() { + super.flush(); + PWebGPU.flush(surfaceId); } @Override public void endDraw() { super.endDraw(); - PWebGPU.update(); + PWebGPU.endDraw(surfaceId); } @Override public void dispose() { super.dispose(); - if (windowId != 0) { - PWebGPU.destroySurface(windowId); - windowId = 0; + if (surfaceId != 0) { + PWebGPU.destroySurface(surfaceId); + surfaceId = 0; } PWebGPU.exit(); } @Override protected void backgroundImpl() { - if (windowId == 0) { + if (surfaceId == 0) { + return; + } + PWebGPU.backgroundColor(surfaceId, backgroundR, backgroundG, backgroundB, backgroundA); + } + + @Override + protected void fillFromCalc() { + super.fillFromCalc(); + if (surfaceId == 0) { + return; + } + if (fill) { + PWebGPU.setFill(surfaceId, fillR, fillG, fillB, fillA); + } else { + PWebGPU.noFill(surfaceId); + } + } + + @Override + protected void strokeFromCalc() { + super.strokeFromCalc(); + if (surfaceId == 0) { + return; + } + if (stroke) { + PWebGPU.setStrokeColor(surfaceId, strokeR, strokeG, strokeB, strokeA); + } else { + PWebGPU.noStroke(surfaceId); + } + } + + @Override + public void strokeWeight(float weight) { + super.strokeWeight(weight); + if (surfaceId == 0) { + return; + } + PWebGPU.setStrokeWeight(surfaceId, weight); + } + + @Override + public void noFill() { + super.noFill(); + if (surfaceId == 0) { + return; + } + PWebGPU.noFill(surfaceId); + } + + @Override + public void noStroke() { + super.noStroke(); + if (surfaceId == 0) { + return; + } + PWebGPU.noStroke(surfaceId); + } + + @Override + protected void rectImpl(float x1, float y1, float x2, float y2) { + rectImpl(x1, y1, x2, y2, 0, 0, 0, 0); + } + + @Override + protected void rectImpl(float x1, float y1, float x2, float y2, + float tl, float tr, float br, float bl) { + if (surfaceId == 0) { return; } - PWebGPU.backgroundColor(windowId, backgroundR, backgroundG, backgroundB, backgroundA); + // rectImpl receives corner coordinates, so let's convert to x,y,w,h + PWebGPU.rect(surfaceId, x1, y1, x2 - x1, y2 - y1, tl, tr, br, bl); } } diff --git a/core/src/processing/webgpu/PWebGPU.java b/core/src/processing/webgpu/PWebGPU.java index 2fde44f71..fdc151262 100644 --- a/core/src/processing/webgpu/PWebGPU.java +++ b/core/src/processing/webgpu/PWebGPU.java @@ -44,38 +44,46 @@ public static void init() { * @return Window ID to use for subsequent operations */ public static long createSurface(long windowHandle, int width, int height, float scaleFactor) { - long windowId = processing_create_surface(windowHandle, width, height, scaleFactor); + long surfaceId = processing_create_surface(windowHandle, width, height, scaleFactor); checkError(); - return windowId; + return surfaceId; } /** * Destroys a WebGPU surface. * - * @param windowId The window ID returned from createSurface + * @param surfaceId The window ID returned from createSurface */ - public static void destroySurface(long windowId) { - processing_destroy_surface(windowId); + public static void destroySurface(long surfaceId) { + processing_destroy_surface(surfaceId); checkError(); } /** * Updates a window's size. * - * @param windowId The window ID returned from createSurface + * @param surfaceId The window ID returned from createSurface * @param width New physical window width in pixels * @param height New physical window height in pixels */ - public static void windowResized(long windowId, int width, int height) { - processing_resize_surface(windowId, width, height); + public static void windowResized(long surfaceId, int width, int height) { + processing_resize_surface(surfaceId, width, height); checkError(); } - /** - * Updates the WebGPU subsystem. Should be called once per frame after all drawing is complete. - */ - public static void update() { - processing_update(); + + public static void beginDraw(long surfaceId) { + processing_begin_draw(surfaceId); + checkError(); + } + + public static void flush(long surfaceId) { + processing_flush(surfaceId); + checkError(); + } + + public static void endDraw(long surfaceId) { + processing_end_draw(surfaceId); checkError(); } @@ -87,7 +95,7 @@ public static void exit() { checkError(); } - public static void backgroundColor(long windowId, float r, float g, float b, float a) { + public static void backgroundColor(long surfaceId, float r, float g, float b, float a) { try (Arena arena = Arena.ofConfined()) { MemorySegment color = Color.allocate(arena); @@ -96,11 +104,60 @@ public static void backgroundColor(long windowId, float r, float g, float b, flo Color.b(color, b); Color.a(color, a); - processing_background_color(windowId, color); + processing_background_color(surfaceId, color); checkError(); } } + /** + * Set the fill color. + */ + public static void setFill(long surfaceId, float r, float g, float b, float a) { + processing_set_fill(surfaceId, r, g, b, a); + checkError(); + } + + /** + * Set the stroke color. + */ + public static void setStrokeColor(long surfaceId, float r, float g, float b, float a) { + processing_set_stroke_color(surfaceId, r, g, b, a); + checkError(); + } + + /** + * Set the stroke weight. + */ + public static void setStrokeWeight(long surfaceId, float weight) { + processing_set_stroke_weight(surfaceId, weight); + checkError(); + } + + /** + * Disable fill for subsequent shapes. + */ + public static void noFill(long surfaceId) { + processing_no_fill(surfaceId); + checkError(); + } + + /** + * Disable stroke for subsequent shapes. + */ + public static void noStroke(long surfaceId) { + processing_no_stroke(surfaceId); + checkError(); + } + + /** + * Draw a rectangle. + */ + public static void rect(long surfaceId, float x, float y, float w, float h, + float tl, float tr, float br, float bl) { + processing_rect(surfaceId, x, y, w, h, tl, tr, br, bl); + checkError(); + } + /** * Checks for errors from the native library and throws a PWebGPUException if an error occurred. */ diff --git a/libProcessing/Cargo.lock b/libProcessing/Cargo.lock index aaee0a5a0..e8af7ea5f 100644 --- a/libProcessing/Cargo.lock +++ b/libProcessing/Cargo.lock @@ -110,7 +110,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed7572b7ba83a31e20d1b48970ee402d2e3e0537dcfe0a3ff4d6eb7508617d43" dependencies = [ "alsa-sys", - "bitflags 2.9.4", + "bitflags 2.10.0", "cfg-if", "libc", ] @@ -132,7 +132,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef6978589202a00cd7e118380c448a08b6ed394c3a8df3a430d0898e3a42d046" dependencies = [ "android-properties", - "bitflags 2.9.4", + "bitflags 2.10.0", "cc", "cesu8", "jni", @@ -502,7 +502,7 @@ dependencies = [ "bevy_reflect", "bevy_tasks", "bevy_utils", - "bitflags 2.9.4", + "bitflags 2.10.0", "blake3", "crossbeam-channel", "derive_more", @@ -617,7 +617,7 @@ dependencies = [ "bevy_transform", "bevy_utils", "bevy_window", - "bitflags 2.9.4", + "bitflags 2.10.0", "nonmax", "radsort", "smallvec", @@ -667,7 +667,7 @@ dependencies = [ "bevy_reflect", "bevy_tasks", "bevy_utils", - "bitflags 2.9.4", + "bitflags 2.10.0", "bumpalo", "concurrent-queue", "derive_more", @@ -809,7 +809,7 @@ dependencies = [ "bevy_platform", "bevy_reflect", "bevy_utils", - "bitflags 2.9.4", + "bitflags 2.10.0", "bytemuck", "futures-lite", "guillotiere", @@ -998,7 +998,7 @@ dependencies = [ "bevy_platform", "bevy_reflect", "bevy_transform", - "bitflags 2.9.4", + "bitflags 2.10.0", "bytemuck", "derive_more", "hexasphere", @@ -1037,7 +1037,7 @@ dependencies = [ "bevy_shader", "bevy_transform", "bevy_utils", - "bitflags 2.9.4", + "bitflags 2.10.0", "bytemuck", "derive_more", "fixedbitset", @@ -1116,7 +1116,7 @@ dependencies = [ "bevy_transform", "bevy_utils", "bevy_window", - "bitflags 2.9.4", + "bitflags 2.10.0", "nonmax", "radsort", "smallvec", @@ -1199,7 +1199,7 @@ dependencies = [ "bevy_transform", "bevy_utils", "bevy_window", - "bitflags 2.9.4", + "bitflags 2.10.0", "bytemuck", "derive_more", "downcast-rs 2.0.2", @@ -1320,7 +1320,7 @@ dependencies = [ "bevy_text", "bevy_transform", "bevy_utils", - "bitflags 2.9.4", + "bitflags 2.10.0", "bytemuck", "derive_more", "fixedbitset", @@ -1566,7 +1566,7 @@ version = "0.72.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "cexpr", "clang-sys", "itertools 0.13.0", @@ -1601,12 +1601,12 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.9.4" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394" +checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" dependencies = [ "bytemuck", - "serde", + "serde_core", ] [[package]] @@ -1709,7 +1709,7 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b99da2f8558ca23c71f4fd15dc57c906239752dd27ff3c00a1d56b685b7cbfec" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "log", "polling", "rustix 0.38.44", @@ -1964,7 +1964,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d44a101f213f6c4cdc1853d4b78aef6db6bdfa3468798cc1d9912f4735013eb" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "core-foundation 0.10.1", "libc", ] @@ -1995,7 +1995,7 @@ version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da46a9d5a8905cc538a4a5bceb6a4510de7a51049c5588c0114efce102bcbbe8" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "fontdb", "log", "rangemap", @@ -2142,7 +2142,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "objc2 0.6.3", ] @@ -2329,6 +2329,12 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "float_next_after" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bf7cc16383c4b8d58b9905a8509f02926ce3058053c056376248d958c9df1e8" + [[package]] name = "fnv" version = "1.0.7" @@ -2590,7 +2596,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fbcd2dba93594b227a1f57ee09b8b9da8892c34d55aa332e034a228d0fe6a171" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "gpu-alloc-types", ] @@ -2600,7 +2606,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "98ff03b468aa837d70984d55f5d3f846f6ec31fe34bbb97c4f85219caeee1ca4" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", ] [[package]] @@ -2621,7 +2627,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b89c83349105e3732062a895becfc71a8f921bb71ecbbdd8ff99263e3b53a0ca" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "gpu-descriptor-types", "hashbrown 0.15.5", ] @@ -2632,7 +2638,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdf242682df893b86f33a73828fb09ca4b2d3bb6cc95249707fc684d27484b91" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", ] [[package]] @@ -2768,7 +2774,7 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f37dccff2791ab604f9babef0ba14fbe0be30bd368dc541e2b08d07c8aa908f3" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "inotify-sys", "libc", ] @@ -2896,7 +2902,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff7f53bdf698e7aa7ec916411bbdc8078135da11b66db5182675b2227f6c0d07" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", ] [[package]] @@ -2944,7 +2950,7 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "libc", "redox_syscall 0.5.18", ] @@ -2992,6 +2998,58 @@ version = "0.4.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" +[[package]] +name = "lyon" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbcb7d54d54c8937364c9d41902d066656817dce1e03a44e5533afebd1ef4352" +dependencies = [ + "lyon_algorithms", + "lyon_tessellation", +] + +[[package]] +name = "lyon_algorithms" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c0829e28c4f336396f250d850c3987e16ce6db057ffe047ce0dd54aab6b647" +dependencies = [ + "lyon_path", + "num-traits", +] + +[[package]] +name = "lyon_geom" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e16770d760c7848b0c1c2d209101e408207a65168109509f8483837a36cf2e7" +dependencies = [ + "arrayvec", + "euclid", + "num-traits", +] + +[[package]] +name = "lyon_path" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aeca86bcfd632a15984ba029b539ffb811e0a70bf55e814ef8b0f54f506fdeb" +dependencies = [ + "lyon_geom", + "num-traits", +] + +[[package]] +name = "lyon_tessellation" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3f586142e1280335b1bc89539f7c97dd80f08fc43e9ab1b74ef0a42b04aa353" +dependencies = [ + "float_next_after", + "lyon_path", + "num-traits", +] + [[package]] name = "mach2" version = "0.4.3" @@ -3040,7 +3098,7 @@ version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00c15a6f673ff72ddcc22394663290f870fb224c1bfce55734a75c414150e605" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "block", "core-graphics-types 0.2.0", "foreign-types", @@ -3083,7 +3141,7 @@ checksum = "916cbc7cb27db60be930a4e2da243cf4bc39569195f22fd8ee419cd31d5b662c" dependencies = [ "arrayvec", "bit-set", - "bitflags 2.9.4", + "bitflags 2.10.0", "cfg-if", "cfg_aliases", "codespan-reporting", @@ -3125,7 +3183,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2076a31b7010b17a38c01907c45b945e8f11495ee4dd588309718901b1f7a5b7" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "jni-sys", "log", "ndk-sys 0.5.0+25.2.9519653", @@ -3139,7 +3197,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "jni-sys", "log", "ndk-sys 0.6.0+11769913", @@ -3178,7 +3236,7 @@ version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "cfg-if", "cfg_aliases", "libc", @@ -3301,7 +3359,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "block2 0.5.1", "libc", "objc2 0.5.2", @@ -3317,7 +3375,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d49e936b501e5c5bf01fda3a9452ff86dc3ea98ad5f283e1455153142d97518c" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "block2 0.6.2", "libc", "objc2 0.6.3", @@ -3338,7 +3396,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "block2 0.5.1", "objc2 0.5.2", "objc2-core-location", @@ -3351,7 +3409,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73ad74d880bb43877038da939b7427bba67e9dd42004a18b809ba7d87cee241c" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "objc2 0.6.3", "objc2-foundation 0.3.2", ] @@ -3373,7 +3431,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "block2 0.5.1", "objc2 0.5.2", "objc2-foundation 0.2.2", @@ -3385,7 +3443,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b402a653efbb5e82ce4df10683b6b28027616a2715e90009947d50b8dd298fa" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "objc2 0.6.3", "objc2-foundation 0.3.2", ] @@ -3396,7 +3454,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "dispatch2", "objc2 0.6.3", ] @@ -3407,7 +3465,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e022c9d066895efa1345f8e33e584b9f958da2fd4cd116792e15e07e4720a807" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "dispatch2", "objc2 0.6.3", "objc2-core-foundation", @@ -3454,7 +3512,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0cde0dfb48d25d2b4862161a4d5fcc0e3c24367869ad306b0c9ec0073bfed92d" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "objc2 0.6.3", "objc2-core-foundation", "objc2-core-graphics", @@ -3466,7 +3524,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d425caf1df73233f29fd8a5c3e5edbc30d2d4307870f802d18f00d83dc5141a6" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "objc2 0.6.3", "objc2-core-foundation", "objc2-core-graphics", @@ -3485,7 +3543,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "block2 0.5.1", "dispatch", "libc", @@ -3498,7 +3556,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "objc2 0.6.3", "objc2-core-foundation", ] @@ -3519,7 +3577,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "180788110936d59bab6bd83b6060ffdfffb3b922ba1396b312ae795e1de9d81d" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "objc2 0.6.3", "objc2-core-foundation", ] @@ -3542,7 +3600,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "block2 0.5.1", "objc2 0.5.2", "objc2-foundation 0.2.2", @@ -3554,7 +3612,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "block2 0.5.1", "objc2 0.5.2", "objc2-foundation 0.2.2", @@ -3567,7 +3625,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96c1358452b371bf9f104e21ec536d37a650eb10f7ee379fff67d2e08d537f1f" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "objc2 0.6.3", "objc2-foundation 0.3.2", ] @@ -3588,7 +3646,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "block2 0.5.1", "objc2 0.5.2", "objc2-cloud-kit 0.2.2", @@ -3620,7 +3678,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "block2 0.5.1", "objc2 0.5.2", "objc2-core-location", @@ -3811,7 +3869,7 @@ version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97baced388464909d42d89643fe4361939af9b7ce7a31ee32a168f832a70f2a0" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "crc32fast", "fdeflate", "flate2", @@ -4022,7 +4080,7 @@ version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", ] [[package]] @@ -4065,6 +4123,7 @@ name = "renderer" version = "0.1.0" dependencies = [ "bevy", + "lyon", "objc2 0.6.3", "objc2-app-kit 0.3.2", "raw-window-handle", @@ -4091,7 +4150,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "beceb6f7bf81c73e73aeef6dd1356d9a1b2b4909e1f0fc3e59b034f9572d7b7f" dependencies = [ "base64", - "bitflags 2.9.4", + "bitflags 2.10.0", "serde", "serde_derive", "unicode-ident", @@ -4121,7 +4180,7 @@ version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "errno", "libc", "linux-raw-sys 0.4.15", @@ -4134,7 +4193,7 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "errno", "libc", "linux-raw-sys 0.11.0", @@ -4153,7 +4212,7 @@ version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfb9cf8877777222e4a3bc7eb247e398b56baba500c38c1c46842431adc8b55c" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "bytemuck", "libm", "smallvec", @@ -4335,7 +4394,7 @@ version = "0.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3457dea1f0eb631b4034d61d4d8c32074caa6cd1ab2d59f2327bd8461e2c0016" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "calloop", "calloop-wayland-source", "cursor-icon", @@ -4378,7 +4437,7 @@ version = "0.3.0+sdk-1.3.268.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eda41003dc44290527a59b13432d4a0379379fa074b70174882adfbdfd917844" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", ] [[package]] @@ -4994,7 +5053,7 @@ version = "0.31.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c66a47e840dc20793f2264eb4b3e4ecb4b75d91c0dd4af04b456128e0bdd449d" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "rustix 1.1.2", "wayland-backend", "wayland-scanner", @@ -5006,7 +5065,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "625c5029dbd43d25e6aa9615e88b829a5cad13b2819c4ae129fdbb7c31ab4c7e" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "cursor-icon", "wayland-backend", ] @@ -5028,7 +5087,7 @@ version = "0.32.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "efa790ed75fbfd71283bd2521a1cfdc022aabcc28bdcff00851f9e4ae88d9901" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "wayland-backend", "wayland-client", "wayland-scanner", @@ -5040,7 +5099,7 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a07a14257c077ab3279987c4f8bb987851bf57081b93710381daea94f2c2c032" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "wayland-backend", "wayland-client", "wayland-protocols", @@ -5053,7 +5112,7 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "efd94963ed43cf9938a090ca4f7da58eb55325ec8200c3848963e98dc25b78ec" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "wayland-backend", "wayland-client", "wayland-protocols", @@ -5109,7 +5168,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70b6ff82bbf6e9206828e1a3178e851f8c20f1c9028e74dd3a8090741ccd5798" dependencies = [ "arrayvec", - "bitflags 2.9.4", + "bitflags 2.10.0", "cfg-if", "cfg_aliases", "document-features", @@ -5138,7 +5197,7 @@ dependencies = [ "arrayvec", "bit-set", "bit-vec", - "bitflags 2.9.4", + "bitflags 2.10.0", "cfg_aliases", "document-features", "hashbrown 0.15.5", @@ -5197,7 +5256,7 @@ dependencies = [ "arrayvec", "ash", "bit-set", - "bitflags 2.9.4", + "bitflags 2.10.0", "block", "bytemuck", "cfg-if", @@ -5241,7 +5300,7 @@ version = "26.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eca7a8d8af57c18f57d393601a1fb159ace8b2328f1b6b5f80893f7d672c9ae2" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "bytemuck", "js-sys", "log", @@ -5813,7 +5872,7 @@ dependencies = [ "ahash", "android-activity", "atomic-waker", - "bitflags 2.9.4", + "bitflags 2.10.0", "block2 0.5.1", "bytemuck", "calloop", @@ -5915,7 +5974,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d039de8032a9a8856a6be89cea3e5d12fdd82306ab7c94d74e6deab2460651c5" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "dlib", "log", "once_cell", diff --git a/libProcessing/ffi/build.rs b/libProcessing/ffi/build.rs index b9dcb3d61..e94d8186d 100644 --- a/libProcessing/ffi/build.rs +++ b/libProcessing/ffi/build.rs @@ -1,5 +1,4 @@ -use std::env; -use std::path::PathBuf; +use std::{env, path::PathBuf}; fn main() { let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap(); @@ -11,7 +10,9 @@ fn main() { let config_path = PathBuf::from(&crate_dir).join("cbindgen.toml"); cbindgen::Builder::new() - .with_config(cbindgen::Config::from_file(&config_path).expect("Failed to load cbindgen.toml")) + .with_config( + cbindgen::Config::from_file(&config_path).expect("Failed to load cbindgen.toml"), + ) .with_crate(&crate_dir) .generate() .expect("Unable to generate bindings") @@ -19,5 +20,8 @@ fn main() { println!("cargo:rerun-if-changed=src/lib.rs"); println!("cargo:rerun-if-changed=cbindgen.toml"); - println!("cargo:warning=Generated header at: {}", output_file.display()); + println!( + "cargo:warning=Generated header at: {}", + output_file.display() + ); } diff --git a/libProcessing/ffi/src/color.rs b/libProcessing/ffi/src/color.rs index 25735675d..fc063be63 100644 --- a/libProcessing/ffi/src/color.rs +++ b/libProcessing/ffi/src/color.rs @@ -1,5 +1,6 @@ /// A sRGB (?) color #[repr(C)] +#[derive(Debug, Clone, Copy)] pub struct Color { pub r: f32, pub g: f32, @@ -11,4 +12,4 @@ impl From for bevy::color::Color { fn from(color: Color) -> Self { bevy::color::Color::srgba(color.r, color.g, color.b, color.a) } -} \ No newline at end of file +} diff --git a/libProcessing/ffi/src/error.rs b/libProcessing/ffi/src/error.rs index 1f235580e..ee509cd0c 100644 --- a/libProcessing/ffi/src/error.rs +++ b/libProcessing/ffi/src/error.rs @@ -1,7 +1,10 @@ +use std::{ + cell::RefCell, + ffi::{CString, c_char}, + panic, +}; + use renderer::error::ProcessingError; -use std::cell::RefCell; -use std::ffi::{CString, c_char}; -use std::panic; thread_local! { static LAST_ERROR: RefCell> = RefCell::new(None); diff --git a/libProcessing/ffi/src/lib.rs b/libProcessing/ffi/src/lib.rs index ff62d0361..bde38a56b 100644 --- a/libProcessing/ffi/src/lib.rs +++ b/libProcessing/ffi/src/lib.rs @@ -1,5 +1,7 @@ -use crate::color::Color; use bevy::prelude::Entity; +use renderer::render::command::DrawCommand; + +use crate::color::Color; mod color; mod error; @@ -72,15 +74,40 @@ pub extern "C" fn processing_background_color(window_id: u64, color: Color) { error::check(|| renderer::background_color(window_entity, color.into())); } -/// Step the application forward. +/// Begins the draw for the given window. /// /// SAFETY: /// - Init has been called and exit has not been called. /// - This is called from the same thread as init. #[unsafe(no_mangle)] -pub extern "C" fn processing_update() { +pub extern "C" fn processing_begin_draw(window_id: u64) { error::clear_error(); - error::check(|| renderer::update()); + let window_entity = Entity::from_bits(window_id); + error::check(|| renderer::begin_draw(window_entity)); +} + +/// Flushes recorded draw commands for the given window. +/// +/// SAFETY: +/// - Init has been called and exit has not been called. +/// - This is called from the same thread as init. +#[unsafe(no_mangle)] +pub extern "C" fn processing_flush(window_id: u64) { + error::clear_error(); + let window_entity = Entity::from_bits(window_id); + error::check(|| renderer::flush(window_entity)); +} + +/// Ends the draw for the given window and presents the frame. +/// +/// SAFETY: +/// - Init has been called and exit has not been called. +/// - This is called from the same thread as init. +#[unsafe(no_mangle)] +pub extern "C" fn processing_end_draw(window_id: u64) { + error::clear_error(); + let window_entity = Entity::from_bits(window_id); + error::check(|| renderer::end_draw(window_entity)); } /// Shuts down internal resources with given exit code, but does *not* terminate the process. @@ -93,3 +120,104 @@ pub extern "C" fn processing_exit(exit_code: u8) { error::clear_error(); error::check(|| renderer::exit(exit_code)); } + +/// Set the fill color. +/// +/// SAFETY: +/// - Init and create_surface have been called. +/// - window_id is a valid ID returned from create_surface. +/// - This is called from the same thread as init. +#[unsafe(no_mangle)] +pub extern "C" fn processing_set_fill(window_id: u64, r: f32, g: f32, b: f32, a: f32) { + error::clear_error(); + let window_entity = Entity::from_bits(window_id); + let color = bevy::color::Color::srgba(r, g, b, a); + error::check(|| renderer::record_command(window_entity, DrawCommand::Fill(color))); +} + +/// Set the stroke color. +/// +/// SAFETY: +/// - Init and create_surface have been called. +/// - window_id is a valid ID returned from create_surface. +/// - This is called from the same thread as init. +#[unsafe(no_mangle)] +pub extern "C" fn processing_set_stroke_color(window_id: u64, r: f32, g: f32, b: f32, a: f32) { + error::clear_error(); + let window_entity = Entity::from_bits(window_id); + let color = bevy::color::Color::srgba(r, g, b, a); + error::check(|| renderer::record_command(window_entity, DrawCommand::StrokeColor(color))); +} + +/// Set the stroke weight. +/// +/// SAFETY: +/// - Init and create_surface have been called. +/// - window_id is a valid ID returned from create_surface. +/// - This is called from the same thread as init. +#[unsafe(no_mangle)] +pub extern "C" fn processing_set_stroke_weight(window_id: u64, weight: f32) { + error::clear_error(); + let window_entity = Entity::from_bits(window_id); + error::check(|| renderer::record_command(window_entity, DrawCommand::StrokeWeight(weight))); +} + +/// Disable fill for subsequent shapes. +/// +/// SAFETY: +/// - Init and create_surface have been called. +/// - window_id is a valid ID returned from create_surface. +/// - This is called from the same thread as init. +#[unsafe(no_mangle)] +pub extern "C" fn processing_no_fill(window_id: u64) { + error::clear_error(); + let window_entity = Entity::from_bits(window_id); + error::check(|| renderer::record_command(window_entity, DrawCommand::NoFill)); +} + +/// Disable stroke for subsequent shapes. +/// +/// SAFETY: +/// - Init and create_surface have been called. +/// - window_id is a valid ID returned from create_surface. +/// - This is called from the same thread as init. +#[unsafe(no_mangle)] +pub extern "C" fn processing_no_stroke(window_id: u64) { + error::clear_error(); + let window_entity = Entity::from_bits(window_id); + error::check(|| renderer::record_command(window_entity, DrawCommand::NoStroke)); +} + +/// Draw a rectangle. +/// +/// SAFETY: +/// - Init and create_surface have been called. +/// - window_id is a valid ID returned from create_surface. +/// - This is called from the same thread as init. +#[unsafe(no_mangle)] +pub extern "C" fn processing_rect( + window_id: u64, + x: f32, + y: f32, + w: f32, + h: f32, + tl: f32, + tr: f32, + br: f32, + bl: f32, +) { + error::clear_error(); + let window_entity = Entity::from_bits(window_id); + error::check(|| { + renderer::record_command( + window_entity, + DrawCommand::Rect { + x, + y, + w, + h, + radii: [tl, tr, br, bl], + }, + ) + }); +} diff --git a/libProcessing/renderer/Cargo.toml b/libProcessing/renderer/Cargo.toml index afda9a5da..c78a2f976 100644 --- a/libProcessing/renderer/Cargo.toml +++ b/libProcessing/renderer/Cargo.toml @@ -4,11 +4,12 @@ version = "0.1.0" edition = "2024" [dependencies] -tracing = "0.1" -tracing-subscriber = "0.3" bevy = { workspace = true } -thiserror = "2" +lyon = "1.0" raw-window-handle = "0.6" +thiserror = "2" +tracing = "0.1" +tracing-subscriber = "0.3" [target.'cfg(target_os = "macos")'.dependencies] objc2 = { version = "0.6", default-features = false } diff --git a/libProcessing/renderer/src/error.rs b/libProcessing/renderer/src/error.rs index aae0092ab..9eedd9d26 100644 --- a/libProcessing/renderer/src/error.rs +++ b/libProcessing/renderer/src/error.rs @@ -2,7 +2,6 @@ use thiserror::Error; pub type Result = std::result::Result; - #[derive(Error, Debug)] pub enum ProcessingError { #[error("App was accessed from multiple threads")] @@ -15,4 +14,4 @@ pub enum ProcessingError { HandleError(#[from] raw_window_handle::HandleError), #[error("Invalid window handle provided")] InvalidWindowHandle, -} \ No newline at end of file +} diff --git a/libProcessing/renderer/src/lib.rs b/libProcessing/renderer/src/lib.rs index 2536a3529..18c316256 100644 --- a/libProcessing/renderer/src/lib.rs +++ b/libProcessing/renderer/src/lib.rs @@ -1,29 +1,39 @@ pub mod error; +pub mod render; -use crate::error::Result; -use bevy::app::{App, AppExit}; -use bevy::log::tracing_subscriber; -use bevy::prelude::*; -use bevy::window::{RawHandleWrapper, Window, WindowRef, WindowResolution, WindowWrapper}; +use std::{cell::RefCell, num::NonZero, sync::OnceLock}; + +use bevy::{ + app::{App, AppExit}, + asset::AssetEventSystems, + camera::{CameraOutputMode, RenderTarget, visibility::RenderLayers}, + log::tracing_subscriber, + prelude::*, + window::{RawHandleWrapper, Window, WindowRef, WindowResolution, WindowWrapper}, +}; use raw_window_handle::{ DisplayHandle, HandleError, HasDisplayHandle, HasWindowHandle, RawDisplayHandle, RawWindowHandle, WindowHandle, }; -use std::cell::RefCell; -use std::num::NonZero; -use std::sync::atomic::AtomicU32; -use std::sync::OnceLock; -use bevy::camera::RenderTarget; -use bevy::camera::visibility::RenderLayers; +use render::{activate_cameras, clear_transient_meshes, flush_draw_commands}; use tracing::debug; +use crate::{ + error::Result, + render::command::{CommandBuffer, DrawCommand}, +}; + static IS_INIT: OnceLock<()> = OnceLock::new(); -static WINDOW_COUNT: AtomicU32 = AtomicU32::new(0); thread_local! { static APP: OnceLock> = OnceLock::default(); } +#[derive(Resource, Default)] +struct WindowCount(u32); + +#[derive(Component)] +pub struct Flush; fn app(cb: impl FnOnce(&App) -> Result) -> Result { let res = APP.with(|app_lock| { @@ -180,29 +190,55 @@ pub fn create_surface( let handle_wrapper = RawHandleWrapper::new(&window_wrapper)?; let entity_id = app_mut(|app| { - let mut window = app - .world_mut() - .spawn(( - Window { - resolution: WindowResolution::new(width, height) - .with_scale_factor_override(scale_factor), - ..default() - }, - handle_wrapper, - )); - - let count = WINDOW_COUNT.fetch_add(1, std::sync::atomic::Ordering::SeqCst); + let mut window_count = app.world_mut().resource_mut::(); + let count = window_count.0; + window_count.0 += 1; let render_layer = RenderLayers::none().with(count as usize); + let mut window = app.world_mut().spawn(( + Window { + resolution: WindowResolution::new(width, height) + .with_scale_factor_override(scale_factor), + ..default() + }, + handle_wrapper, + CommandBuffer::default(), + // this doesn't do anything but makes it easier to fetch the render layer for + // meshes to be drawn to this window + render_layer.clone(), + )); + let window_entity = window.id(); window.with_children(|parent| { + // processing has a different coordinate system for 2d rendering: + // - origin at top-left + // - x increases to the right, y increases downward + // - coordinate units are in screen pixels + let half_width = width as f32 / 2.0; + let half_height = height as f32 / 2.0; + + let projection = OrthographicProjection { + near: -1000.0, + far: 1000.0, + viewport_origin: Vec2::new(0.0, 0.0), // top left + scaling_mode: bevy::camera::ScalingMode::Fixed { + width: width as f32, + height: height as f32, + }, + scale: 1.0, + ..OrthographicProjection::default_3d() + }; + parent.spawn(( Camera3d::default(), Camera { target: RenderTarget::Window(WindowRef::Entity(window_entity)), ..default() }, - Projection::Orthographic(OrthographicProjection::default_3d()), + Projection::Orthographic(projection), + // position camera to match coordinate system + Transform::from_xyz(half_width, -half_height, 999.0) + .looking_at(Vec3::new(half_width, -half_height, 0.0), Vec3::Y), render_layer, )); }); @@ -213,11 +249,12 @@ pub fn create_surface( Ok(entity_id) } -pub fn destroy_surface(window_entity: Entity) -> Result<()>{ +pub fn destroy_surface(window_entity: Entity) -> Result<()> { app_mut(|app| { if app.world_mut().get::(window_entity).is_some() { app.world_mut().despawn(window_entity); - WINDOW_COUNT.fetch_sub(1, std::sync::atomic::Ordering::SeqCst); + let mut window_count = app.world_mut().resource_mut::(); + window_count.0 = window_count.0.saturating_sub(1); } Ok(()) }) @@ -267,6 +304,13 @@ pub fn init() -> Result<()> { }), ); + // resources + app.init_resource::(); + + // rendering + app.add_systems(First, (clear_transient_meshes, activate_cameras)) + .add_systems(Update, flush_draw_commands.before(AssetEventSystems)); + // this does not mean, as one might imagine, that the app is "done", but rather is part // of bevy's plugin lifecycle prior to "starting" the app. we are manually driving the app // so we don't need to call `app.run()` @@ -278,9 +322,63 @@ pub fn init() -> Result<()> { Ok(()) } -pub fn update() -> Result<()> { + +macro_rules! camera_mut { + ($app:expr, $window_entity:expr) => { + $app.world_mut() + .query::<(&mut Camera, &ChildOf)>() + .iter_mut(&mut $app.world_mut()) + .filter_map(|(camera, parent)| { + if parent.parent() == $window_entity { + Some(camera) + } else { + None + } + }) + .next() + .ok_or_else(|| error::ProcessingError::WindowNotFound)? + }; +} + +macro_rules! window_mut { + ($app:expr, $window_entity:expr) => { + $app.world_mut() + .get_entity_mut($window_entity) + .map_err(|_| error::ProcessingError::WindowNotFound)? + }; +} + +pub fn begin_draw(_window_entity: Entity) -> Result<()> { + app_mut(|_app| Ok(())) +} + +pub fn flush(window_entity: Entity) -> Result<()> { app_mut(|app| { + window_mut!(app, window_entity).insert(Flush); app.update(); + window_mut!(app, window_entity).remove::(); + + // ensure that the intermediate texture is not cleared + camera_mut!(app, window_entity).clear_color = ClearColorConfig::None; + Ok(()) + }) +} + +pub fn end_draw(window_entity: Entity) -> Result<()> { + // since we are ending the draw, set the camera to write to the output render target + app_mut(|app| { + camera_mut!(app, window_entity).output_mode = CameraOutputMode::Write { + blend_state: None, + clear_color: ClearColorConfig::Default, + }; + Ok(()) + })?; + // flush any remaining draw commands, this ensures that the frame is presented even if there + // is no remaining draw commands + flush(window_entity)?; + // reset to skipping output for the next frame + app_mut(|app| { + camera_mut!(app, window_entity).output_mode = CameraOutputMode::Skip; Ok(()) }) } @@ -315,3 +413,15 @@ fn setup_tracing() -> Result<()> { tracing::subscriber::set_global_default(subscriber)?; Ok(()) } + +/// Record a drawing command for a window +pub fn record_command(window_entity: Entity, cmd: DrawCommand) -> Result<()> { + app_mut(|app| { + let mut entity_mut = app.world_mut().entity_mut(window_entity); + if let Some(mut buffer) = entity_mut.get_mut::() { + buffer.push(cmd); + } + + Ok(()) + }) +} diff --git a/libProcessing/renderer/src/render/command.rs b/libProcessing/renderer/src/render/command.rs new file mode 100644 index 000000000..8965aaea0 --- /dev/null +++ b/libProcessing/renderer/src/render/command.rs @@ -0,0 +1,38 @@ +use bevy::prelude::*; + +#[derive(Debug, Clone)] +pub enum DrawCommand { + Fill(Color), + NoFill, + StrokeColor(Color), + NoStroke, + StrokeWeight(f32), + Rect { + x: f32, + y: f32, + w: f32, + h: f32, + radii: [f32; 4], // [tl, tr, br, bl] + }, +} + +#[derive(Debug, Default, Component)] +pub struct CommandBuffer { + pub commands: Vec, +} + +impl CommandBuffer { + pub fn new() -> Self { + Self { + commands: Vec::new(), + } + } + + pub fn push(&mut self, cmd: DrawCommand) { + self.commands.push(cmd); + } + + pub fn clear(&mut self) { + self.commands.clear(); + } +} diff --git a/libProcessing/renderer/src/render/material.rs b/libProcessing/renderer/src/render/material.rs new file mode 100644 index 000000000..9529e8ec4 --- /dev/null +++ b/libProcessing/renderer/src/render/material.rs @@ -0,0 +1,22 @@ +use bevy::{prelude::*, render::alpha::AlphaMode}; + +#[derive(Clone, PartialEq, Eq, Hash, Debug)] +pub struct MaterialKey { + pub transparent: bool, +} + +impl MaterialKey { + pub fn to_material(&self) -> StandardMaterial { + StandardMaterial { + base_color: Color::WHITE, + unlit: true, + cull_mode: None, + alpha_mode: if self.transparent { + AlphaMode::Blend + } else { + AlphaMode::Opaque + }, + ..default() + } + } +} diff --git a/libProcessing/renderer/src/render/mesh_builder.rs b/libProcessing/renderer/src/render/mesh_builder.rs new file mode 100644 index 000000000..ce3a5ae58 --- /dev/null +++ b/libProcessing/renderer/src/render/mesh_builder.rs @@ -0,0 +1,101 @@ +use bevy::{ + mesh::{Indices, VertexAttributeValues}, + prelude::*, +}; +use lyon::tessellation::{ + FillVertex, StrokeVertex, VertexId, + geometry_builder::{ + FillGeometryBuilder, GeometryBuilder, GeometryBuilderError, StrokeGeometryBuilder, + }, +}; + +pub struct MeshBuilder<'a> { + mesh: &'a mut Mesh, + color: Color, + begin_vertex_count: u32, +} + +impl<'a> MeshBuilder<'a> { + pub fn new(mesh: &'a mut Mesh, color: Color) -> Self { + Self { + mesh, + color, + begin_vertex_count: 0, + } + } + + fn push_vertex(&mut self, position: [f32; 3]) -> VertexId { + let id = VertexId::from_usize(self.vertex_count()); + + if let Some(VertexAttributeValues::Float32x3(positions)) = + self.mesh.attribute_mut(Mesh::ATTRIBUTE_POSITION) + { + positions.push(position); + } + + if let Some(VertexAttributeValues::Float32x4(colors)) = + self.mesh.attribute_mut(Mesh::ATTRIBUTE_COLOR) + { + colors.push(self.color.to_srgba().to_f32_array()); + } + + if let Some(VertexAttributeValues::Float32x3(normals)) = + self.mesh.attribute_mut(Mesh::ATTRIBUTE_NORMAL) + { + normals.push([0.0, 0.0, 1.0]); // flat normal for 2d + } + + id + } + + fn push_index(&mut self, index: u32) { + if let Some(Indices::U32(indices)) = self.mesh.indices_mut() { + indices.push(index); + } + } + + fn vertex_count(&self) -> usize { + if let Some(VertexAttributeValues::Float32x3(positions)) = + self.mesh.attribute(Mesh::ATTRIBUTE_POSITION) + { + positions.len() + } else { + 0 + } + } +} + +impl<'a> GeometryBuilder for MeshBuilder<'a> { + fn begin_geometry(&mut self) { + self.begin_vertex_count = self.vertex_count() as u32; + } + + fn add_triangle(&mut self, a: VertexId, b: VertexId, c: VertexId) { + self.push_index(a.to_usize() as u32); + self.push_index(b.to_usize() as u32); + self.push_index(c.to_usize() as u32); + } + + fn abort_geometry(&mut self) { + todo!("Implement abort_geometry if needed"); + } +} + +impl<'a> FillGeometryBuilder for MeshBuilder<'a> { + fn add_fill_vertex(&mut self, vertex: FillVertex) -> Result { + let pos = vertex.position(); + let position = [pos.x, pos.y, 0.0]; + Ok(self.push_vertex(position)) + } +} + +impl<'a> StrokeGeometryBuilder for MeshBuilder<'a> { + fn add_stroke_vertex( + &mut self, + vertex: StrokeVertex, + ) -> Result { + let pos = vertex.position(); + let position = [pos.x, pos.y, 0.0]; + Ok(self.push_vertex(position)) + } +} diff --git a/libProcessing/renderer/src/render/mod.rs b/libProcessing/renderer/src/render/mod.rs new file mode 100644 index 000000000..98222a536 --- /dev/null +++ b/libProcessing/renderer/src/render/mod.rs @@ -0,0 +1,238 @@ +pub mod command; +pub mod material; +pub mod mesh_builder; +mod primitive; + +use bevy::{camera::visibility::RenderLayers, ecs::system::SystemParam, prelude::*}; +use command::{CommandBuffer, DrawCommand}; +use material::MaterialKey; +use primitive::{TessellationMode, empty_mesh}; + +use crate::{Flush, render::primitive::rect}; + +#[derive(Component)] +pub struct TransientMesh; + +#[derive(SystemParam)] +pub struct RenderContext<'w, 's> { + commands: Commands<'w, 's>, + meshes: ResMut<'w, Assets>, + materials: ResMut<'w, Assets>, + batch: Local<'s, BatchState>, + state: Local<'s, RenderState>, +} + +#[derive(Default)] +struct BatchState { + current_mesh: Option, + material_key: Option, + draw_index: u32, + render_layers: RenderLayers, + surface_entity: Option, +} + +#[derive(Debug)] +pub struct RenderState { + // drawing state + pub fill_color: Option, + pub stroke_color: Option, + pub stroke_weight: f32, +} + +impl Default for RenderState { + fn default() -> Self { + Self { + fill_color: Some(Color::WHITE), + stroke_color: Some(Color::BLACK), + stroke_weight: 1.0, + } + } +} + +impl RenderState { + pub fn new() -> Self { + Self::default() + } + + pub fn has_fill(&self) -> bool { + self.fill_color.is_some() + } + + pub fn has_stroke(&self) -> bool { + self.stroke_color.is_some() + } + + pub fn fill_is_transparent(&self) -> bool { + self.fill_color.map(|c| c.alpha() < 1.0).unwrap_or(false) + } + + pub fn stroke_is_transparent(&self) -> bool { + self.stroke_color.map(|c| c.alpha() < 1.0).unwrap_or(false) + } +} + +pub fn flush_draw_commands( + mut ctx: RenderContext, + mut query: Query<(Entity, &mut CommandBuffer, &RenderLayers), With>, +) { + for (surface_entity, mut cmd_buffer, render_layers) in query.iter_mut() { + let draw_commands = std::mem::take(&mut cmd_buffer.commands); + ctx.batch.render_layers = render_layers.clone(); + ctx.batch.surface_entity = Some(surface_entity); + ctx.batch.draw_index = 0; // Reset draw index for each flush + + for cmd in draw_commands { + match cmd { + DrawCommand::Fill(color) => { + ctx.state.fill_color = Some(color); + } + DrawCommand::NoFill => { + ctx.state.fill_color = None; + } + DrawCommand::StrokeColor(color) => { + ctx.state.stroke_color = Some(color); + } + DrawCommand::NoStroke => { + ctx.state.stroke_color = None; + } + DrawCommand::StrokeWeight(weight) => { + ctx.state.stroke_weight = weight; + } + DrawCommand::Rect { x, y, w, h, radii } => { + add_fill(&mut ctx, |mesh, color| { + rect(mesh, x, y, w, h, radii, color, TessellationMode::Fill) + }); + + add_stroke(&mut ctx, |mesh, color, weight| { + rect( + mesh, + x, + y, + w, + h, + radii, + color, + TessellationMode::Stroke(weight), + ) + }); + } + } + } + + flush_batch(&mut ctx); + } +} + +pub fn activate_cameras( + mut cameras: Query<&mut Camera>, + mut surfaces: Query<&Children, With>, +) { + for mut camera in cameras.iter_mut() { + camera.is_active = false; + } + + for children in surfaces.iter_mut() { + for child in children.iter() { + if let Ok(mut camera) = cameras.get_mut(child) { + camera.is_active = true; + } + } + } +} + +pub fn clear_transient_meshes( + mut commands: Commands, + surfaces: Query<&Children, With>, + transient_meshes: Query<(), With>, +) { + // for all flushing surfaces, despawn all transient meshes that rendered in a previous frame + for children in surfaces.iter() { + for child in children.iter() { + if transient_meshes.contains(child) { + commands.entity(child).despawn(); + } + } + } +} + +fn spawn_mesh(ctx: &mut RenderContext, mesh: Mesh, z_offset: Option) { + let Some(material_key) = &ctx.batch.material_key else { + return; + }; + let Some(surface_entity) = ctx.batch.surface_entity else { + return; + }; + + let mesh_handle = ctx.meshes.add(mesh); + let material_handle = ctx.materials.add(material_key.to_material()); + + let components = ( + Mesh3d(mesh_handle), + MeshMaterial3d(material_handle), + TransientMesh, + ctx.batch.render_layers.clone(), + ); + + let mesh_id = if let Some(z) = z_offset { + ctx.commands + .spawn((components, Transform::from_xyz(0.0, 0.0, z))) + .id() + } else { + ctx.commands.spawn(components).id() + }; + + ctx.commands.entity(surface_entity).add_child(mesh_id); +} + +fn add_fill(ctx: &mut RenderContext, tessellate: impl FnOnce(&mut Mesh, Color)) { + let Some(color) = ctx.state.fill_color else { + return; + }; + let material_key = MaterialKey { + transparent: ctx.state.fill_is_transparent(), + }; + + // when the material changes, flush the current batch + if ctx.batch.material_key.as_ref() != Some(&material_key) { + flush_batch(ctx); + ctx.batch.material_key = Some(material_key); + ctx.batch.current_mesh = Some(empty_mesh()); + } + + // accumulate geometry into the current mega mesh + if let Some(ref mut mesh) = ctx.batch.current_mesh { + tessellate(mesh, color); + } +} + +fn add_stroke(ctx: &mut RenderContext, tessellate: impl FnOnce(&mut Mesh, Color, f32)) { + let Some(color) = ctx.state.stroke_color else { + return; + }; + let stroke_weight = ctx.state.stroke_weight; + let material_key = MaterialKey { + transparent: ctx.state.stroke_is_transparent(), + }; + + // when the material changes, flush the current batch + if ctx.batch.material_key.as_ref() != Some(&material_key) { + flush_batch(ctx); + ctx.batch.material_key = Some(material_key); + ctx.batch.current_mesh = Some(empty_mesh()); + } + + // accumulate geometry into the current mega mesh + if let Some(ref mut mesh) = ctx.batch.current_mesh { + tessellate(mesh, color, stroke_weight); + } +} + +fn flush_batch(ctx: &mut RenderContext) { + if let Some(mesh) = ctx.batch.current_mesh.take() { + // we defensively apply a small z-offset based on draw_index to preserve painter's algorithm + let z_offset = ctx.batch.draw_index as f32 * -0.001; + spawn_mesh(ctx, mesh, Some(z_offset)); + ctx.batch.draw_index += 1; + } + ctx.batch.material_key = None; +} diff --git a/libProcessing/renderer/src/render/primitive/mod.rs b/libProcessing/renderer/src/render/primitive/mod.rs new file mode 100644 index 000000000..3d47dcd94 --- /dev/null +++ b/libProcessing/renderer/src/render/primitive/mod.rs @@ -0,0 +1,58 @@ +mod rect; + +use bevy::{ + asset::RenderAssetUsages, + mesh::{Indices, PrimitiveTopology}, + prelude::*, +}; +use lyon::{ + path::Path, + tessellation::{ + FillOptions, FillTessellator, LineCap, LineJoin, StrokeOptions, StrokeTessellator, + }, +}; +pub use rect::rect; + +use super::mesh_builder::MeshBuilder; + +pub enum TessellationMode { + Fill, + Stroke(f32), +} + +pub fn tessellate_path(mesh: &mut Mesh, path: &Path, color: Color, mode: TessellationMode) { + let mut builder = MeshBuilder::new(mesh, color); + match mode { + TessellationMode::Fill => { + let mut tessellator = FillTessellator::new(); + tessellator + .tessellate_path(path, &FillOptions::default(), &mut builder) + .expect("Failed to tessellate fill"); + } + TessellationMode::Stroke(weight) => { + let mut tessellator = StrokeTessellator::new(); + let options = StrokeOptions::default() + .with_line_width(weight) + .with_line_cap(LineCap::Round) + .with_line_join(LineJoin::Round); + + tessellator + .tessellate_path(path, &options, &mut builder) + .expect("Failed to tessellate stroke"); + } + } +} + +pub fn empty_mesh() -> Mesh { + let mut mesh = Mesh::new( + PrimitiveTopology::TriangleList, + RenderAssetUsages::default(), + ); + + mesh.insert_attribute(Mesh::ATTRIBUTE_POSITION, Vec::<[f32; 3]>::new()); + mesh.insert_attribute(Mesh::ATTRIBUTE_COLOR, Vec::<[f32; 4]>::new()); + mesh.insert_attribute(Mesh::ATTRIBUTE_NORMAL, Vec::<[f32; 3]>::new()); + mesh.insert_indices(Indices::U32(Vec::new())); + + mesh +} diff --git a/libProcessing/renderer/src/render/primitive/rect.rs b/libProcessing/renderer/src/render/primitive/rect.rs new file mode 100644 index 000000000..b176df0a2 --- /dev/null +++ b/libProcessing/renderer/src/render/primitive/rect.rs @@ -0,0 +1,112 @@ +use bevy::{ + mesh::{Indices, VertexAttributeValues}, + prelude::*, +}; +use lyon::{geom::Point, path::Path}; + +use crate::render::primitive::{TessellationMode, tessellate_path}; + +fn rect_path(x: f32, y: f32, w: f32, h: f32, radii: [f32; 4]) -> Path { + let mut path_builder = Path::builder(); + let [tl, tr, br, bl] = radii; + + // tl + path_builder.begin(Point::new(x + tl, y)); + + // tl -> tr + if tr > 0.0 { + path_builder.line_to(Point::new(x + w - tr, y)); + path_builder.quadratic_bezier_to(Point::new(x + w, y), Point::new(x + w, y + tr)); + } else { + path_builder.line_to(Point::new(x + w, y)); + } + + // tr -> br + if br > 0.0 { + path_builder.line_to(Point::new(x + w, y + h - br)); + path_builder.quadratic_bezier_to(Point::new(x + w, y + h), Point::new(x + w - br, y + h)); + } else { + path_builder.line_to(Point::new(x + w, y + h)); + } + + // br -> bl + if bl > 0.0 { + path_builder.line_to(Point::new(x + bl, y + h)); + path_builder.quadratic_bezier_to(Point::new(x, y + h), Point::new(x, y + h - bl)); + } else { + path_builder.line_to(Point::new(x, y + h)); + } + + // bl -> tl + if tl > 0.0 { + path_builder.line_to(Point::new(x, y + tl)); + path_builder.quadratic_bezier_to(Point::new(x, y), Point::new(x + tl, y)); + } + + path_builder.end(true); + path_builder.build() +} + +pub fn rect( + mesh: &mut Mesh, + x: f32, + y: f32, + w: f32, + h: f32, + radii: [f32; 4], // [tl, tr, br, bl] + color: Color, + mode: TessellationMode, +) { + if radii == [0.0; 4] && matches!(mode, TessellationMode::Fill) { + simple_rect(mesh, x, y, w, h, color); + } else { + let path = rect_path(x, y, w, h, radii); + tessellate_path(mesh, &path, color, mode); + } +} + +fn simple_rect(mesh: &mut Mesh, x: f32, y: f32, w: f32, h: f32, color: Color) { + let base_idx = if let Some(VertexAttributeValues::Float32x3(positions)) = + mesh.attribute(Mesh::ATTRIBUTE_POSITION) + { + positions.len() as u32 + } else { + 0 + }; + + if let Some(VertexAttributeValues::Float32x3(positions)) = + mesh.attribute_mut(Mesh::ATTRIBUTE_POSITION) + { + positions.push([x, y, 0.0]); + positions.push([x + w, y, 0.0]); + positions.push([x + w, y + h, 0.0]); + positions.push([x, y + h, 0.0]); + } + + if let Some(VertexAttributeValues::Float32x4(colors)) = + mesh.attribute_mut(Mesh::ATTRIBUTE_COLOR) + { + let color_array = color.to_srgba().to_f32_array(); + for _ in 0..4 { + colors.push(color_array); + } + } + + if let Some(VertexAttributeValues::Float32x3(normals)) = + mesh.attribute_mut(Mesh::ATTRIBUTE_NORMAL) + { + for _ in 0..4 { + normals.push([0.0, 0.0, 1.0]); + } + } + + if let Some(Indices::U32(indices)) = mesh.indices_mut() { + indices.push(base_idx + 0); + indices.push(base_idx + 1); + indices.push(base_idx + 2); + + indices.push(base_idx + 0); + indices.push(base_idx + 2); + indices.push(base_idx + 3); + } +} From f6eaf886c5efc25f151b266b99ad509e841ac796 Mon Sep 17 00:00:00 2001 From: "Moon D." Date: Fri, 21 Nov 2025 15:53:16 -0500 Subject: [PATCH 15/26] libprocessing submodule --- .gitignore | 2 +- .gitmodules | 3 + core/build.gradle.kts | 26 +- core/src/processing/webgpu/PWebGPU.java | 2 +- libProcessing/.gitignore | 2 - libProcessing/Cargo.lock | 6026 ----------------- libProcessing/Cargo.toml | 9 - libProcessing/ffi/Cargo.toml | 15 - libProcessing/ffi/build.rs | 27 - libProcessing/ffi/cbindgen.toml | 12 - libProcessing/ffi/src/color.rs | 15 - libProcessing/ffi/src/error.rs | 65 - libProcessing/ffi/src/lib.rs | 223 - libProcessing/renderer/Cargo.toml | 19 - libProcessing/renderer/src/error.rs | 17 - libProcessing/renderer/src/lib.rs | 427 -- libProcessing/renderer/src/render/command.rs | 38 - libProcessing/renderer/src/render/material.rs | 22 - .../renderer/src/render/mesh_builder.rs | 101 - libProcessing/renderer/src/render/mod.rs | 238 - .../renderer/src/render/primitive/mod.rs | 58 - .../renderer/src/render/primitive/rect.rs | 112 - libprocessing | 1 + 23 files changed, 19 insertions(+), 7441 deletions(-) create mode 100644 .gitmodules delete mode 100644 libProcessing/.gitignore delete mode 100644 libProcessing/Cargo.lock delete mode 100644 libProcessing/Cargo.toml delete mode 100644 libProcessing/ffi/Cargo.toml delete mode 100644 libProcessing/ffi/build.rs delete mode 100644 libProcessing/ffi/cbindgen.toml delete mode 100644 libProcessing/ffi/src/color.rs delete mode 100644 libProcessing/ffi/src/error.rs delete mode 100644 libProcessing/ffi/src/lib.rs delete mode 100644 libProcessing/renderer/Cargo.toml delete mode 100644 libProcessing/renderer/src/error.rs delete mode 100644 libProcessing/renderer/src/lib.rs delete mode 100644 libProcessing/renderer/src/render/command.rs delete mode 100644 libProcessing/renderer/src/render/material.rs delete mode 100644 libProcessing/renderer/src/render/mesh_builder.rs delete mode 100644 libProcessing/renderer/src/render/mod.rs delete mode 100644 libProcessing/renderer/src/render/primitive/mod.rs delete mode 100644 libProcessing/renderer/src/render/primitive/rect.rs create mode 160000 libprocessing diff --git a/.gitignore b/.gitignore index 6a81e3cf7..174115912 100644 --- a/.gitignore +++ b/.gitignore @@ -125,4 +125,4 @@ generated/ /java/gradle/build /java/gradle/example/.processing -libProcessing/ffi/include/* \ No newline at end of file +libprocessing/ffi/include/* diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 000000000..f430a4bd2 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "libprocessing"] + path = libprocessing + url = https://github.com/processing/libprocessing diff --git a/core/build.gradle.kts b/core/build.gradle.kts index e764f8e1c..7299016a4 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -64,25 +64,25 @@ dependencies { if (enableWebGPU) { val currentPlatform = PlatformUtils.detect() - val libProcessingDir = file("${project.rootDir}/libProcessing") - val rustTargetDir = file("$libProcessingDir/target") + val libprocessingDir = file("${project.rootDir}/libprocessing") + val rustTargetDir = file("$libprocessingDir/target") val nativeOutputDir = file("${layout.buildDirectory.get()}/native/${currentPlatform.target}") val buildRustRelease by tasks.registering(CargoBuildTask::class) { - cargoWorkspaceDir.set(libProcessingDir) + cargoWorkspaceDir.set(libprocessingDir) manifestPath.set("ffi/Cargo.toml") release.set(true) cargoPath.set(PlatformUtils.getCargoPath()) outputLibrary.set(file("$rustTargetDir/release/${currentPlatform.libName}")) - inputs.files(fileTree("$libProcessingDir/ffi/src")) - inputs.file("$libProcessingDir/ffi/Cargo.toml") - inputs.file("$libProcessingDir/ffi/build.rs") - inputs.file("$libProcessingDir/ffi/cbindgen.toml") - inputs.files(fileTree("$libProcessingDir/renderer/src")) - inputs.file("$libProcessingDir/renderer/Cargo.toml") - inputs.file("$libProcessingDir/Cargo.toml") - outputs.file("$libProcessingDir/ffi/include/processing.h") + inputs.files(fileTree("$libprocessingDir/ffi/src")) + inputs.file("$libprocessingDir/ffi/Cargo.toml") + inputs.file("$libprocessingDir/ffi/build.rs") + inputs.file("$libprocessingDir/ffi/cbindgen.toml") + inputs.files(fileTree("$libprocessingDir/renderer/src")) + inputs.file("$libprocessingDir/renderer/Cargo.toml") + inputs.file("$libprocessingDir/Cargo.toml") + outputs.file("$libprocessingDir/ffi/include/processing.h") } val copyNativeLibs by tasks.registering(Copy::class) { @@ -109,7 +109,7 @@ if (enableWebGPU) { } val cleanRust by tasks.registering(CargoCleanTask::class) { - cargoWorkspaceDir.set(libProcessingDir) + cargoWorkspaceDir.set(libprocessingDir) manifestPath.set("ffi/Cargo.toml") cargoPath.set(PlatformUtils.getCargoPath()) @@ -158,7 +158,7 @@ if (enableWebGPU) { dependsOn(downloadJextract, makeJextractExecutable) } - headerFile.set(file("$libProcessingDir/ffi/include/processing.h")) + headerFile.set(file("$libprocessingDir/ffi/include/processing.h")) outputDirectory.set(generatedJavaDir) targetPackage.set("processing.ffi") diff --git a/core/src/processing/webgpu/PWebGPU.java b/core/src/processing/webgpu/PWebGPU.java index fdc151262..e0a1a7630 100644 --- a/core/src/processing/webgpu/PWebGPU.java +++ b/core/src/processing/webgpu/PWebGPU.java @@ -10,7 +10,7 @@ import processing.ffi.Color; /** - * PWebGPU provides the native interface layer for libProcessing's WebGPU support. + * PWebGPU provides the native interface layer for libprocessing's WebGPU support. */ public class PWebGPU { diff --git a/libProcessing/.gitignore b/libProcessing/.gitignore deleted file mode 100644 index 66cc71077..000000000 --- a/libProcessing/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/target/ - diff --git a/libProcessing/Cargo.lock b/libProcessing/Cargo.lock deleted file mode 100644 index e8af7ea5f..000000000 --- a/libProcessing/Cargo.lock +++ /dev/null @@ -1,6026 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "ab_glyph" -version = "0.2.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01c0457472c38ea5bd1c3b5ada5e368271cb550be7a4ca4a0b4634e9913f6cc2" -dependencies = [ - "ab_glyph_rasterizer", - "owned_ttf_parser", -] - -[[package]] -name = "ab_glyph_rasterizer" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "366ffbaa4442f4684d91e2cd7c5ea7c4ed8add41959a31447066e279e432b618" - -[[package]] -name = "accesskit" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf203f9d3bd8f29f98833d1fbef628df18f759248a547e7e01cfbf63cda36a99" - -[[package]] -name = "accesskit_consumer" -version = "0.30.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdd06f5fea9819250fffd4debf926709f3593ac22f8c1541a2573e5ee0ca01cd" -dependencies = [ - "accesskit", - "hashbrown 0.15.5", -] - -[[package]] -name = "accesskit_macos" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fbaf15815f39084e0cb24950c232f0e3634702c2dfbf182ae3b4919a4a1d45" -dependencies = [ - "accesskit", - "accesskit_consumer", - "hashbrown 0.15.5", - "objc2 0.5.2", - "objc2-app-kit 0.2.2", - "objc2-foundation 0.2.2", -] - -[[package]] -name = "accesskit_windows" -version = "0.29.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "792991159fa9ba57459de59e12e918bb90c5346fea7d40ac1a11f8632b41e63a" -dependencies = [ - "accesskit", - "accesskit_consumer", - "hashbrown 0.15.5", - "static_assertions", - "windows 0.61.3", - "windows-core 0.61.2", -] - -[[package]] -name = "accesskit_winit" -version = "0.29.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd9db0ea66997e3f4eae4a5f2c6b6486cf206642639ee629dbbb860ace1dec87" -dependencies = [ - "accesskit", - "accesskit_macos", - "accesskit_windows", - "raw-window-handle", - "winit", -] - -[[package]] -name = "adler2" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" - -[[package]] -name = "ahash" -version = "0.8.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" -dependencies = [ - "cfg-if", - "getrandom", - "once_cell", - "version_check", - "zerocopy", -] - -[[package]] -name = "aho-corasick" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" -dependencies = [ - "memchr", -] - -[[package]] -name = "alsa" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed7572b7ba83a31e20d1b48970ee402d2e3e0537dcfe0a3ff4d6eb7508617d43" -dependencies = [ - "alsa-sys", - "bitflags 2.10.0", - "cfg-if", - "libc", -] - -[[package]] -name = "alsa-sys" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db8fee663d06c4e303404ef5f40488a53e062f89ba8bfed81f42325aafad1527" -dependencies = [ - "libc", - "pkg-config", -] - -[[package]] -name = "android-activity" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef6978589202a00cd7e118380c448a08b6ed394c3a8df3a430d0898e3a42d046" -dependencies = [ - "android-properties", - "bitflags 2.10.0", - "cc", - "cesu8", - "jni", - "jni-sys", - "libc", - "log", - "ndk 0.9.0", - "ndk-context", - "ndk-sys 0.6.0+11769913", - "num_enum", - "thiserror 1.0.69", -] - -[[package]] -name = "android-properties" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04" - -[[package]] -name = "android_log-sys" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84521a3cf562bc62942e294181d9eef17eb38ceb8c68677bc49f144e4c3d4f8d" - -[[package]] -name = "android_system_properties" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" -dependencies = [ - "libc", -] - -[[package]] -name = "anstream" -version = "0.6.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" -dependencies = [ - "anstyle", - "anstyle-parse", - "anstyle-query", - "anstyle-wincon", - "colorchoice", - "is_terminal_polyfill", - "utf8parse", -] - -[[package]] -name = "anstyle" -version = "1.0.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" - -[[package]] -name = "anstyle-parse" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" -dependencies = [ - "utf8parse", -] - -[[package]] -name = "anstyle-query" -version = "1.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2" -dependencies = [ - "windows-sys 0.60.2", -] - -[[package]] -name = "anstyle-wincon" -version = "3.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a" -dependencies = [ - "anstyle", - "once_cell_polyfill", - "windows-sys 0.60.2", -] - -[[package]] -name = "approx" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6" -dependencies = [ - "num-traits", -] - -[[package]] -name = "arrayref" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" - -[[package]] -name = "arrayvec" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" - -[[package]] -name = "as-raw-xcb-connection" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "175571dd1d178ced59193a6fc02dde1b972eb0bc56c892cde9beeceac5bf0f6b" - -[[package]] -name = "ash" -version = "0.38.0+1.3.281" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bb44936d800fea8f016d7f2311c6a4f97aebd5dc86f09906139ec848cf3a46f" -dependencies = [ - "libloading", -] - -[[package]] -name = "assert_type_match" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f548ad2c4031f2902e3edc1f29c29e835829437de49562d8eb5dc5584d3a1043" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "async-broadcast" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "435a87a52755b8f27fcf321ac4f04b2802e337c8c4872923137471ec39c37532" -dependencies = [ - "event-listener", - "event-listener-strategy", - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "async-channel" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "924ed96dd52d1b75e9c1a3e6275715fd320f5f9439fb5a4a11fa51f4221158d2" -dependencies = [ - "concurrent-queue", - "event-listener-strategy", - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "async-executor" -version = "1.13.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497c00e0fd83a72a79a39fcbd8e3e2f055d6f6c7e025f3b3d91f4f8e76527fb8" -dependencies = [ - "async-task", - "concurrent-queue", - "fastrand", - "futures-lite", - "pin-project-lite", - "slab", -] - -[[package]] -name = "async-fs" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8034a681df4aed8b8edbd7fbe472401ecf009251c8b40556b304567052e294c5" -dependencies = [ - "async-lock", - "blocking", - "futures-lite", -] - -[[package]] -name = "async-lock" -version = "3.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fd03604047cee9b6ce9de9f70c6cd540a0520c813cbd49bae61f33ab80ed1dc" -dependencies = [ - "event-listener", - "event-listener-strategy", - "pin-project-lite", -] - -[[package]] -name = "async-task" -version = "4.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" -dependencies = [ - "portable-atomic", -] - -[[package]] -name = "atomic-waker" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" -dependencies = [ - "portable-atomic", -] - -[[package]] -name = "atomicow" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f52e8890bb9844440d0c412fa74b67fd2f14e85248b6e00708059b6da9e5f8bf" -dependencies = [ - "portable-atomic", - "portable-atomic-util", -] - -[[package]] -name = "autocfg" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" - -[[package]] -name = "base64" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" - -[[package]] -name = "bevy" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "342f7e9335416dc98642d5747c4ed8a6ad9f7244a36d5b2b7a1b7910e4d8f524" -dependencies = [ - "bevy_internal", -] - -[[package]] -name = "bevy_a11y" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3917cd35096fb2fe176632740b68a4b53cb61006cfff13d66ef47ee2c2478d53" -dependencies = [ - "accesskit", - "bevy_app", - "bevy_derive", - "bevy_ecs", - "bevy_reflect", -] - -[[package]] -name = "bevy_android" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2a9dd9488c77fa2ea31b5da2f978aab7f1cc82e6d2c3be0adf637d9fd7cb6c8" -dependencies = [ - "android-activity", -] - -[[package]] -name = "bevy_animation" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00d2eadb9c20d87ab3a5528a8df483492d5b8102d3f2d61c7b1ed23f40a79166" -dependencies = [ - "bevy_animation_macros", - "bevy_app", - "bevy_asset", - "bevy_color", - "bevy_derive", - "bevy_ecs", - "bevy_math", - "bevy_mesh", - "bevy_platform", - "bevy_reflect", - "bevy_time", - "bevy_transform", - "bevy_utils", - "blake3", - "derive_more", - "downcast-rs 2.0.2", - "either", - "petgraph", - "ron", - "serde", - "smallvec", - "thiserror 2.0.17", - "thread_local", - "tracing", - "uuid", -] - -[[package]] -name = "bevy_animation_macros" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aec80b84926f730f6df81b9bc07255c120f57aaf7ac577f38d12dd8e1a0268ad" -dependencies = [ - "bevy_macro_utils", - "quote", - "syn", -] - -[[package]] -name = "bevy_anti_alias" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38c1adb85fe0956d6c3b6f90777b829785bb7e29a48f58febeeefd2bad317713" -dependencies = [ - "bevy_app", - "bevy_asset", - "bevy_camera", - "bevy_core_pipeline", - "bevy_derive", - "bevy_diagnostic", - "bevy_ecs", - "bevy_image", - "bevy_math", - "bevy_reflect", - "bevy_render", - "bevy_shader", - "bevy_utils", - "tracing", -] - -[[package]] -name = "bevy_app" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f582409b4ed3850d9b66ee94e71a0e2c20e7068121d372530060c4dfcba66fa" -dependencies = [ - "bevy_derive", - "bevy_ecs", - "bevy_platform", - "bevy_reflect", - "bevy_tasks", - "bevy_utils", - "cfg-if", - "console_error_panic_hook", - "ctrlc", - "downcast-rs 2.0.2", - "log", - "thiserror 2.0.17", - "variadics_please", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "bevy_asset" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e6ee42e74a64a46ab91bd1c0155f8abe5b732bdb948a9b26e541456cc7940e5" -dependencies = [ - "async-broadcast", - "async-fs", - "async-lock", - "atomicow", - "bevy_android", - "bevy_app", - "bevy_asset_macros", - "bevy_ecs", - "bevy_platform", - "bevy_reflect", - "bevy_tasks", - "bevy_utils", - "bitflags 2.10.0", - "blake3", - "crossbeam-channel", - "derive_more", - "disqualified", - "downcast-rs 2.0.2", - "either", - "futures-io", - "futures-lite", - "js-sys", - "parking_lot", - "ron", - "serde", - "stackfuture", - "thiserror 2.0.17", - "tracing", - "uuid", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", -] - -[[package]] -name = "bevy_asset_macros" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d03711d2c087227f64ba85dd38a99d4d6893f80d2475c2e77fb90a883760a055" -dependencies = [ - "bevy_macro_utils", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "bevy_audio" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f83620c82f281848c02ed4b65133a0364512b4eca2b39cd21a171e50e2986d89" -dependencies = [ - "bevy_app", - "bevy_asset", - "bevy_ecs", - "bevy_math", - "bevy_reflect", - "bevy_transform", - "coreaudio-sys", - "cpal", - "rodio", - "tracing", -] - -[[package]] -name = "bevy_camera" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b70d79ccbd8bfefc79f33a104dfd82ae2f5276ce04d6df75787bfa3edc4c4c1a" -dependencies = [ - "bevy_app", - "bevy_asset", - "bevy_color", - "bevy_derive", - "bevy_ecs", - "bevy_image", - "bevy_math", - "bevy_mesh", - "bevy_reflect", - "bevy_transform", - "bevy_utils", - "bevy_window", - "derive_more", - "downcast-rs 2.0.2", - "serde", - "smallvec", - "thiserror 2.0.17", - "wgpu-types", -] - -[[package]] -name = "bevy_color" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94dc78477c1c208c0cd221c64e907aba8ba165f39bebb72adc6180e1a13e8938" -dependencies = [ - "bevy_math", - "bevy_reflect", - "bytemuck", - "derive_more", - "encase", - "serde", - "thiserror 2.0.17", - "wgpu-types", -] - -[[package]] -name = "bevy_core_pipeline" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c866a2fe33ec27a612d883223d30f1857aa852766b21a9603628735dace632f" -dependencies = [ - "bevy_app", - "bevy_asset", - "bevy_camera", - "bevy_color", - "bevy_derive", - "bevy_ecs", - "bevy_image", - "bevy_math", - "bevy_platform", - "bevy_reflect", - "bevy_render", - "bevy_shader", - "bevy_transform", - "bevy_utils", - "bevy_window", - "bitflags 2.10.0", - "nonmax", - "radsort", - "smallvec", - "thiserror 2.0.17", - "tracing", -] - -[[package]] -name = "bevy_derive" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8c733807158f8fcac68e23222e69ed91a6492ae9410fc2c145b9bb182cfd63e" -dependencies = [ - "bevy_macro_utils", - "quote", - "syn", -] - -[[package]] -name = "bevy_diagnostic" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f12fa32312818c08aa4035bebe9fb3f62aaf7efae33688e718dd6ee6c0147493" -dependencies = [ - "atomic-waker", - "bevy_app", - "bevy_ecs", - "bevy_platform", - "bevy_tasks", - "bevy_time", - "const-fnv1a-hash", - "log", - "serde", - "sysinfo", -] - -[[package]] -name = "bevy_ecs" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69d929d32190cfcde6efd2df493601c4dbc18a691fd9775a544c951c3c112e1a" -dependencies = [ - "arrayvec", - "bevy_ecs_macros", - "bevy_platform", - "bevy_ptr", - "bevy_reflect", - "bevy_tasks", - "bevy_utils", - "bitflags 2.10.0", - "bumpalo", - "concurrent-queue", - "derive_more", - "fixedbitset", - "indexmap", - "log", - "nonmax", - "serde", - "slotmap", - "smallvec", - "thiserror 2.0.17", - "variadics_please", -] - -[[package]] -name = "bevy_ecs_macros" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6eeddfb80a2e000663e87be9229c26b4da92bddbc06c8776bc0d1f4a7f679079" -dependencies = [ - "bevy_macro_utils", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "bevy_encase_derive" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7449e5903594a00f007732ba232af0c527ad4e6e3d29bc3e195ec78dbd20c8b2" -dependencies = [ - "bevy_macro_utils", - "encase_derive_impl", -] - -[[package]] -name = "bevy_gilrs" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28ff35087f25406006338e6d57f31f313a60f3a5e09990ab7c7b5203b0b55077" -dependencies = [ - "bevy_app", - "bevy_ecs", - "bevy_input", - "bevy_platform", - "bevy_time", - "gilrs", - "thiserror 2.0.17", - "tracing", -] - -[[package]] -name = "bevy_gizmos" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d3f174faa13041634060dd99f6f59c29997fd62f40252f0466c2ebea8603d4d" -dependencies = [ - "bevy_app", - "bevy_asset", - "bevy_camera", - "bevy_color", - "bevy_core_pipeline", - "bevy_ecs", - "bevy_gizmos_macros", - "bevy_image", - "bevy_light", - "bevy_math", - "bevy_mesh", - "bevy_pbr", - "bevy_reflect", - "bevy_render", - "bevy_shader", - "bevy_sprite_render", - "bevy_time", - "bevy_transform", - "bevy_utils", - "bytemuck", - "tracing", -] - -[[package]] -name = "bevy_gizmos_macros" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "714273aa7f285c0aaa874b7fbe37fe4e6e45355e3e6f3321aefa1b78cda259e0" -dependencies = [ - "bevy_macro_utils", - "quote", - "syn", -] - -[[package]] -name = "bevy_gltf" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13d67e954b20551818f7cdb33f169ab4db64506ada66eb4d60d3cb8861103411" -dependencies = [ - "base64", - "bevy_animation", - "bevy_app", - "bevy_asset", - "bevy_camera", - "bevy_color", - "bevy_ecs", - "bevy_image", - "bevy_light", - "bevy_math", - "bevy_mesh", - "bevy_pbr", - "bevy_platform", - "bevy_reflect", - "bevy_render", - "bevy_scene", - "bevy_tasks", - "bevy_transform", - "fixedbitset", - "gltf", - "itertools 0.14.0", - "percent-encoding", - "serde", - "serde_json", - "smallvec", - "thiserror 2.0.17", - "tracing", -] - -[[package]] -name = "bevy_image" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "168de8239b2aedd2eeef9f76ae1909b2fdf859b11dcdb4d4d01b93f5f2c771be" -dependencies = [ - "bevy_app", - "bevy_asset", - "bevy_color", - "bevy_ecs", - "bevy_math", - "bevy_platform", - "bevy_reflect", - "bevy_utils", - "bitflags 2.10.0", - "bytemuck", - "futures-lite", - "guillotiere", - "half", - "image", - "ktx2", - "rectangle-pack", - "ruzstd", - "serde", - "thiserror 2.0.17", - "tracing", - "wgpu-types", -] - -[[package]] -name = "bevy_input" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cf4074b2d0d6680b4deb308ded7b4e8b1b99181c0502e2632e78af815b26f01" -dependencies = [ - "bevy_app", - "bevy_ecs", - "bevy_math", - "bevy_platform", - "bevy_reflect", - "derive_more", - "log", - "smol_str", - "thiserror 2.0.17", -] - -[[package]] -name = "bevy_input_focus" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70761eba0f616a1caa761457bff2b8ae80c9916f39d167fab8c2d5c98d2b8951" -dependencies = [ - "bevy_app", - "bevy_ecs", - "bevy_input", - "bevy_math", - "bevy_picking", - "bevy_reflect", - "bevy_window", - "log", - "thiserror 2.0.17", -] - -[[package]] -name = "bevy_internal" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43985739584f3a5d43026aa1edd772f064830be46c497518f05f7dfbc886bba" -dependencies = [ - "bevy_a11y", - "bevy_android", - "bevy_animation", - "bevy_anti_alias", - "bevy_app", - "bevy_asset", - "bevy_audio", - "bevy_camera", - "bevy_color", - "bevy_core_pipeline", - "bevy_derive", - "bevy_diagnostic", - "bevy_ecs", - "bevy_gilrs", - "bevy_gizmos", - "bevy_gltf", - "bevy_image", - "bevy_input", - "bevy_input_focus", - "bevy_light", - "bevy_log", - "bevy_math", - "bevy_mesh", - "bevy_pbr", - "bevy_picking", - "bevy_platform", - "bevy_post_process", - "bevy_ptr", - "bevy_reflect", - "bevy_render", - "bevy_scene", - "bevy_shader", - "bevy_sprite", - "bevy_sprite_render", - "bevy_state", - "bevy_tasks", - "bevy_text", - "bevy_time", - "bevy_transform", - "bevy_ui", - "bevy_ui_render", - "bevy_utils", - "bevy_window", - "bevy_winit", -] - -[[package]] -name = "bevy_light" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cad00ab66d1e93edb928be66606a71066f3b1cbc9f414720e290ef5361eb6237" -dependencies = [ - "bevy_app", - "bevy_asset", - "bevy_camera", - "bevy_color", - "bevy_ecs", - "bevy_image", - "bevy_math", - "bevy_mesh", - "bevy_platform", - "bevy_reflect", - "bevy_transform", - "bevy_utils", - "tracing", -] - -[[package]] -name = "bevy_log" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ae217a035714a37b779487f82edc4c7c1223f7088d7ad94054f29f524d61c51" -dependencies = [ - "android_log-sys", - "bevy_app", - "bevy_ecs", - "bevy_platform", - "bevy_utils", - "tracing", - "tracing-log", - "tracing-oslog", - "tracing-subscriber", - "tracing-wasm", -] - -[[package]] -name = "bevy_macro_utils" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17dbc3f8948da58b3c17767d20fd3cd35fe4721ed19a9a3204a6f1d6c9951bdd" -dependencies = [ - "parking_lot", - "proc-macro2", - "quote", - "syn", - "toml_edit 0.23.7", -] - -[[package]] -name = "bevy_math" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7a41e368ffa95ae2a353197d1ae3993f4d3d471444d80b65c932db667ea7b9e" -dependencies = [ - "approx", - "bevy_reflect", - "derive_more", - "glam", - "itertools 0.14.0", - "libm", - "rand", - "rand_distr", - "serde", - "smallvec", - "thiserror 2.0.17", - "variadics_please", -] - -[[package]] -name = "bevy_mesh" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6255244b71153b305fddb4e6f827cb97ed51f276b6e632f5fc46538647948f6" -dependencies = [ - "bevy_app", - "bevy_asset", - "bevy_derive", - "bevy_ecs", - "bevy_image", - "bevy_math", - "bevy_mikktspace", - "bevy_platform", - "bevy_reflect", - "bevy_transform", - "bitflags 2.10.0", - "bytemuck", - "derive_more", - "hexasphere", - "thiserror 2.0.17", - "tracing", - "wgpu-types", -] - -[[package]] -name = "bevy_mikktspace" -version = "0.17.0-dev" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef8e4b7e61dfe7719bb03c884dc270cd46a82efb40f93e9933b990c5c190c59" - -[[package]] -name = "bevy_pbr" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf8c76337a6ae9d73d50be168aeee974d05fdeda9129a413eaff719e3b7b5fea" -dependencies = [ - "bevy_app", - "bevy_asset", - "bevy_camera", - "bevy_color", - "bevy_core_pipeline", - "bevy_derive", - "bevy_diagnostic", - "bevy_ecs", - "bevy_image", - "bevy_light", - "bevy_math", - "bevy_mesh", - "bevy_platform", - "bevy_reflect", - "bevy_render", - "bevy_shader", - "bevy_transform", - "bevy_utils", - "bitflags 2.10.0", - "bytemuck", - "derive_more", - "fixedbitset", - "nonmax", - "offset-allocator", - "smallvec", - "static_assertions", - "thiserror 2.0.17", - "tracing", -] - -[[package]] -name = "bevy_picking" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a232a8ea4dc9b83c08226f56b868acb1ead06946a95d8b9c8cbbcc860cd8090" -dependencies = [ - "bevy_app", - "bevy_asset", - "bevy_camera", - "bevy_derive", - "bevy_ecs", - "bevy_input", - "bevy_math", - "bevy_mesh", - "bevy_platform", - "bevy_reflect", - "bevy_time", - "bevy_transform", - "bevy_window", - "crossbeam-channel", - "tracing", - "uuid", -] - -[[package]] -name = "bevy_platform" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10cf8cda162688c95250e74cffaa1c3a04597f105d4ca35554106f107308ea57" -dependencies = [ - "critical-section", - "foldhash 0.2.0", - "futures-channel", - "getrandom", - "hashbrown 0.16.0", - "js-sys", - "portable-atomic", - "portable-atomic-util", - "serde", - "spin", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-time", -] - -[[package]] -name = "bevy_post_process" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26ee8ab6043f8bbe43e9c16bbdde0c5e7289b99e62cd8aad1a2a4166a7f2bce6" -dependencies = [ - "bevy_app", - "bevy_asset", - "bevy_camera", - "bevy_color", - "bevy_core_pipeline", - "bevy_derive", - "bevy_ecs", - "bevy_image", - "bevy_math", - "bevy_platform", - "bevy_reflect", - "bevy_render", - "bevy_shader", - "bevy_transform", - "bevy_utils", - "bevy_window", - "bitflags 2.10.0", - "nonmax", - "radsort", - "smallvec", - "thiserror 2.0.17", - "tracing", -] - -[[package]] -name = "bevy_ptr" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28ab4074e7b781bab84e9b0a41ede245d673d1f75646ce0db27643aedcfb3a85" - -[[package]] -name = "bevy_reflect" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "333df3f5947b7e62728eb5c0b51d679716b16c7c5283118fed4563f13230954e" -dependencies = [ - "assert_type_match", - "bevy_platform", - "bevy_ptr", - "bevy_reflect_derive", - "bevy_utils", - "derive_more", - "disqualified", - "downcast-rs 2.0.2", - "erased-serde", - "foldhash 0.2.0", - "glam", - "inventory", - "petgraph", - "serde", - "smallvec", - "smol_str", - "thiserror 2.0.17", - "uuid", - "variadics_please", - "wgpu-types", -] - -[[package]] -name = "bevy_reflect_derive" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0205dce9c5a4d8d041b263bcfd96e9d9d6f3d49416e12db347ab5778b3071fe1" -dependencies = [ - "bevy_macro_utils", - "indexmap", - "proc-macro2", - "quote", - "syn", - "uuid", -] - -[[package]] -name = "bevy_render" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70d6a5d47ebb247e4ecaaf4a3b0310b7c518728ff2362c69f4220d0d3228e17d" -dependencies = [ - "async-channel", - "bevy_app", - "bevy_asset", - "bevy_camera", - "bevy_color", - "bevy_derive", - "bevy_diagnostic", - "bevy_ecs", - "bevy_encase_derive", - "bevy_image", - "bevy_math", - "bevy_mesh", - "bevy_platform", - "bevy_reflect", - "bevy_render_macros", - "bevy_shader", - "bevy_tasks", - "bevy_time", - "bevy_transform", - "bevy_utils", - "bevy_window", - "bitflags 2.10.0", - "bytemuck", - "derive_more", - "downcast-rs 2.0.2", - "encase", - "fixedbitset", - "image", - "indexmap", - "js-sys", - "naga", - "nonmax", - "offset-allocator", - "send_wrapper", - "smallvec", - "thiserror 2.0.17", - "tracing", - "variadics_please", - "wasm-bindgen", - "web-sys", - "wgpu", -] - -[[package]] -name = "bevy_render_macros" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7e8b553adf0a4f9f059c5c2dcb52d9ac09abede1c322a92b43b9f4bb11c3843" -dependencies = [ - "bevy_macro_utils", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "bevy_scene" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e601ffeebbdaba1193f823dbdc9fc8787a24cf83225a72fee4def5c27a18778a" -dependencies = [ - "bevy_app", - "bevy_asset", - "bevy_camera", - "bevy_derive", - "bevy_ecs", - "bevy_platform", - "bevy_reflect", - "bevy_transform", - "bevy_utils", - "derive_more", - "serde", - "thiserror 2.0.17", - "uuid", -] - -[[package]] -name = "bevy_shader" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cef8f8e53776d286eb62bb60164f30671f07005ff407e94ec1176e9426d1477" -dependencies = [ - "bevy_asset", - "bevy_platform", - "bevy_reflect", - "naga", - "naga_oil", - "serde", - "thiserror 2.0.17", - "tracing", - "wgpu-types", -] - -[[package]] -name = "bevy_sprite" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74bb52fa52caa1cc8d95acf45e52efc0c72b59755c2f0801a30fdab367921db0" -dependencies = [ - "bevy_app", - "bevy_asset", - "bevy_camera", - "bevy_color", - "bevy_derive", - "bevy_ecs", - "bevy_image", - "bevy_math", - "bevy_mesh", - "bevy_picking", - "bevy_reflect", - "bevy_text", - "bevy_transform", - "bevy_window", - "radsort", - "tracing", - "wgpu-types", -] - -[[package]] -name = "bevy_sprite_render" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31bb90a9139b04568bd30b2492ba61234092d95a7f7e3c84b55369b16d7e261b" -dependencies = [ - "bevy_app", - "bevy_asset", - "bevy_camera", - "bevy_color", - "bevy_core_pipeline", - "bevy_derive", - "bevy_ecs", - "bevy_image", - "bevy_math", - "bevy_mesh", - "bevy_platform", - "bevy_reflect", - "bevy_render", - "bevy_shader", - "bevy_sprite", - "bevy_text", - "bevy_transform", - "bevy_utils", - "bitflags 2.10.0", - "bytemuck", - "derive_more", - "fixedbitset", - "nonmax", - "tracing", -] - -[[package]] -name = "bevy_state" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe4e955f36cdc7b31556e4619a653dcf65d46967d90d36fb788f746c8e89257e" -dependencies = [ - "bevy_app", - "bevy_ecs", - "bevy_platform", - "bevy_reflect", - "bevy_state_macros", - "bevy_utils", - "log", - "variadics_please", -] - -[[package]] -name = "bevy_state_macros" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c3e4e32b1b96585740a2b447661af7db1b9d688db5e4d96da50461cd8f5ce63" -dependencies = [ - "bevy_macro_utils", - "quote", - "syn", -] - -[[package]] -name = "bevy_tasks" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18839182775f30d26f0f84d9de85d25361bb593c99517a80b64ede6cbaf41adc" -dependencies = [ - "async-channel", - "async-executor", - "async-task", - "atomic-waker", - "bevy_platform", - "concurrent-queue", - "crossbeam-queue", - "derive_more", - "futures-lite", - "heapless", - "pin-project", -] - -[[package]] -name = "bevy_text" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc1b759cf2ed8992132bd541ebb9ffcfa777d2faf3596d418fb25984bc6677d8" -dependencies = [ - "bevy_app", - "bevy_asset", - "bevy_color", - "bevy_derive", - "bevy_ecs", - "bevy_image", - "bevy_log", - "bevy_math", - "bevy_platform", - "bevy_reflect", - "bevy_utils", - "cosmic-text", - "serde", - "smallvec", - "sys-locale", - "thiserror 2.0.17", - "tracing", - "wgpu-types", -] - -[[package]] -name = "bevy_time" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a52edd3d30ed94074f646ba1c9914e407af9abe5b6fb7a4322c855341a536cc" -dependencies = [ - "bevy_app", - "bevy_ecs", - "bevy_platform", - "bevy_reflect", - "crossbeam-channel", - "log", - "serde", -] - -[[package]] -name = "bevy_transform" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7995ae14430b1a268d1e4f098ab770e8af880d2df5e4e37161b47d8d9e9625bd" -dependencies = [ - "bevy_app", - "bevy_ecs", - "bevy_log", - "bevy_math", - "bevy_reflect", - "bevy_tasks", - "bevy_utils", - "derive_more", - "serde", - "thiserror 2.0.17", -] - -[[package]] -name = "bevy_ui" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc999815a67a6b2fc911df9eea27af703ff656aed6fd31d8606dced701f07fd6" -dependencies = [ - "accesskit", - "bevy_a11y", - "bevy_app", - "bevy_asset", - "bevy_camera", - "bevy_color", - "bevy_derive", - "bevy_ecs", - "bevy_image", - "bevy_input", - "bevy_math", - "bevy_picking", - "bevy_platform", - "bevy_reflect", - "bevy_sprite", - "bevy_text", - "bevy_transform", - "bevy_utils", - "bevy_window", - "derive_more", - "smallvec", - "taffy", - "thiserror 2.0.17", - "tracing", - "uuid", -] - -[[package]] -name = "bevy_ui_render" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adae9770089e04339d003afe7abe7153fe71600d81c828f964c7ac329b04d5b9" -dependencies = [ - "bevy_app", - "bevy_asset", - "bevy_camera", - "bevy_color", - "bevy_core_pipeline", - "bevy_derive", - "bevy_ecs", - "bevy_image", - "bevy_math", - "bevy_mesh", - "bevy_platform", - "bevy_reflect", - "bevy_render", - "bevy_shader", - "bevy_sprite", - "bevy_sprite_render", - "bevy_text", - "bevy_transform", - "bevy_ui", - "bevy_utils", - "bytemuck", - "derive_more", - "tracing", -] - -[[package]] -name = "bevy_utils" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "080254083c74d5f6eb0649d7cd6181bda277e8fe3c509ec68990a5d56ec23f24" -dependencies = [ - "bevy_platform", - "disqualified", - "thread_local", -] - -[[package]] -name = "bevy_window" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f582478606d6b6e5c53befbe7612f038fdfb73f8a27f7aae644406637347acd4" -dependencies = [ - "bevy_app", - "bevy_asset", - "bevy_ecs", - "bevy_image", - "bevy_input", - "bevy_math", - "bevy_platform", - "bevy_reflect", - "log", - "raw-window-handle", - "serde", -] - -[[package]] -name = "bevy_winit" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb0ccf2faca4b4c156a26284d1bbf90a8cac8568a273adcd6c1a270c1342f3df" -dependencies = [ - "accesskit", - "accesskit_winit", - "approx", - "bevy_a11y", - "bevy_android", - "bevy_app", - "bevy_asset", - "bevy_derive", - "bevy_ecs", - "bevy_image", - "bevy_input", - "bevy_input_focus", - "bevy_log", - "bevy_math", - "bevy_platform", - "bevy_reflect", - "bevy_tasks", - "bevy_window", - "bytemuck", - "cfg-if", - "tracing", - "wasm-bindgen", - "web-sys", - "wgpu-types", - "winit", -] - -[[package]] -name = "bindgen" -version = "0.72.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895" -dependencies = [ - "bitflags 2.10.0", - "cexpr", - "clang-sys", - "itertools 0.13.0", - "proc-macro2", - "quote", - "regex", - "rustc-hash 2.1.1", - "shlex", - "syn", -] - -[[package]] -name = "bit-set" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" -dependencies = [ - "bit-vec", -] - -[[package]] -name = "bit-vec" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bitflags" -version = "2.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" -dependencies = [ - "bytemuck", - "serde_core", -] - -[[package]] -name = "blake3" -version = "1.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3888aaa89e4b2a40fca9848e400f6a658a5a3978de7be858e209cafa8be9a4a0" -dependencies = [ - "arrayref", - "arrayvec", - "cc", - "cfg-if", - "constant_time_eq", -] - -[[package]] -name = "block" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" - -[[package]] -name = "block2" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f" -dependencies = [ - "objc2 0.5.2", -] - -[[package]] -name = "block2" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdeb9d870516001442e364c5220d3574d2da8dc765554b4a617230d33fa58ef5" -dependencies = [ - "objc2 0.6.3", -] - -[[package]] -name = "blocking" -version = "1.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e83f8d02be6967315521be875afa792a316e28d57b5a2d401897e2a7921b7f21" -dependencies = [ - "async-channel", - "async-task", - "futures-io", - "futures-lite", - "piper", -] - -[[package]] -name = "bumpalo" -version = "3.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" - -[[package]] -name = "bytemuck" -version = "1.24.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fbdf580320f38b612e485521afda1ee26d10cc9884efaaa750d383e13e3c5f4" -dependencies = [ - "bytemuck_derive", -] - -[[package]] -name = "bytemuck_derive" -version = "1.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9abbd1bc6865053c427f7198e6af43bfdedc55ab791faed4fbd361d789575ff" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - -[[package]] -name = "byteorder-lite" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" - -[[package]] -name = "bytes" -version = "1.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" - -[[package]] -name = "calloop" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b99da2f8558ca23c71f4fd15dc57c906239752dd27ff3c00a1d56b685b7cbfec" -dependencies = [ - "bitflags 2.10.0", - "log", - "polling", - "rustix 0.38.44", - "slab", - "thiserror 1.0.69", -] - -[[package]] -name = "calloop-wayland-source" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95a66a987056935f7efce4ab5668920b5d0dac4a7c99991a67395f13702ddd20" -dependencies = [ - "calloop", - "rustix 0.38.44", - "wayland-backend", - "wayland-client", -] - -[[package]] -name = "cbindgen" -version = "0.29.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "975982cdb7ad6a142be15bdf84aea7ec6a9e5d4d797c004d43185b24cfe4e684" -dependencies = [ - "clap", - "heck", - "indexmap", - "log", - "proc-macro2", - "quote", - "serde", - "serde_json", - "syn", - "tempfile", - "toml", -] - -[[package]] -name = "cc" -version = "1.2.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac9fe6cdbb24b6ade63616c0a0688e45bb56732262c158df3c0c4bea4ca47cb7" -dependencies = [ - "find-msvc-tools", - "jobserver", - "libc", - "shlex", -] - -[[package]] -name = "cesu8" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" - -[[package]] -name = "cexpr" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" -dependencies = [ - "nom", -] - -[[package]] -name = "cfg-if" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" - -[[package]] -name = "cfg_aliases" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" - -[[package]] -name = "clang-sys" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" -dependencies = [ - "glob", - "libc", - "libloading", -] - -[[package]] -name = "clap" -version = "4.5.49" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4512b90fa68d3a9932cea5184017c5d200f5921df706d45e853537dea51508f" -dependencies = [ - "clap_builder", -] - -[[package]] -name = "clap_builder" -version = "4.5.49" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0025e98baa12e766c67ba13ff4695a887a1eba19569aad00a472546795bd6730" -dependencies = [ - "anstream", - "anstyle", - "clap_lex", - "strsim", -] - -[[package]] -name = "clap_lex" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" - -[[package]] -name = "codespan-reporting" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe6d2e5af09e8c8ad56c969f2157a3d4238cebc7c55f0a517728c38f7b200f81" -dependencies = [ - "serde", - "termcolor", - "unicode-width", -] - -[[package]] -name = "colorchoice" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" - -[[package]] -name = "combine" -version = "4.6.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" -dependencies = [ - "bytes", - "memchr", -] - -[[package]] -name = "concurrent-queue" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" -dependencies = [ - "crossbeam-utils", - "portable-atomic", -] - -[[package]] -name = "console_error_panic_hook" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" -dependencies = [ - "cfg-if", - "wasm-bindgen", -] - -[[package]] -name = "const-fnv1a-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32b13ea120a812beba79e34316b3942a857c86ec1593cb34f27bb28272ce2cca" - -[[package]] -name = "const_panic" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e262cdaac42494e3ae34c43969f9cdeb7da178bdb4b66fa6a1ea2edb4c8ae652" -dependencies = [ - "typewit", -] - -[[package]] -name = "const_soft_float" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87ca1caa64ef4ed453e68bb3db612e51cf1b2f5b871337f0fcab1c8f87cc3dff" - -[[package]] -name = "constant_time_eq" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" - -[[package]] -name = "constgebra" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1aaf9b65849a68662ac6c0810c8893a765c960b907dd7cfab9c4a50bf764fbc" -dependencies = [ - "const_soft_float", -] - -[[package]] -name = "core-foundation" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "core-foundation" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" - -[[package]] -name = "core-graphics" -version = "0.23.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c07782be35f9e1140080c6b96f0d44b739e2278479f64e02fdab4e32dfd8b081" -dependencies = [ - "bitflags 1.3.2", - "core-foundation 0.9.4", - "core-graphics-types 0.1.3", - "foreign-types", - "libc", -] - -[[package]] -name = "core-graphics-types" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" -dependencies = [ - "bitflags 1.3.2", - "core-foundation 0.9.4", - "libc", -] - -[[package]] -name = "core-graphics-types" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d44a101f213f6c4cdc1853d4b78aef6db6bdfa3468798cc1d9912f4735013eb" -dependencies = [ - "bitflags 2.10.0", - "core-foundation 0.10.1", - "libc", -] - -[[package]] -name = "coreaudio-rs" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "321077172d79c662f64f5071a03120748d5bb652f5231570141be24cfcd2bace" -dependencies = [ - "bitflags 1.3.2", - "core-foundation-sys", - "coreaudio-sys", -] - -[[package]] -name = "coreaudio-sys" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ceec7a6067e62d6f931a2baf6f3a751f4a892595bcec1461a3c94ef9949864b6" -dependencies = [ - "bindgen", -] - -[[package]] -name = "cosmic-text" -version = "0.14.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da46a9d5a8905cc538a4a5bceb6a4510de7a51049c5588c0114efce102bcbbe8" -dependencies = [ - "bitflags 2.10.0", - "fontdb", - "log", - "rangemap", - "rustc-hash 1.1.0", - "rustybuzz", - "self_cell", - "smol_str", - "swash", - "sys-locale", - "ttf-parser 0.21.1", - "unicode-bidi", - "unicode-linebreak", - "unicode-script", - "unicode-segmentation", -] - -[[package]] -name = "cpal" -version = "0.15.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "873dab07c8f743075e57f524c583985fbaf745602acbe916a01539364369a779" -dependencies = [ - "alsa", - "core-foundation-sys", - "coreaudio-rs", - "dasp_sample", - "jni", - "js-sys", - "libc", - "mach2", - "ndk 0.8.0", - "ndk-context", - "oboe", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "windows 0.54.0", -] - -[[package]] -name = "crc32fast" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "critical-section" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" - -[[package]] -name = "crossbeam-channel" -version = "0.5.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-queue" -version = "0.3.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" - -[[package]] -name = "crunchy" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" - -[[package]] -name = "ctrlc" -version = "3.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "881c5d0a13b2f1498e2306e82cbada78390e152d4b1378fb28a84f4dcd0dc4f3" -dependencies = [ - "dispatch", - "nix", - "windows-sys 0.61.2", -] - -[[package]] -name = "cursor-icon" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f27ae1dd37df86211c42e150270f82743308803d90a6f6e6651cd730d5e1732f" - -[[package]] -name = "dasp_sample" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c87e182de0887fd5361989c677c4e8f5000cd9491d6d563161a8f3a5519fc7f" - -[[package]] -name = "data-encoding" -version = "2.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" - -[[package]] -name = "derive_more" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678" -dependencies = [ - "derive_more-impl", -] - -[[package]] -name = "derive_more-impl" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "unicode-xid", -] - -[[package]] -name = "dispatch" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" - -[[package]] -name = "dispatch2" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec" -dependencies = [ - "bitflags 2.10.0", - "objc2 0.6.3", -] - -[[package]] -name = "disqualified" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9c272297e804878a2a4b707cfcfc6d2328b5bb936944613b4fdf2b9269afdfd" - -[[package]] -name = "dlib" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412" -dependencies = [ - "libloading", -] - -[[package]] -name = "document-features" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95249b50c6c185bee49034bcb378a49dc2b5dff0be90ff6616d31d64febab05d" -dependencies = [ - "litrs", -] - -[[package]] -name = "downcast-rs" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" - -[[package]] -name = "downcast-rs" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "117240f60069e65410b3ae1bb213295bd828f707b5bec6596a1afc8793ce0cbc" - -[[package]] -name = "dpi" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8b14ccef22fc6f5a8f4d7d768562a182c04ce9a3b3157b91390b52ddfdf1a76" - -[[package]] -name = "either" -version = "1.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" - -[[package]] -name = "encase" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02ba239319a4f60905966390f5e52799d868103a533bb7e27822792332504ddd" -dependencies = [ - "const_panic", - "encase_derive", - "glam", - "thiserror 2.0.17", -] - -[[package]] -name = "encase_derive" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5223d6c647f09870553224f6e37261fe5567bc5a4f4cf13ed337476e79990f2f" -dependencies = [ - "encase_derive_impl", -] - -[[package]] -name = "encase_derive_impl" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1796db3d892515842ca2dfb11124c4bb4a9e58d9f2c5c1072e5bca1b2334507b" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "equivalent" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" - -[[package]] -name = "erased-serde" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "259d404d09818dec19332e31d94558aeb442fea04c817006456c24b5460bbd4b" -dependencies = [ - "serde", - "serde_core", - "typeid", -] - -[[package]] -name = "errno" -version = "0.3.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" -dependencies = [ - "libc", - "windows-sys 0.61.2", -] - -[[package]] -name = "euclid" -version = "0.22.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad9cdb4b747e485a12abb0e6566612956c7a1bafa3bdb8d682c5b6d403589e48" -dependencies = [ - "num-traits", -] - -[[package]] -name = "event-listener" -version = "5.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab" -dependencies = [ - "concurrent-queue", - "parking", - "pin-project-lite", -] - -[[package]] -name = "event-listener-strategy" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" -dependencies = [ - "event-listener", - "pin-project-lite", -] - -[[package]] -name = "fastrand" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" - -[[package]] -name = "fdeflate" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c" -dependencies = [ - "simd-adler32", -] - -[[package]] -name = "ffi" -version = "0.1.0" -dependencies = [ - "bevy", - "cbindgen", - "renderer", -] - -[[package]] -name = "find-msvc-tools" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52051878f80a721bb68ebfbc930e07b65ba72f2da88968ea5c06fd6ca3d3a127" - -[[package]] -name = "fixedbitset" -version = "0.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" - -[[package]] -name = "flate2" -version = "1.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc5a4e564e38c699f2880d3fda590bedc2e69f3f84cd48b457bd892ce61d0aa9" -dependencies = [ - "crc32fast", - "miniz_oxide", -] - -[[package]] -name = "float_next_after" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bf7cc16383c4b8d58b9905a8509f02926ce3058053c056376248d958c9df1e8" - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "foldhash" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" - -[[package]] -name = "foldhash" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" - -[[package]] -name = "font-types" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "511e2c18a516c666d27867d2f9821f76e7d591f762e9fc41dd6cc5c90fe54b0b" -dependencies = [ - "bytemuck", -] - -[[package]] -name = "fontconfig-parser" -version = "0.5.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbc773e24e02d4ddd8395fd30dc147524273a83e54e0f312d986ea30de5f5646" -dependencies = [ - "roxmltree", -] - -[[package]] -name = "fontdb" -version = "0.16.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0299020c3ef3f60f526a4f64ab4a3d4ce116b1acbf24cdd22da0068e5d81dc3" -dependencies = [ - "fontconfig-parser", - "log", - "memmap2", - "slotmap", - "tinyvec", - "ttf-parser 0.20.0", -] - -[[package]] -name = "foreign-types" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" -dependencies = [ - "foreign-types-macros", - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-macros" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "foreign-types-shared" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" - -[[package]] -name = "futures-channel" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" -dependencies = [ - "futures-core", -] - -[[package]] -name = "futures-core" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" - -[[package]] -name = "futures-io" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" - -[[package]] -name = "futures-lite" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f78e10609fe0e0b3f4157ffab1876319b5b0db102a2c60dc4626306dc46b44ad" -dependencies = [ - "fastrand", - "futures-core", - "futures-io", - "parking", - "pin-project-lite", -] - -[[package]] -name = "gethostname" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bd49230192a3797a9a4d6abe9b3eed6f7fa4c8a8a4947977c6f80025f92cbd8" -dependencies = [ - "rustix 1.1.2", - "windows-link 0.2.1", -] - -[[package]] -name = "getrandom" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" -dependencies = [ - "cfg-if", - "js-sys", - "libc", - "r-efi", - "wasip2", - "wasm-bindgen", -] - -[[package]] -name = "gilrs" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbb2c998745a3c1ac90f64f4f7b3a54219fd3612d7705e7798212935641ed18f" -dependencies = [ - "fnv", - "gilrs-core", - "log", - "uuid", - "vec_map", -] - -[[package]] -name = "gilrs-core" -version = "0.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be11a71ac3564f6965839e2ed275bf4fcf5ce16d80d396e1dfdb7b2d80bd587e" -dependencies = [ - "core-foundation 0.10.1", - "inotify", - "io-kit-sys", - "js-sys", - "libc", - "libudev-sys", - "log", - "nix", - "uuid", - "vec_map", - "wasm-bindgen", - "web-sys", - "windows 0.62.2", -] - -[[package]] -name = "gl_generator" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a95dfc23a2b4a9a2f5ab41d194f8bfda3cabec42af4e39f08c339eb2a0c124d" -dependencies = [ - "khronos_api", - "log", - "xml-rs", -] - -[[package]] -name = "glam" -version = "0.30.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e12d847aeb25f41be4c0ec9587d624e9cd631bc007a8fd7ce3f5851e064c6460" -dependencies = [ - "bytemuck", - "libm", - "rand", - "serde_core", -] - -[[package]] -name = "glob" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" - -[[package]] -name = "glow" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5e5ea60d70410161c8bf5da3fdfeaa1c72ed2c15f8bbb9d19fe3a4fad085f08" -dependencies = [ - "js-sys", - "slotmap", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "gltf" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3ce1918195723ce6ac74e80542c5a96a40c2b26162c1957a5cd70799b8cacf7" -dependencies = [ - "byteorder", - "gltf-json", - "lazy_static", - "serde_json", -] - -[[package]] -name = "gltf-derive" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14070e711538afba5d6c807edb74bcb84e5dbb9211a3bf5dea0dfab5b24f4c51" -dependencies = [ - "inflections", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "gltf-json" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6176f9d60a7eab0a877e8e96548605dedbde9190a7ae1e80bbcc1c9af03ab14" -dependencies = [ - "gltf-derive", - "serde", - "serde_derive", - "serde_json", -] - -[[package]] -name = "glutin_wgl_sys" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c4ee00b289aba7a9e5306d57c2d05499b2e5dc427f84ac708bd2c090212cf3e" -dependencies = [ - "gl_generator", -] - -[[package]] -name = "gpu-alloc" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbcd2dba93594b227a1f57ee09b8b9da8892c34d55aa332e034a228d0fe6a171" -dependencies = [ - "bitflags 2.10.0", - "gpu-alloc-types", -] - -[[package]] -name = "gpu-alloc-types" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98ff03b468aa837d70984d55f5d3f846f6ec31fe34bbb97c4f85219caeee1ca4" -dependencies = [ - "bitflags 2.10.0", -] - -[[package]] -name = "gpu-allocator" -version = "0.27.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c151a2a5ef800297b4e79efa4f4bec035c5f51d5ae587287c9b952bdf734cacd" -dependencies = [ - "log", - "presser", - "thiserror 1.0.69", - "windows 0.58.0", -] - -[[package]] -name = "gpu-descriptor" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b89c83349105e3732062a895becfc71a8f921bb71ecbbdd8ff99263e3b53a0ca" -dependencies = [ - "bitflags 2.10.0", - "gpu-descriptor-types", - "hashbrown 0.15.5", -] - -[[package]] -name = "gpu-descriptor-types" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdf242682df893b86f33a73828fb09ca4b2d3bb6cc95249707fc684d27484b91" -dependencies = [ - "bitflags 2.10.0", -] - -[[package]] -name = "grid" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36119f3a540b086b4e436bb2b588cf98a68863470e0e880f4d0842f112a3183a" - -[[package]] -name = "guillotiere" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b62d5865c036cb1393e23c50693df631d3f5d7bcca4c04fe4cc0fd592e74a782" -dependencies = [ - "euclid", - "svg_fmt", -] - -[[package]] -name = "half" -version = "2.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" -dependencies = [ - "cfg-if", - "crunchy", - "num-traits", - "zerocopy", -] - -[[package]] -name = "hash32" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606" -dependencies = [ - "byteorder", -] - -[[package]] -name = "hashbrown" -version = "0.15.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" -dependencies = [ - "foldhash 0.1.5", -] - -[[package]] -name = "hashbrown" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" -dependencies = [ - "equivalent", - "serde", -] - -[[package]] -name = "heapless" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad" -dependencies = [ - "hash32", - "portable-atomic", - "stable_deref_trait", -] - -[[package]] -name = "heck" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" - -[[package]] -name = "hermit-abi" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" - -[[package]] -name = "hexasphere" -version = "16.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29a164ceff4500f2a72b1d21beaa8aa8ad83aec2b641844c659b190cb3ea2e0b" -dependencies = [ - "constgebra", - "glam", - "tinyvec", -] - -[[package]] -name = "hexf-parse" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" - -[[package]] -name = "image" -version = "0.25.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "529feb3e6769d234375c4cf1ee2ce713682b8e76538cb13f9fc23e1400a591e7" -dependencies = [ - "bytemuck", - "byteorder-lite", - "moxcms", - "num-traits", - "png", -] - -[[package]] -name = "indexmap" -version = "2.11.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5" -dependencies = [ - "equivalent", - "hashbrown 0.16.0", - "serde", - "serde_core", -] - -[[package]] -name = "inflections" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a257582fdcde896fd96463bf2d40eefea0580021c0712a0e2b028b60b47a837a" - -[[package]] -name = "inotify" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f37dccff2791ab604f9babef0ba14fbe0be30bd368dc541e2b08d07c8aa908f3" -dependencies = [ - "bitflags 2.10.0", - "inotify-sys", - "libc", -] - -[[package]] -name = "inotify-sys" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb" -dependencies = [ - "libc", -] - -[[package]] -name = "inventory" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc61209c082fbeb19919bee74b176221b27223e27b65d781eb91af24eb1fb46e" -dependencies = [ - "rustversion", -] - -[[package]] -name = "io-kit-sys" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "617ee6cf8e3f66f3b4ea67a4058564628cde41901316e19f559e14c7c72c5e7b" -dependencies = [ - "core-foundation-sys", - "mach2", -] - -[[package]] -name = "is_terminal_polyfill" -version = "1.70.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" - -[[package]] -name = "itertools" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" -dependencies = [ - "either", -] - -[[package]] -name = "itertools" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" - -[[package]] -name = "jni" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" -dependencies = [ - "cesu8", - "cfg-if", - "combine", - "jni-sys", - "log", - "thiserror 1.0.69", - "walkdir", - "windows-sys 0.45.0", -] - -[[package]] -name = "jni-sys" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" - -[[package]] -name = "jobserver" -version = "0.1.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" -dependencies = [ - "getrandom", - "libc", -] - -[[package]] -name = "js-sys" -version = "0.3.81" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec48937a97411dcb524a265206ccd4c90bb711fca92b2792c407f268825b9305" -dependencies = [ - "once_cell", - "wasm-bindgen", -] - -[[package]] -name = "khronos-egl" -version = "6.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6aae1df220ece3c0ada96b8153459b67eebe9ae9212258bb0134ae60416fdf76" -dependencies = [ - "libc", - "libloading", - "pkg-config", -] - -[[package]] -name = "khronos_api" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" - -[[package]] -name = "ktx2" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff7f53bdf698e7aa7ec916411bbdc8078135da11b66db5182675b2227f6c0d07" -dependencies = [ - "bitflags 2.10.0", -] - -[[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" - -[[package]] -name = "lewton" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "777b48df9aaab155475a83a7df3070395ea1ac6902f5cd062b8f2b028075c030" -dependencies = [ - "byteorder", - "ogg", - "tinyvec", -] - -[[package]] -name = "libc" -version = "0.2.177" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" - -[[package]] -name = "libloading" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" -dependencies = [ - "cfg-if", - "windows-link 0.2.1", -] - -[[package]] -name = "libm" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" - -[[package]] -name = "libredox" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb" -dependencies = [ - "bitflags 2.10.0", - "libc", - "redox_syscall 0.5.18", -] - -[[package]] -name = "libudev-sys" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c8469b4a23b962c1396b9b451dda50ef5b283e8dd309d69033475fa9b334324" -dependencies = [ - "libc", - "pkg-config", -] - -[[package]] -name = "linux-raw-sys" -version = "0.4.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" - -[[package]] -name = "linux-raw-sys" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" - -[[package]] -name = "litrs" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5e54036fe321fd421e10d732f155734c4e4afd610dd556d9a82833ab3ee0bed" - -[[package]] -name = "lock_api" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" -dependencies = [ - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" - -[[package]] -name = "lyon" -version = "1.0.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbcb7d54d54c8937364c9d41902d066656817dce1e03a44e5533afebd1ef4352" -dependencies = [ - "lyon_algorithms", - "lyon_tessellation", -] - -[[package]] -name = "lyon_algorithms" -version = "1.0.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c0829e28c4f336396f250d850c3987e16ce6db057ffe047ce0dd54aab6b647" -dependencies = [ - "lyon_path", - "num-traits", -] - -[[package]] -name = "lyon_geom" -version = "1.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e16770d760c7848b0c1c2d209101e408207a65168109509f8483837a36cf2e7" -dependencies = [ - "arrayvec", - "euclid", - "num-traits", -] - -[[package]] -name = "lyon_path" -version = "1.0.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aeca86bcfd632a15984ba029b539ffb811e0a70bf55e814ef8b0f54f506fdeb" -dependencies = [ - "lyon_geom", - "num-traits", -] - -[[package]] -name = "lyon_tessellation" -version = "1.0.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3f586142e1280335b1bc89539f7c97dd80f08fc43e9ab1b74ef0a42b04aa353" -dependencies = [ - "float_next_after", - "lyon_path", - "num-traits", -] - -[[package]] -name = "mach2" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d640282b302c0bb0a2a8e0233ead9035e3bed871f0b7e81fe4a1ec829765db44" -dependencies = [ - "libc", -] - -[[package]] -name = "malloc_buf" -version = "0.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" -dependencies = [ - "libc", -] - -[[package]] -name = "matchers" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" -dependencies = [ - "regex-automata", -] - -[[package]] -name = "memchr" -version = "2.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" - -[[package]] -name = "memmap2" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843a98750cd611cc2965a8213b53b43e715f13c37a9e096c6408e69990961db7" -dependencies = [ - "libc", -] - -[[package]] -name = "metal" -version = "0.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00c15a6f673ff72ddcc22394663290f870fb224c1bfce55734a75c414150e605" -dependencies = [ - "bitflags 2.10.0", - "block", - "core-graphics-types 0.2.0", - "foreign-types", - "log", - "objc", - "paste", -] - -[[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - -[[package]] -name = "miniz_oxide" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" -dependencies = [ - "adler2", - "simd-adler32", -] - -[[package]] -name = "moxcms" -version = "0.7.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c588e11a3082784af229e23e8e4ecf5bcc6fbe4f69101e0421ce8d79da7f0b40" -dependencies = [ - "num-traits", - "pxfm", -] - -[[package]] -name = "naga" -version = "26.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "916cbc7cb27db60be930a4e2da243cf4bc39569195f22fd8ee419cd31d5b662c" -dependencies = [ - "arrayvec", - "bit-set", - "bitflags 2.10.0", - "cfg-if", - "cfg_aliases", - "codespan-reporting", - "half", - "hashbrown 0.15.5", - "hexf-parse", - "indexmap", - "libm", - "log", - "num-traits", - "once_cell", - "pp-rs", - "rustc-hash 1.1.0", - "spirv", - "thiserror 2.0.17", - "unicode-ident", -] - -[[package]] -name = "naga_oil" -version = "0.19.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b586d3cf5c9b7e13fe2af6e114406ff70773fd80881960378933b63e76f37dd" -dependencies = [ - "codespan-reporting", - "data-encoding", - "indexmap", - "naga", - "regex", - "rustc-hash 1.1.0", - "thiserror 2.0.17", - "tracing", - "unicode-ident", -] - -[[package]] -name = "ndk" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2076a31b7010b17a38c01907c45b945e8f11495ee4dd588309718901b1f7a5b7" -dependencies = [ - "bitflags 2.10.0", - "jni-sys", - "log", - "ndk-sys 0.5.0+25.2.9519653", - "num_enum", - "thiserror 1.0.69", -] - -[[package]] -name = "ndk" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" -dependencies = [ - "bitflags 2.10.0", - "jni-sys", - "log", - "ndk-sys 0.6.0+11769913", - "num_enum", - "raw-window-handle", - "thiserror 1.0.69", -] - -[[package]] -name = "ndk-context" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" - -[[package]] -name = "ndk-sys" -version = "0.5.0+25.2.9519653" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c196769dd60fd4f363e11d948139556a344e79d451aeb2fa2fd040738ef7691" -dependencies = [ - "jni-sys", -] - -[[package]] -name = "ndk-sys" -version = "0.6.0+11769913" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee6cda3051665f1fb8d9e08fc35c96d5a244fb1be711a03b71118828afc9a873" -dependencies = [ - "jni-sys", -] - -[[package]] -name = "nix" -version = "0.30.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" -dependencies = [ - "bitflags 2.10.0", - "cfg-if", - "cfg_aliases", - "libc", -] - -[[package]] -name = "nom" -version = "7.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" -dependencies = [ - "memchr", - "minimal-lexical", -] - -[[package]] -name = "nonmax" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "610a5acd306ec67f907abe5567859a3c693fb9886eb1f012ab8f2a47bef3db51" - -[[package]] -name = "ntapi" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4" -dependencies = [ - "winapi", -] - -[[package]] -name = "nu-ansi-term" -version = "0.50.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" -dependencies = [ - "windows-sys 0.61.2", -] - -[[package]] -name = "num-derive" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", - "libm", -] - -[[package]] -name = "num_enum" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a973b4e44ce6cad84ce69d797acf9a044532e4184c4f267913d1b546a0727b7a" -dependencies = [ - "num_enum_derive", - "rustversion", -] - -[[package]] -name = "num_enum_derive" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77e878c846a8abae00dd069496dbe8751b16ac1c3d6bd2a7283a938e8228f90d" -dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "objc" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" -dependencies = [ - "malloc_buf", -] - -[[package]] -name = "objc-sys" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310" - -[[package]] -name = "objc2" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46a785d4eeff09c14c487497c162e92766fbb3e4059a71840cecc03d9a50b804" -dependencies = [ - "objc-sys", - "objc2-encode", -] - -[[package]] -name = "objc2" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7c2599ce0ec54857b29ce62166b0ed9b4f6f1a70ccc9a71165b6154caca8c05" -dependencies = [ - "objc2-encode", -] - -[[package]] -name = "objc2-app-kit" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" -dependencies = [ - "bitflags 2.10.0", - "block2 0.5.1", - "libc", - "objc2 0.5.2", - "objc2-core-data 0.2.2", - "objc2-core-image 0.2.2", - "objc2-foundation 0.2.2", - "objc2-quartz-core 0.2.2", -] - -[[package]] -name = "objc2-app-kit" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d49e936b501e5c5bf01fda3a9452ff86dc3ea98ad5f283e1455153142d97518c" -dependencies = [ - "bitflags 2.10.0", - "block2 0.6.2", - "libc", - "objc2 0.6.3", - "objc2-cloud-kit 0.3.2", - "objc2-core-data 0.3.2", - "objc2-core-foundation", - "objc2-core-graphics", - "objc2-core-image 0.3.2", - "objc2-core-text", - "objc2-core-video", - "objc2-foundation 0.3.2", - "objc2-quartz-core 0.3.2", -] - -[[package]] -name = "objc2-cloud-kit" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009" -dependencies = [ - "bitflags 2.10.0", - "block2 0.5.1", - "objc2 0.5.2", - "objc2-core-location", - "objc2-foundation 0.2.2", -] - -[[package]] -name = "objc2-cloud-kit" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73ad74d880bb43877038da939b7427bba67e9dd42004a18b809ba7d87cee241c" -dependencies = [ - "bitflags 2.10.0", - "objc2 0.6.3", - "objc2-foundation 0.3.2", -] - -[[package]] -name = "objc2-contacts" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5ff520e9c33812fd374d8deecef01d4a840e7b41862d849513de77e44aa4889" -dependencies = [ - "block2 0.5.1", - "objc2 0.5.2", - "objc2-foundation 0.2.2", -] - -[[package]] -name = "objc2-core-data" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" -dependencies = [ - "bitflags 2.10.0", - "block2 0.5.1", - "objc2 0.5.2", - "objc2-foundation 0.2.2", -] - -[[package]] -name = "objc2-core-data" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b402a653efbb5e82ce4df10683b6b28027616a2715e90009947d50b8dd298fa" -dependencies = [ - "bitflags 2.10.0", - "objc2 0.6.3", - "objc2-foundation 0.3.2", -] - -[[package]] -name = "objc2-core-foundation" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" -dependencies = [ - "bitflags 2.10.0", - "dispatch2", - "objc2 0.6.3", -] - -[[package]] -name = "objc2-core-graphics" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e022c9d066895efa1345f8e33e584b9f958da2fd4cd116792e15e07e4720a807" -dependencies = [ - "bitflags 2.10.0", - "dispatch2", - "objc2 0.6.3", - "objc2-core-foundation", - "objc2-io-surface", -] - -[[package]] -name = "objc2-core-image" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80" -dependencies = [ - "block2 0.5.1", - "objc2 0.5.2", - "objc2-foundation 0.2.2", - "objc2-metal", -] - -[[package]] -name = "objc2-core-image" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5d563b38d2b97209f8e861173de434bd0214cf020e3423a52624cd1d989f006" -dependencies = [ - "objc2 0.6.3", - "objc2-foundation 0.3.2", -] - -[[package]] -name = "objc2-core-location" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "000cfee34e683244f284252ee206a27953279d370e309649dc3ee317b37e5781" -dependencies = [ - "block2 0.5.1", - "objc2 0.5.2", - "objc2-contacts", - "objc2-foundation 0.2.2", -] - -[[package]] -name = "objc2-core-text" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cde0dfb48d25d2b4862161a4d5fcc0e3c24367869ad306b0c9ec0073bfed92d" -dependencies = [ - "bitflags 2.10.0", - "objc2 0.6.3", - "objc2-core-foundation", - "objc2-core-graphics", -] - -[[package]] -name = "objc2-core-video" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d425caf1df73233f29fd8a5c3e5edbc30d2d4307870f802d18f00d83dc5141a6" -dependencies = [ - "bitflags 2.10.0", - "objc2 0.6.3", - "objc2-core-foundation", - "objc2-core-graphics", - "objc2-io-surface", -] - -[[package]] -name = "objc2-encode" -version = "4.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" - -[[package]] -name = "objc2-foundation" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" -dependencies = [ - "bitflags 2.10.0", - "block2 0.5.1", - "dispatch", - "libc", - "objc2 0.5.2", -] - -[[package]] -name = "objc2-foundation" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272" -dependencies = [ - "bitflags 2.10.0", - "objc2 0.6.3", - "objc2-core-foundation", -] - -[[package]] -name = "objc2-io-kit" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33fafba39597d6dc1fb709123dfa8289d39406734be322956a69f0931c73bb15" -dependencies = [ - "libc", - "objc2-core-foundation", -] - -[[package]] -name = "objc2-io-surface" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180788110936d59bab6bd83b6060ffdfffb3b922ba1396b312ae795e1de9d81d" -dependencies = [ - "bitflags 2.10.0", - "objc2 0.6.3", - "objc2-core-foundation", -] - -[[package]] -name = "objc2-link-presentation" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1a1ae721c5e35be65f01a03b6d2ac13a54cb4fa70d8a5da293d7b0020261398" -dependencies = [ - "block2 0.5.1", - "objc2 0.5.2", - "objc2-app-kit 0.2.2", - "objc2-foundation 0.2.2", -] - -[[package]] -name = "objc2-metal" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" -dependencies = [ - "bitflags 2.10.0", - "block2 0.5.1", - "objc2 0.5.2", - "objc2-foundation 0.2.2", -] - -[[package]] -name = "objc2-quartz-core" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" -dependencies = [ - "bitflags 2.10.0", - "block2 0.5.1", - "objc2 0.5.2", - "objc2-foundation 0.2.2", - "objc2-metal", -] - -[[package]] -name = "objc2-quartz-core" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96c1358452b371bf9f104e21ec536d37a650eb10f7ee379fff67d2e08d537f1f" -dependencies = [ - "bitflags 2.10.0", - "objc2 0.6.3", - "objc2-foundation 0.3.2", -] - -[[package]] -name = "objc2-symbols" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a684efe3dec1b305badae1a28f6555f6ddd3bb2c2267896782858d5a78404dc" -dependencies = [ - "objc2 0.5.2", - "objc2-foundation 0.2.2", -] - -[[package]] -name = "objc2-ui-kit" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f" -dependencies = [ - "bitflags 2.10.0", - "block2 0.5.1", - "objc2 0.5.2", - "objc2-cloud-kit 0.2.2", - "objc2-core-data 0.2.2", - "objc2-core-image 0.2.2", - "objc2-core-location", - "objc2-foundation 0.2.2", - "objc2-link-presentation", - "objc2-quartz-core 0.2.2", - "objc2-symbols", - "objc2-uniform-type-identifiers", - "objc2-user-notifications", -] - -[[package]] -name = "objc2-uniform-type-identifiers" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44fa5f9748dbfe1ca6c0b79ad20725a11eca7c2218bceb4b005cb1be26273bfe" -dependencies = [ - "block2 0.5.1", - "objc2 0.5.2", - "objc2-foundation 0.2.2", -] - -[[package]] -name = "objc2-user-notifications" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3" -dependencies = [ - "bitflags 2.10.0", - "block2 0.5.1", - "objc2 0.5.2", - "objc2-core-location", - "objc2-foundation 0.2.2", -] - -[[package]] -name = "oboe" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8b61bebd49e5d43f5f8cc7ee2891c16e0f41ec7954d36bcb6c14c5e0de867fb" -dependencies = [ - "jni", - "ndk 0.8.0", - "ndk-context", - "num-derive", - "num-traits", - "oboe-sys", -] - -[[package]] -name = "oboe-sys" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8bb09a4a2b1d668170cfe0a7d5bc103f8999fb316c98099b6a9939c9f2e79d" -dependencies = [ - "cc", -] - -[[package]] -name = "offset-allocator" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e234d535da3521eb95106f40f0b73483d80bfb3aacf27c40d7e2b72f1a3e00a2" -dependencies = [ - "log", - "nonmax", -] - -[[package]] -name = "ogg" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6951b4e8bf21c8193da321bcce9c9dd2e13c858fe078bf9054a288b419ae5d6e" -dependencies = [ - "byteorder", -] - -[[package]] -name = "once_cell" -version = "1.21.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" - -[[package]] -name = "once_cell_polyfill" -version = "1.70.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" - -[[package]] -name = "orbclient" -version = "0.3.48" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba0b26cec2e24f08ed8bb31519a9333140a6599b867dac464bb150bdb796fd43" -dependencies = [ - "libredox", -] - -[[package]] -name = "ordered-float" -version = "4.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bb71e1b3fa6ca1c61f383464aaf2bb0e2f8e772a1f01d486832464de363b951" -dependencies = [ - "num-traits", -] - -[[package]] -name = "owned_ttf_parser" -version = "0.25.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36820e9051aca1014ddc75770aab4d68bc1e9e632f0f5627c4086bc216fb583b" -dependencies = [ - "ttf-parser 0.25.1", -] - -[[package]] -name = "parking" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" - -[[package]] -name = "parking_lot" -version = "0.12.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall 0.5.18", - "smallvec", - "windows-link 0.2.1", -] - -[[package]] -name = "paste" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" - -[[package]] -name = "percent-encoding" -version = "2.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" - -[[package]] -name = "petgraph" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8701b58ea97060d5e5b155d383a69952a60943f0e6dfe30b04c287beb0b27455" -dependencies = [ - "fixedbitset", - "hashbrown 0.15.5", - "indexmap", - "serde", - "serde_derive", -] - -[[package]] -name = "pin-project" -version = "1.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "pin-project-lite" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" - -[[package]] -name = "piper" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" -dependencies = [ - "atomic-waker", - "fastrand", - "futures-io", -] - -[[package]] -name = "pkg-config" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" - -[[package]] -name = "png" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97baced388464909d42d89643fe4361939af9b7ce7a31ee32a168f832a70f2a0" -dependencies = [ - "bitflags 2.10.0", - "crc32fast", - "fdeflate", - "flate2", - "miniz_oxide", -] - -[[package]] -name = "polling" -version = "3.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d0e4f59085d47d8241c88ead0f274e8a0cb551f3625263c05eb8dd897c34218" -dependencies = [ - "cfg-if", - "concurrent-queue", - "hermit-abi", - "pin-project-lite", - "rustix 1.1.2", - "windows-sys 0.61.2", -] - -[[package]] -name = "portable-atomic" -version = "1.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" - -[[package]] -name = "portable-atomic-util" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" -dependencies = [ - "portable-atomic", -] - -[[package]] -name = "pp-rs" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb458bb7f6e250e6eb79d5026badc10a3ebb8f9a15d1fff0f13d17c71f4d6dee" -dependencies = [ - "unicode-xid", -] - -[[package]] -name = "ppv-lite86" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" -dependencies = [ - "zerocopy", -] - -[[package]] -name = "presser" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8cf8e6a8aa66ce33f63993ffc4ea4271eb5b0530a9002db8455ea6050c77bfa" - -[[package]] -name = "proc-macro-crate" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" -dependencies = [ - "toml_edit 0.23.7", -] - -[[package]] -name = "proc-macro2" -version = "1.0.101" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "profiling" -version = "1.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3eb8486b569e12e2c32ad3e204dbaba5e4b5b216e9367044f25f1dba42341773" - -[[package]] -name = "pxfm" -version = "0.1.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3cbdf373972bf78df4d3b518d07003938e2c7d1fb5891e55f9cb6df57009d84" -dependencies = [ - "num-traits", -] - -[[package]] -name = "quick-xml" -version = "0.37.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "331e97a1af0bf59823e6eadffe373d7b27f485be8748f71471c662c1f269b7fb" -dependencies = [ - "memchr", -] - -[[package]] -name = "quote" -version = "1.0.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "r-efi" -version = "5.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" - -[[package]] -name = "radsort" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "019b4b213425016d7d84a153c4c73afb0946fbb4840e4eece7ba8848b9d6da22" - -[[package]] -name = "rand" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" -dependencies = [ - "rand_chacha", - "rand_core", -] - -[[package]] -name = "rand_chacha" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" -dependencies = [ - "getrandom", -] - -[[package]] -name = "rand_distr" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a8615d50dcf34fa31f7ab52692afec947c4dd0ab803cc87cb3b0b4570ff7463" -dependencies = [ - "num-traits", - "rand", -] - -[[package]] -name = "range-alloc" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d6831663a5098ea164f89cff59c6284e95f4e3c76ce9848d4529f5ccca9bde" - -[[package]] -name = "rangemap" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93e7e49bb0bf967717f7bd674458b3d6b0c5f48ec7e3038166026a69fc22223" - -[[package]] -name = "raw-window-handle" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" - -[[package]] -name = "read-fonts" -version = "0.35.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6717cf23b488adf64b9d711329542ba34de147df262370221940dfabc2c91358" -dependencies = [ - "bytemuck", - "font-types", -] - -[[package]] -name = "rectangle-pack" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0d463f2884048e7153449a55166f91028d5b0ea53c79377099ce4e8cf0cf9bb" - -[[package]] -name = "redox_syscall" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" -dependencies = [ - "bitflags 1.3.2", -] - -[[package]] -name = "redox_syscall" -version = "0.5.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" -dependencies = [ - "bitflags 2.10.0", -] - -[[package]] -name = "regex" -version = "1.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.8.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" - -[[package]] -name = "renderdoc-sys" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832" - -[[package]] -name = "renderer" -version = "0.1.0" -dependencies = [ - "bevy", - "lyon", - "objc2 0.6.3", - "objc2-app-kit 0.3.2", - "raw-window-handle", - "thiserror 2.0.17", - "tracing", - "tracing-subscriber", - "windows 0.58.0", -] - -[[package]] -name = "rodio" -version = "0.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ceb6607dd738c99bc8cb28eff249b7cd5c8ec88b9db96c0608c1480d140fb1" -dependencies = [ - "cpal", - "lewton", -] - -[[package]] -name = "ron" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "beceb6f7bf81c73e73aeef6dd1356d9a1b2b4909e1f0fc3e59b034f9572d7b7f" -dependencies = [ - "base64", - "bitflags 2.10.0", - "serde", - "serde_derive", - "unicode-ident", -] - -[[package]] -name = "roxmltree" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c20b6793b5c2fa6553b250154b78d6d0db37e72700ae35fad9387a46f487c97" - -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - -[[package]] -name = "rustc-hash" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" - -[[package]] -name = "rustix" -version = "0.38.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" -dependencies = [ - "bitflags 2.10.0", - "errno", - "libc", - "linux-raw-sys 0.4.15", - "windows-sys 0.59.0", -] - -[[package]] -name = "rustix" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" -dependencies = [ - "bitflags 2.10.0", - "errno", - "libc", - "linux-raw-sys 0.11.0", - "windows-sys 0.61.2", -] - -[[package]] -name = "rustversion" -version = "1.0.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" - -[[package]] -name = "rustybuzz" -version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfb9cf8877777222e4a3bc7eb247e398b56baba500c38c1c46842431adc8b55c" -dependencies = [ - "bitflags 2.10.0", - "bytemuck", - "libm", - "smallvec", - "ttf-parser 0.21.1", - "unicode-bidi-mirroring", - "unicode-ccc", - "unicode-properties", - "unicode-script", -] - -[[package]] -name = "ruzstd" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3640bec8aad418d7d03c72ea2de10d5c646a598f9883c7babc160d91e3c1b26c" -dependencies = [ - "twox-hash", -] - -[[package]] -name = "ryu" -version = "1.0.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" - -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "scoped-tls" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" - -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - -[[package]] -name = "sctk-adwaita" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6277f0217056f77f1d8f49f2950ac6c278c0d607c45f5ee99328d792ede24ec" -dependencies = [ - "ab_glyph", - "log", - "memmap2", - "smithay-client-toolkit", - "tiny-skia", -] - -[[package]] -name = "self_cell" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f7d95a54511e0c7be3f51e8867aa8cf35148d7b9445d44de2f943e2b206e749" - -[[package]] -name = "send_wrapper" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" - -[[package]] -name = "serde" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" -dependencies = [ - "serde_core", - "serde_derive", -] - -[[package]] -name = "serde_core" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_json" -version = "1.0.145" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" -dependencies = [ - "itoa", - "memchr", - "ryu", - "serde", - "serde_core", -] - -[[package]] -name = "serde_spanned" -version = "0.6.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" -dependencies = [ - "serde", -] - -[[package]] -name = "sharded-slab" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" -dependencies = [ - "lazy_static", -] - -[[package]] -name = "shlex" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" - -[[package]] -name = "simd-adler32" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" - -[[package]] -name = "skrifa" -version = "0.37.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c31071dedf532758ecf3fed987cdb4bd9509f900e026ab684b4ecb81ea49841" -dependencies = [ - "bytemuck", - "read-fonts", -] - -[[package]] -name = "slab" -version = "0.4.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" - -[[package]] -name = "slotmap" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbff4acf519f630b3a3ddcfaea6c06b42174d9a44bc70c620e9ed1649d58b82a" -dependencies = [ - "version_check", -] - -[[package]] -name = "smallvec" -version = "1.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" - -[[package]] -name = "smithay-client-toolkit" -version = "0.19.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3457dea1f0eb631b4034d61d4d8c32074caa6cd1ab2d59f2327bd8461e2c0016" -dependencies = [ - "bitflags 2.10.0", - "calloop", - "calloop-wayland-source", - "cursor-icon", - "libc", - "log", - "memmap2", - "rustix 0.38.44", - "thiserror 1.0.69", - "wayland-backend", - "wayland-client", - "wayland-csd-frame", - "wayland-cursor", - "wayland-protocols", - "wayland-protocols-wlr", - "wayland-scanner", - "xkeysym", -] - -[[package]] -name = "smol_str" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd538fb6910ac1099850255cf94a94df6551fbdd602454387d0adb2d1ca6dead" -dependencies = [ - "serde", -] - -[[package]] -name = "spin" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5fe4ccb98d9c292d56fec89a5e07da7fc4cf0dc11e156b41793132775d3e591" -dependencies = [ - "portable-atomic", -] - -[[package]] -name = "spirv" -version = "0.3.0+sdk-1.3.268.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eda41003dc44290527a59b13432d4a0379379fa074b70174882adfbdfd917844" -dependencies = [ - "bitflags 2.10.0", -] - -[[package]] -name = "stable_deref_trait" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" - -[[package]] -name = "stackfuture" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6eae92052b72ef70dafa16eddbabffc77e5ca3574be2f7bc1127b36f0a7ad7f2" - -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - -[[package]] -name = "strict-num" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731" - -[[package]] -name = "strsim" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" - -[[package]] -name = "svg_fmt" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0193cc4331cfd2f3d2011ef287590868599a2f33c3e69bc22c1a3d3acf9e02fb" - -[[package]] -name = "swash" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47846491253e976bdd07d0f9cc24b7daf24720d11309302ccbbc6e6b6e53550a" -dependencies = [ - "skrifa", - "yazi", - "zeno", -] - -[[package]] -name = "syn" -version = "2.0.106" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "sys-locale" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eab9a99a024a169fe8a903cf9d4a3b3601109bcc13bd9e3c6fff259138626c4" -dependencies = [ - "libc", -] - -[[package]] -name = "sysinfo" -version = "0.37.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16607d5caffd1c07ce073528f9ed972d88db15dd44023fa57142963be3feb11f" -dependencies = [ - "libc", - "memchr", - "ntapi", - "objc2-core-foundation", - "objc2-io-kit", - "windows 0.61.3", -] - -[[package]] -name = "taffy" -version = "0.7.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab4f4d046dd956a47a7e1a2947083d7ac3e6aa3cfaaead36173ceaa5ab11878c" -dependencies = [ - "arrayvec", - "grid", - "serde", - "slotmap", -] - -[[package]] -name = "tempfile" -version = "3.23.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" -dependencies = [ - "fastrand", - "getrandom", - "once_cell", - "rustix 1.1.2", - "windows-sys 0.61.2", -] - -[[package]] -name = "termcolor" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "thiserror" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" -dependencies = [ - "thiserror-impl 1.0.69", -] - -[[package]] -name = "thiserror" -version = "2.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" -dependencies = [ - "thiserror-impl 2.0.17", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "thiserror-impl" -version = "2.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "thread_local" -version = "1.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "tiny-skia" -version = "0.11.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83d13394d44dae3207b52a326c0c85a8bf87f1541f23b0d143811088497b09ab" -dependencies = [ - "arrayref", - "arrayvec", - "bytemuck", - "cfg-if", - "log", - "tiny-skia-path", -] - -[[package]] -name = "tiny-skia-path" -version = "0.11.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c9e7fc0c2e86a30b117d0462aa261b72b7a99b7ebd7deb3a14ceda95c5bdc93" -dependencies = [ - "arrayref", - "bytemuck", - "strict-num", -] - -[[package]] -name = "tinyvec" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - -[[package]] -name = "toml" -version = "0.8.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" -dependencies = [ - "serde", - "serde_spanned", - "toml_datetime 0.6.11", - "toml_edit 0.22.27", -] - -[[package]] -name = "toml_datetime" -version = "0.6.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" -dependencies = [ - "serde", -] - -[[package]] -name = "toml_datetime" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2cdb639ebbc97961c51720f858597f7f24c4fc295327923af55b74c3c724533" -dependencies = [ - "serde_core", -] - -[[package]] -name = "toml_edit" -version = "0.22.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" -dependencies = [ - "indexmap", - "serde", - "serde_spanned", - "toml_datetime 0.6.11", - "toml_write", - "winnow", -] - -[[package]] -name = "toml_edit" -version = "0.23.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6485ef6d0d9b5d0ec17244ff7eb05310113c3f316f2d14200d4de56b3cb98f8d" -dependencies = [ - "indexmap", - "toml_datetime 0.7.3", - "toml_parser", - "winnow", -] - -[[package]] -name = "toml_parser" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0cbe268d35bdb4bb5a56a2de88d0ad0eb70af5384a99d648cd4b3d04039800e" -dependencies = [ - "winnow", -] - -[[package]] -name = "toml_write" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" - -[[package]] -name = "tracing" -version = "0.1.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" -dependencies = [ - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "tracing-core" -version = "0.1.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" -dependencies = [ - "once_cell", - "valuable", -] - -[[package]] -name = "tracing-log" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" -dependencies = [ - "log", - "once_cell", - "tracing-core", -] - -[[package]] -name = "tracing-oslog" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d76902d2a8d5f9f55a81155c08971734071968c90f2d9bfe645fe700579b2950" -dependencies = [ - "cc", - "cfg-if", - "tracing-core", - "tracing-subscriber", -] - -[[package]] -name = "tracing-subscriber" -version = "0.3.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5" -dependencies = [ - "matchers", - "nu-ansi-term", - "once_cell", - "regex-automata", - "sharded-slab", - "smallvec", - "thread_local", - "tracing", - "tracing-core", - "tracing-log", -] - -[[package]] -name = "tracing-wasm" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4575c663a174420fa2d78f4108ff68f65bf2fbb7dd89f33749b6e826b3626e07" -dependencies = [ - "tracing", - "tracing-subscriber", - "wasm-bindgen", -] - -[[package]] -name = "ttf-parser" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17f77d76d837a7830fe1d4f12b7b4ba4192c1888001c7164257e4bc6d21d96b4" - -[[package]] -name = "ttf-parser" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c591d83f69777866b9126b24c6dd9a18351f177e49d625920d19f989fd31cf8" - -[[package]] -name = "ttf-parser" -version = "0.25.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2df906b07856748fa3f6e0ad0cbaa047052d4a7dd609e231c4f72cee8c36f31" - -[[package]] -name = "twox-hash" -version = "2.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ea3136b675547379c4bd395ca6b938e5ad3c3d20fad76e7fe85f9e0d011419c" - -[[package]] -name = "typeid" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" - -[[package]] -name = "typewit" -version = "1.14.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8c1ae7cc0fdb8b842d65d127cb981574b0d2b249b74d1c7a2986863dc134f71" - -[[package]] -name = "unicode-bidi" -version = "0.3.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" - -[[package]] -name = "unicode-bidi-mirroring" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23cb788ffebc92c5948d0e997106233eeb1d8b9512f93f41651f52b6c5f5af86" - -[[package]] -name = "unicode-ccc" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1df77b101bcc4ea3d78dafc5ad7e4f58ceffe0b2b16bf446aeb50b6cb4157656" - -[[package]] -name = "unicode-ident" -version = "1.0.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d" - -[[package]] -name = "unicode-linebreak" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" - -[[package]] -name = "unicode-properties" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0" - -[[package]] -name = "unicode-script" -version = "0.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb421b350c9aff471779e262955939f565ec18b86c15364e6bdf0d662ca7c1f" - -[[package]] -name = "unicode-segmentation" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" - -[[package]] -name = "unicode-width" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" - -[[package]] -name = "unicode-xid" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" - -[[package]] -name = "utf8parse" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" - -[[package]] -name = "uuid" -version = "1.18.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2" -dependencies = [ - "getrandom", - "js-sys", - "serde", - "wasm-bindgen", -] - -[[package]] -name = "valuable" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" - -[[package]] -name = "variadics_please" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41b6d82be61465f97d42bd1d15bf20f3b0a3a0905018f38f9d6f6962055b0b5c" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "vec_map" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" - -[[package]] -name = "version_check" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" - -[[package]] -name = "walkdir" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" -dependencies = [ - "same-file", - "winapi-util", -] - -[[package]] -name = "wasip2" -version = "1.0.1+wasi-0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" -dependencies = [ - "wit-bindgen", -] - -[[package]] -name = "wasm-bindgen" -version = "0.2.104" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1da10c01ae9f1ae40cbfac0bac3b1e724b320abfcf52229f80b547c0d250e2d" -dependencies = [ - "cfg-if", - "once_cell", - "rustversion", - "wasm-bindgen-macro", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.104" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "671c9a5a66f49d8a47345ab942e2cb93c7d1d0339065d4f8139c486121b43b19" -dependencies = [ - "bumpalo", - "log", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.54" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e038d41e478cc73bae0ff9b36c60cff1c98b8f38f8d7e8061e79ee63608ac5c" -dependencies = [ - "cfg-if", - "js-sys", - "once_cell", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.104" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ca60477e4c59f5f2986c50191cd972e3a50d8a95603bc9434501cf156a9a119" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.104" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f07d2f20d4da7b26400c9f4a0511e6e0345b040694e8a75bd41d578fa4421d7" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.104" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bad67dc8b2a1a6e5448428adec4c3e84c43e561d8c9ee8a9e5aabeb193ec41d1" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "wayland-backend" -version = "0.3.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "673a33c33048a5ade91a6b139580fa174e19fb0d23f396dca9fa15f2e1e49b35" -dependencies = [ - "cc", - "downcast-rs 1.2.1", - "rustix 1.1.2", - "scoped-tls", - "smallvec", - "wayland-sys", -] - -[[package]] -name = "wayland-client" -version = "0.31.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c66a47e840dc20793f2264eb4b3e4ecb4b75d91c0dd4af04b456128e0bdd449d" -dependencies = [ - "bitflags 2.10.0", - "rustix 1.1.2", - "wayland-backend", - "wayland-scanner", -] - -[[package]] -name = "wayland-csd-frame" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "625c5029dbd43d25e6aa9615e88b829a5cad13b2819c4ae129fdbb7c31ab4c7e" -dependencies = [ - "bitflags 2.10.0", - "cursor-icon", - "wayland-backend", -] - -[[package]] -name = "wayland-cursor" -version = "0.31.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "447ccc440a881271b19e9989f75726d60faa09b95b0200a9b7eb5cc47c3eeb29" -dependencies = [ - "rustix 1.1.2", - "wayland-client", - "xcursor", -] - -[[package]] -name = "wayland-protocols" -version = "0.32.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efa790ed75fbfd71283bd2521a1cfdc022aabcc28bdcff00851f9e4ae88d9901" -dependencies = [ - "bitflags 2.10.0", - "wayland-backend", - "wayland-client", - "wayland-scanner", -] - -[[package]] -name = "wayland-protocols-plasma" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a07a14257c077ab3279987c4f8bb987851bf57081b93710381daea94f2c2c032" -dependencies = [ - "bitflags 2.10.0", - "wayland-backend", - "wayland-client", - "wayland-protocols", - "wayland-scanner", -] - -[[package]] -name = "wayland-protocols-wlr" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efd94963ed43cf9938a090ca4f7da58eb55325ec8200c3848963e98dc25b78ec" -dependencies = [ - "bitflags 2.10.0", - "wayland-backend", - "wayland-client", - "wayland-protocols", - "wayland-scanner", -] - -[[package]] -name = "wayland-scanner" -version = "0.31.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54cb1e9dc49da91950bdfd8b848c49330536d9d1fb03d4bfec8cae50caa50ae3" -dependencies = [ - "proc-macro2", - "quick-xml", - "quote", -] - -[[package]] -name = "wayland-sys" -version = "0.31.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34949b42822155826b41db8e5d0c1be3a2bd296c747577a43a3e6daefc296142" -dependencies = [ - "dlib", - "log", - "pkg-config", -] - -[[package]] -name = "web-sys" -version = "0.3.81" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9367c417a924a74cae129e6a2ae3b47fabb1f8995595ab474029da749a8be120" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "web-time" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "wgpu" -version = "26.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70b6ff82bbf6e9206828e1a3178e851f8c20f1c9028e74dd3a8090741ccd5798" -dependencies = [ - "arrayvec", - "bitflags 2.10.0", - "cfg-if", - "cfg_aliases", - "document-features", - "hashbrown 0.15.5", - "js-sys", - "log", - "naga", - "portable-atomic", - "profiling", - "raw-window-handle", - "smallvec", - "static_assertions", - "wasm-bindgen", - "web-sys", - "wgpu-core", - "wgpu-hal", - "wgpu-types", -] - -[[package]] -name = "wgpu-core" -version = "26.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5f62f1053bd28c2268f42916f31588f81f64796e2ff91b81293515017ca8bd9" -dependencies = [ - "arrayvec", - "bit-set", - "bit-vec", - "bitflags 2.10.0", - "cfg_aliases", - "document-features", - "hashbrown 0.15.5", - "indexmap", - "log", - "naga", - "once_cell", - "parking_lot", - "portable-atomic", - "profiling", - "raw-window-handle", - "rustc-hash 1.1.0", - "smallvec", - "thiserror 2.0.17", - "wgpu-core-deps-apple", - "wgpu-core-deps-wasm", - "wgpu-core-deps-windows-linux-android", - "wgpu-hal", - "wgpu-types", -] - -[[package]] -name = "wgpu-core-deps-apple" -version = "26.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18ae5fbde6a4cbebae38358aa73fcd6e0f15c6144b67ef5dc91ded0db125dbdf" -dependencies = [ - "wgpu-hal", -] - -[[package]] -name = "wgpu-core-deps-wasm" -version = "26.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c03b9f9e1a50686d315fc6debe4980cc45cd37b0e919351917df494e8fdc8885" -dependencies = [ - "wgpu-hal", -] - -[[package]] -name = "wgpu-core-deps-windows-linux-android" -version = "26.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "720a5cb9d12b3d337c15ff0e24d3e97ed11490ff3f7506e7f3d98c68fa5d6f14" -dependencies = [ - "wgpu-hal", -] - -[[package]] -name = "wgpu-hal" -version = "26.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7df2c64ac282a91ad7662c90bc4a77d4a2135bc0b2a2da5a4d4e267afc034b9e" -dependencies = [ - "android_system_properties", - "arrayvec", - "ash", - "bit-set", - "bitflags 2.10.0", - "block", - "bytemuck", - "cfg-if", - "cfg_aliases", - "core-graphics-types 0.2.0", - "glow", - "glutin_wgl_sys", - "gpu-alloc", - "gpu-allocator", - "gpu-descriptor", - "hashbrown 0.15.5", - "js-sys", - "khronos-egl", - "libc", - "libloading", - "log", - "metal", - "naga", - "ndk-sys 0.6.0+11769913", - "objc", - "ordered-float", - "parking_lot", - "portable-atomic", - "portable-atomic-util", - "profiling", - "range-alloc", - "raw-window-handle", - "renderdoc-sys", - "smallvec", - "thiserror 2.0.17", - "wasm-bindgen", - "web-sys", - "wgpu-types", - "windows 0.58.0", - "windows-core 0.58.0", -] - -[[package]] -name = "wgpu-types" -version = "26.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eca7a8d8af57c18f57d393601a1fb159ace8b2328f1b6b5f80893f7d672c9ae2" -dependencies = [ - "bitflags 2.10.0", - "bytemuck", - "js-sys", - "log", - "serde", - "thiserror 2.0.17", - "web-sys", -] - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-util" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" -dependencies = [ - "windows-sys 0.61.2", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows" -version = "0.54.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9252e5725dbed82865af151df558e754e4a3c2c30818359eb17465f1346a1b49" -dependencies = [ - "windows-core 0.54.0", - "windows-targets 0.52.6", -] - -[[package]] -name = "windows" -version = "0.58.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" -dependencies = [ - "windows-core 0.58.0", - "windows-targets 0.52.6", -] - -[[package]] -name = "windows" -version = "0.61.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893" -dependencies = [ - "windows-collections 0.2.0", - "windows-core 0.61.2", - "windows-future 0.2.1", - "windows-link 0.1.3", - "windows-numerics 0.2.0", -] - -[[package]] -name = "windows" -version = "0.62.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "527fadee13e0c05939a6a05d5bd6eec6cd2e3dbd648b9f8e447c6518133d8580" -dependencies = [ - "windows-collections 0.3.2", - "windows-core 0.62.2", - "windows-future 0.3.2", - "windows-numerics 0.3.1", -] - -[[package]] -name = "windows-collections" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8" -dependencies = [ - "windows-core 0.61.2", -] - -[[package]] -name = "windows-collections" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23b2d95af1a8a14a3c7367e1ed4fc9c20e0a26e79551b1454d72583c97cc6610" -dependencies = [ - "windows-core 0.62.2", -] - -[[package]] -name = "windows-core" -version = "0.54.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12661b9c89351d684a50a8a643ce5f608e20243b9fb84687800163429f161d65" -dependencies = [ - "windows-result 0.1.2", - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-core" -version = "0.58.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" -dependencies = [ - "windows-implement 0.58.0", - "windows-interface 0.58.0", - "windows-result 0.2.0", - "windows-strings 0.1.0", - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-core" -version = "0.61.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" -dependencies = [ - "windows-implement 0.60.2", - "windows-interface 0.59.3", - "windows-link 0.1.3", - "windows-result 0.3.4", - "windows-strings 0.4.2", -] - -[[package]] -name = "windows-core" -version = "0.62.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" -dependencies = [ - "windows-implement 0.60.2", - "windows-interface 0.59.3", - "windows-link 0.2.1", - "windows-result 0.4.1", - "windows-strings 0.5.1", -] - -[[package]] -name = "windows-future" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e" -dependencies = [ - "windows-core 0.61.2", - "windows-link 0.1.3", - "windows-threading 0.1.0", -] - -[[package]] -name = "windows-future" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1d6f90251fe18a279739e78025bd6ddc52a7e22f921070ccdc67dde84c605cb" -dependencies = [ - "windows-core 0.62.2", - "windows-link 0.2.1", - "windows-threading 0.2.1", -] - -[[package]] -name = "windows-implement" -version = "0.58.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "windows-implement" -version = "0.60.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "windows-interface" -version = "0.58.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "windows-interface" -version = "0.59.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "windows-link" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" - -[[package]] -name = "windows-link" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" - -[[package]] -name = "windows-numerics" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1" -dependencies = [ - "windows-core 0.61.2", - "windows-link 0.1.3", -] - -[[package]] -name = "windows-numerics" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e2e40844ac143cdb44aead537bbf727de9b044e107a0f1220392177d15b0f26" -dependencies = [ - "windows-core 0.62.2", - "windows-link 0.2.1", -] - -[[package]] -name = "windows-result" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-result" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-result" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" -dependencies = [ - "windows-link 0.1.3", -] - -[[package]] -name = "windows-result" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" -dependencies = [ - "windows-link 0.2.1", -] - -[[package]] -name = "windows-strings" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" -dependencies = [ - "windows-result 0.2.0", - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-strings" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" -dependencies = [ - "windows-link 0.1.3", -] - -[[package]] -name = "windows-strings" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" -dependencies = [ - "windows-link 0.2.1", -] - -[[package]] -name = "windows-sys" -version = "0.45.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" -dependencies = [ - "windows-targets 0.42.2", -] - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-sys" -version = "0.59.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-sys" -version = "0.60.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" -dependencies = [ - "windows-targets 0.53.5", -] - -[[package]] -name = "windows-sys" -version = "0.61.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" -dependencies = [ - "windows-link 0.2.1", -] - -[[package]] -name = "windows-targets" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" -dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", -] - -[[package]] -name = "windows-targets" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" -dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 0.52.6", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", -] - -[[package]] -name = "windows-targets" -version = "0.53.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" -dependencies = [ - "windows-link 0.2.1", - "windows_aarch64_gnullvm 0.53.1", - "windows_aarch64_msvc 0.53.1", - "windows_i686_gnu 0.53.1", - "windows_i686_gnullvm 0.53.1", - "windows_i686_msvc 0.53.1", - "windows_x86_64_gnu 0.53.1", - "windows_x86_64_gnullvm 0.53.1", - "windows_x86_64_msvc 0.53.1", -] - -[[package]] -name = "windows-threading" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6" -dependencies = [ - "windows-link 0.1.3", -] - -[[package]] -name = "windows-threading" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3949bd5b99cafdf1c7ca86b43ca564028dfe27d66958f2470940f73d86d75b37" -dependencies = [ - "windows-link 0.2.1", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" - -[[package]] -name = "windows_i686_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" - -[[package]] -name = "windows_i686_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - -[[package]] -name = "windows_i686_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" - -[[package]] -name = "winit" -version = "0.30.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c66d4b9ed69c4009f6321f762d6e61ad8a2389cd431b97cb1e146812e9e6c732" -dependencies = [ - "ahash", - "android-activity", - "atomic-waker", - "bitflags 2.10.0", - "block2 0.5.1", - "bytemuck", - "calloop", - "cfg_aliases", - "concurrent-queue", - "core-foundation 0.9.4", - "core-graphics", - "cursor-icon", - "dpi", - "js-sys", - "libc", - "memmap2", - "ndk 0.9.0", - "objc2 0.5.2", - "objc2-app-kit 0.2.2", - "objc2-foundation 0.2.2", - "objc2-ui-kit", - "orbclient", - "percent-encoding", - "pin-project", - "raw-window-handle", - "redox_syscall 0.4.1", - "rustix 0.38.44", - "sctk-adwaita", - "smithay-client-toolkit", - "smol_str", - "tracing", - "unicode-segmentation", - "wasm-bindgen", - "wasm-bindgen-futures", - "wayland-backend", - "wayland-client", - "wayland-protocols", - "wayland-protocols-plasma", - "web-sys", - "web-time", - "windows-sys 0.52.0", - "x11-dl", - "x11rb", - "xkbcommon-dl", -] - -[[package]] -name = "winnow" -version = "0.7.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf" -dependencies = [ - "memchr", -] - -[[package]] -name = "wit-bindgen" -version = "0.46.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" - -[[package]] -name = "x11-dl" -version = "2.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38735924fedd5314a6e548792904ed8c6de6636285cb9fec04d5b1db85c1516f" -dependencies = [ - "libc", - "once_cell", - "pkg-config", -] - -[[package]] -name = "x11rb" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9993aa5be5a26815fe2c3eacfc1fde061fc1a1f094bf1ad2a18bf9c495dd7414" -dependencies = [ - "as-raw-xcb-connection", - "gethostname", - "libc", - "libloading", - "once_cell", - "rustix 1.1.2", - "x11rb-protocol", -] - -[[package]] -name = "x11rb-protocol" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea6fc2961e4ef194dcbfe56bb845534d0dc8098940c7e5c012a258bfec6701bd" - -[[package]] -name = "xcursor" -version = "0.3.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bec9e4a500ca8864c5b47b8b482a73d62e4237670e5b5f1d6b9e3cae50f28f2b" - -[[package]] -name = "xkbcommon-dl" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d039de8032a9a8856a6be89cea3e5d12fdd82306ab7c94d74e6deab2460651c5" -dependencies = [ - "bitflags 2.10.0", - "dlib", - "log", - "once_cell", - "xkeysym", -] - -[[package]] -name = "xkeysym" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9cc00251562a284751c9973bace760d86c0276c471b4be569fe6b068ee97a56" - -[[package]] -name = "xml-rs" -version = "0.8.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fd8403733700263c6eb89f192880191f1b83e332f7a20371ddcf421c4a337c7" - -[[package]] -name = "yazi" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e01738255b5a16e78bbb83e7fbba0a1e7dd506905cfc53f4622d89015a03fbb5" - -[[package]] -name = "zeno" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6df3dc4292935e51816d896edcd52aa30bc297907c26167fec31e2b0c6a32524" - -[[package]] -name = "zerocopy" -version = "0.8.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.8.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] diff --git a/libProcessing/Cargo.toml b/libProcessing/Cargo.toml deleted file mode 100644 index 8b8a1ccc7..000000000 --- a/libProcessing/Cargo.toml +++ /dev/null @@ -1,9 +0,0 @@ -[workspace] -resolver = "3" -members = ["ffi","renderer"] - -[workspace.dependencies] -bevy = { version = "0.17", no-default-features = true, features = [ - "bevy_render", - "bevy_color", -] } \ No newline at end of file diff --git a/libProcessing/ffi/Cargo.toml b/libProcessing/ffi/Cargo.toml deleted file mode 100644 index 9ea189563..000000000 --- a/libProcessing/ffi/Cargo.toml +++ /dev/null @@ -1,15 +0,0 @@ -[package] -name = "ffi" -version = "0.1.0" -edition = "2024" - -[lib] -name = "processing" -crate-type = ["cdylib"] - -[dependencies] -renderer = { path = "../renderer" } -bevy = { workspace = true } - -[build-dependencies] -cbindgen = "0.29" diff --git a/libProcessing/ffi/build.rs b/libProcessing/ffi/build.rs deleted file mode 100644 index e94d8186d..000000000 --- a/libProcessing/ffi/build.rs +++ /dev/null @@ -1,27 +0,0 @@ -use std::{env, path::PathBuf}; - -fn main() { - let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap(); - let output_dir = PathBuf::from(&crate_dir).join("include"); - - std::fs::create_dir_all(&output_dir).expect("Failed to create include directory"); - - let output_file = output_dir.join("processing.h"); - let config_path = PathBuf::from(&crate_dir).join("cbindgen.toml"); - - cbindgen::Builder::new() - .with_config( - cbindgen::Config::from_file(&config_path).expect("Failed to load cbindgen.toml"), - ) - .with_crate(&crate_dir) - .generate() - .expect("Unable to generate bindings") - .write_to_file(&output_file); - - println!("cargo:rerun-if-changed=src/lib.rs"); - println!("cargo:rerun-if-changed=cbindgen.toml"); - println!( - "cargo:warning=Generated header at: {}", - output_file.display() - ); -} diff --git a/libProcessing/ffi/cbindgen.toml b/libProcessing/ffi/cbindgen.toml deleted file mode 100644 index 923b8ac56..000000000 --- a/libProcessing/ffi/cbindgen.toml +++ /dev/null @@ -1,12 +0,0 @@ -language = "C" -pragma_once = true -include_guard = "PROCESSING_H" -autogen_warning = "/* Warning, this file is autogenerated by cbindgen. Don't modify this manually. */" -include_version = true -documentation = true -documentation_style = "c99" - -[export] -# Export all - -[export.rename] \ No newline at end of file diff --git a/libProcessing/ffi/src/color.rs b/libProcessing/ffi/src/color.rs deleted file mode 100644 index fc063be63..000000000 --- a/libProcessing/ffi/src/color.rs +++ /dev/null @@ -1,15 +0,0 @@ -/// A sRGB (?) color -#[repr(C)] -#[derive(Debug, Clone, Copy)] -pub struct Color { - pub r: f32, - pub g: f32, - pub b: f32, - pub a: f32, -} - -impl From for bevy::color::Color { - fn from(color: Color) -> Self { - bevy::color::Color::srgba(color.r, color.g, color.b, color.a) - } -} diff --git a/libProcessing/ffi/src/error.rs b/libProcessing/ffi/src/error.rs deleted file mode 100644 index ee509cd0c..000000000 --- a/libProcessing/ffi/src/error.rs +++ /dev/null @@ -1,65 +0,0 @@ -use std::{ - cell::RefCell, - ffi::{CString, c_char}, - panic, -}; - -use renderer::error::ProcessingError; - -thread_local! { - static LAST_ERROR: RefCell> = RefCell::new(None); -} - -/// Check if the last operation resulted in an error. Returns a pointer to an error message, or null -/// if there was no error. -#[unsafe(no_mangle)] -pub extern "C" fn processing_check_error() -> *const c_char { - LAST_ERROR.with(|last| { - last.borrow() - .as_ref() - .map(|s| s.as_ptr()) - .unwrap_or(std::ptr::null()) - }) -} - -/// Set the last error message. -pub fn set_error(error_msg: &str) { - LAST_ERROR.with(|last| { - *last.borrow_mut() = Some(CString::new(error_msg).unwrap_or_else(|_| { - CString::new("Failed to allocate error message".to_string()).unwrap() - })); - }); -} - -/// Clear the last error message. -pub fn clear_error() { - LAST_ERROR.with(|last| { - *last.borrow_mut() = None; - }); -} - -/// Check the result of an operation, setting the last error if there was one. -pub fn check(f: F) -> Option -where - F: FnOnce() -> Result + panic::UnwindSafe, -{ - // we'll catch panics here to prevent unwinding across the FFI boundary - panic::catch_unwind(|| match f() { - Ok(value) => Some(value), - Err(err) => { - set_error(&err.to_string()); - None - } - }) - .unwrap_or_else(|e| { - let msg = if let Some(s) = e.downcast_ref::() { - s.clone() - } else if let Some(s) = e.downcast_ref::<&'static str>() { - s.to_string() - } else { - "Unknown panic payload".to_string() - }; - set_error(&format!("Panic occurred: {}", msg)); - None - }) -} diff --git a/libProcessing/ffi/src/lib.rs b/libProcessing/ffi/src/lib.rs deleted file mode 100644 index bde38a56b..000000000 --- a/libProcessing/ffi/src/lib.rs +++ /dev/null @@ -1,223 +0,0 @@ -use bevy::prelude::Entity; -use renderer::render::command::DrawCommand; - -use crate::color::Color; - -mod color; -mod error; - -/// Initialize libProcessing. -/// -/// SAFETY: -/// - This is called from the main thread if the platform requires it. -/// - This can only be called once. -#[unsafe(no_mangle)] -pub extern "C" fn processing_init() { - error::clear_error(); - error::check(|| renderer::init()); -} - -/// Create a WebGPU surface from a native window handle. -/// Returns a window ID (entity ID) that should be used for subsequent operations. -/// Returns 0 on failure. -/// -/// SAFETY: -/// - Init has been called. -/// - window_handle is a valid GLFW window pointer. -/// - This is called from the same thread as init. -#[unsafe(no_mangle)] -pub extern "C" fn processing_create_surface( - window_handle: u64, - width: u32, - height: u32, - scale_factor: f32, -) -> u64 { - error::clear_error(); - error::check(|| renderer::create_surface(window_handle, width, height, scale_factor)) - .unwrap_or(0) -} - -/// Destroy the surface associated with the given window ID. -/// -/// SAFETY: -/// - Init and create_surface have been called. -/// - window_id is a valid ID returned from create_surface. -/// - This is called from the same thread as init. -#[unsafe(no_mangle)] -pub extern "C" fn processing_destroy_surface(window_id: u64) { - error::clear_error(); - let window_entity = Entity::from_bits(window_id); - error::check(|| renderer::destroy_surface(window_entity)); -} - -/// Update window size when resized. -/// -/// SAFETY: -/// - Init and create_surface have been called. -/// - window_id is a valid ID returned from create_surface. -/// - This is called from the same thread as init. -#[unsafe(no_mangle)] -pub extern "C" fn processing_resize_surface(window_id: u64, width: u32, height: u32) { - error::clear_error(); - let window_entity = Entity::from_bits(window_id); - error::check(|| renderer::resize_surface(window_entity, width, height)); -} - -/// Set the background color for the given window. -/// -/// SAFETY: -/// - This is called from the same thread as init. -#[unsafe(no_mangle)] -pub extern "C" fn processing_background_color(window_id: u64, color: Color) { - error::clear_error(); - let window_entity = Entity::from_bits(window_id); - error::check(|| renderer::background_color(window_entity, color.into())); -} - -/// Begins the draw for the given window. -/// -/// SAFETY: -/// - Init has been called and exit has not been called. -/// - This is called from the same thread as init. -#[unsafe(no_mangle)] -pub extern "C" fn processing_begin_draw(window_id: u64) { - error::clear_error(); - let window_entity = Entity::from_bits(window_id); - error::check(|| renderer::begin_draw(window_entity)); -} - -/// Flushes recorded draw commands for the given window. -/// -/// SAFETY: -/// - Init has been called and exit has not been called. -/// - This is called from the same thread as init. -#[unsafe(no_mangle)] -pub extern "C" fn processing_flush(window_id: u64) { - error::clear_error(); - let window_entity = Entity::from_bits(window_id); - error::check(|| renderer::flush(window_entity)); -} - -/// Ends the draw for the given window and presents the frame. -/// -/// SAFETY: -/// - Init has been called and exit has not been called. -/// - This is called from the same thread as init. -#[unsafe(no_mangle)] -pub extern "C" fn processing_end_draw(window_id: u64) { - error::clear_error(); - let window_entity = Entity::from_bits(window_id); - error::check(|| renderer::end_draw(window_entity)); -} - -/// Shuts down internal resources with given exit code, but does *not* terminate the process. -/// -/// SAFETY: -/// - This is called from the same thread as init. -/// - Caller ensures that update is never called again after exit. -#[unsafe(no_mangle)] -pub extern "C" fn processing_exit(exit_code: u8) { - error::clear_error(); - error::check(|| renderer::exit(exit_code)); -} - -/// Set the fill color. -/// -/// SAFETY: -/// - Init and create_surface have been called. -/// - window_id is a valid ID returned from create_surface. -/// - This is called from the same thread as init. -#[unsafe(no_mangle)] -pub extern "C" fn processing_set_fill(window_id: u64, r: f32, g: f32, b: f32, a: f32) { - error::clear_error(); - let window_entity = Entity::from_bits(window_id); - let color = bevy::color::Color::srgba(r, g, b, a); - error::check(|| renderer::record_command(window_entity, DrawCommand::Fill(color))); -} - -/// Set the stroke color. -/// -/// SAFETY: -/// - Init and create_surface have been called. -/// - window_id is a valid ID returned from create_surface. -/// - This is called from the same thread as init. -#[unsafe(no_mangle)] -pub extern "C" fn processing_set_stroke_color(window_id: u64, r: f32, g: f32, b: f32, a: f32) { - error::clear_error(); - let window_entity = Entity::from_bits(window_id); - let color = bevy::color::Color::srgba(r, g, b, a); - error::check(|| renderer::record_command(window_entity, DrawCommand::StrokeColor(color))); -} - -/// Set the stroke weight. -/// -/// SAFETY: -/// - Init and create_surface have been called. -/// - window_id is a valid ID returned from create_surface. -/// - This is called from the same thread as init. -#[unsafe(no_mangle)] -pub extern "C" fn processing_set_stroke_weight(window_id: u64, weight: f32) { - error::clear_error(); - let window_entity = Entity::from_bits(window_id); - error::check(|| renderer::record_command(window_entity, DrawCommand::StrokeWeight(weight))); -} - -/// Disable fill for subsequent shapes. -/// -/// SAFETY: -/// - Init and create_surface have been called. -/// - window_id is a valid ID returned from create_surface. -/// - This is called from the same thread as init. -#[unsafe(no_mangle)] -pub extern "C" fn processing_no_fill(window_id: u64) { - error::clear_error(); - let window_entity = Entity::from_bits(window_id); - error::check(|| renderer::record_command(window_entity, DrawCommand::NoFill)); -} - -/// Disable stroke for subsequent shapes. -/// -/// SAFETY: -/// - Init and create_surface have been called. -/// - window_id is a valid ID returned from create_surface. -/// - This is called from the same thread as init. -#[unsafe(no_mangle)] -pub extern "C" fn processing_no_stroke(window_id: u64) { - error::clear_error(); - let window_entity = Entity::from_bits(window_id); - error::check(|| renderer::record_command(window_entity, DrawCommand::NoStroke)); -} - -/// Draw a rectangle. -/// -/// SAFETY: -/// - Init and create_surface have been called. -/// - window_id is a valid ID returned from create_surface. -/// - This is called from the same thread as init. -#[unsafe(no_mangle)] -pub extern "C" fn processing_rect( - window_id: u64, - x: f32, - y: f32, - w: f32, - h: f32, - tl: f32, - tr: f32, - br: f32, - bl: f32, -) { - error::clear_error(); - let window_entity = Entity::from_bits(window_id); - error::check(|| { - renderer::record_command( - window_entity, - DrawCommand::Rect { - x, - y, - w, - h, - radii: [tl, tr, br, bl], - }, - ) - }); -} diff --git a/libProcessing/renderer/Cargo.toml b/libProcessing/renderer/Cargo.toml deleted file mode 100644 index c78a2f976..000000000 --- a/libProcessing/renderer/Cargo.toml +++ /dev/null @@ -1,19 +0,0 @@ -[package] -name = "renderer" -version = "0.1.0" -edition = "2024" - -[dependencies] -bevy = { workspace = true } -lyon = "1.0" -raw-window-handle = "0.6" -thiserror = "2" -tracing = "0.1" -tracing-subscriber = "0.3" - -[target.'cfg(target_os = "macos")'.dependencies] -objc2 = { version = "0.6", default-features = false } -objc2-app-kit = { version = "0.3", features = ["NSWindow", "NSView"] } - -[target.'cfg(target_os = "windows")'.dependencies] -windows = { version = "0.58", features = ["Win32_Foundation", "Win32_System_LibraryLoader"] } \ No newline at end of file diff --git a/libProcessing/renderer/src/error.rs b/libProcessing/renderer/src/error.rs deleted file mode 100644 index 9eedd9d26..000000000 --- a/libProcessing/renderer/src/error.rs +++ /dev/null @@ -1,17 +0,0 @@ -use thiserror::Error; - -pub type Result = std::result::Result; - -#[derive(Error, Debug)] -pub enum ProcessingError { - #[error("App was accessed from multiple threads")] - AppAccess, - #[error("Error initializing tracing: {0}")] - Tracing(#[from] tracing::subscriber::SetGlobalDefaultError), - #[error("Window not found")] - WindowNotFound, - #[error("Handle error: {0}")] - HandleError(#[from] raw_window_handle::HandleError), - #[error("Invalid window handle provided")] - InvalidWindowHandle, -} diff --git a/libProcessing/renderer/src/lib.rs b/libProcessing/renderer/src/lib.rs deleted file mode 100644 index 18c316256..000000000 --- a/libProcessing/renderer/src/lib.rs +++ /dev/null @@ -1,427 +0,0 @@ -pub mod error; -pub mod render; - -use std::{cell::RefCell, num::NonZero, sync::OnceLock}; - -use bevy::{ - app::{App, AppExit}, - asset::AssetEventSystems, - camera::{CameraOutputMode, RenderTarget, visibility::RenderLayers}, - log::tracing_subscriber, - prelude::*, - window::{RawHandleWrapper, Window, WindowRef, WindowResolution, WindowWrapper}, -}; -use raw_window_handle::{ - DisplayHandle, HandleError, HasDisplayHandle, HasWindowHandle, RawDisplayHandle, - RawWindowHandle, WindowHandle, -}; -use render::{activate_cameras, clear_transient_meshes, flush_draw_commands}; -use tracing::debug; - -use crate::{ - error::Result, - render::command::{CommandBuffer, DrawCommand}, -}; - -static IS_INIT: OnceLock<()> = OnceLock::new(); - -thread_local! { - static APP: OnceLock> = OnceLock::default(); -} - -#[derive(Resource, Default)] -struct WindowCount(u32); - -#[derive(Component)] -pub struct Flush; - -fn app(cb: impl FnOnce(&App) -> Result) -> Result { - let res = APP.with(|app_lock| { - let app = app_lock - .get() - .ok_or_else(|| error::ProcessingError::AppAccess)? - .borrow(); - cb(&app) - })?; - Ok(res) -} - -fn app_mut(cb: impl FnOnce(&mut App) -> Result) -> Result { - let res = APP.with(|app_lock| { - let mut app = app_lock - .get() - .ok_or_else(|| error::ProcessingError::AppAccess)? - .borrow_mut(); - cb(&mut app) - })?; - Ok(res) -} - -struct GlfwWindow { - window_handle: RawWindowHandle, - display_handle: RawDisplayHandle, -} - -// SAFETY: -// - RawWindowHandle and RawDisplayHandle are just pointers -// - The actual window is managed by Java and outlives this struct -// - GLFW is thread-safe-ish, see https://www.glfw.org/faq#29---is-glfw-thread-safe -// -// Note: we enforce that all calls to init/update/exit happen on the main thread, so -// there should be no concurrent access to the window from multiple threads anyway. -unsafe impl Send for GlfwWindow {} -unsafe impl Sync for GlfwWindow {} - -impl HasWindowHandle for GlfwWindow { - fn window_handle(&self) -> core::result::Result, HandleError> { - // SAFETY: - // - Handles passed from Java are valid - Ok(unsafe { WindowHandle::borrow_raw(self.window_handle) }) - } -} - -impl HasDisplayHandle for GlfwWindow { - fn display_handle(&self) -> core::result::Result, HandleError> { - // SAFETY: - // - Handles passed from Java are valid - Ok(unsafe { DisplayHandle::borrow_raw(self.display_handle) }) - } -} - -/// Create a WebGPU surface from a native window handle. -/// -/// Currently, this just creates a bevy window with the given parameters and -/// stores the raw window handle for later use by the renderer, which will -/// actually create the surface. -pub fn create_surface( - window_handle: u64, - width: u32, - height: u32, - scale_factor: f32, -) -> Result { - #[cfg(target_os = "macos")] - let (raw_window_handle, raw_display_handle) = { - use raw_window_handle::{AppKitDisplayHandle, AppKitWindowHandle}; - - // GLFW gives us NSWindow*, but AppKitWindowHandle needs NSView* - // so we have to do some objc magic to grab the right pointer - let ns_view_ptr = { - use objc2::rc::Retained; - use objc2_app_kit::{NSView, NSWindow}; - - // SAFETY: - // - window_handle is a valid NSWindow pointer from the GLFW window - let ns_window = window_handle as *mut NSWindow; - if ns_window.is_null() { - return Err(error::ProcessingError::InvalidWindowHandle); - } - - // SAFETY: - // - The contentView is owned by NSWindow and remains valid as long as the window exists - let ns_window_ref = unsafe { &*ns_window }; - let content_view: Option> = ns_window_ref.contentView(); - - match content_view { - Some(view) => { - let view_ptr = Retained::as_ptr(&view) as *mut std::ffi::c_void; - view_ptr - } - None => { - return Err(error::ProcessingError::InvalidWindowHandle); - } - } - }; - - let window = AppKitWindowHandle::new(std::ptr::NonNull::new(ns_view_ptr).unwrap()); - let display = AppKitDisplayHandle::new(); - ( - RawWindowHandle::AppKit(window), - RawDisplayHandle::AppKit(display), - ) - }; - - #[cfg(target_os = "windows")] - let (raw_window_handle, raw_display_handle) = { - use raw_window_handle::{Win32WindowHandle, WindowsDisplayHandle}; - use std::num::NonZeroIsize; - use windows::Win32::Foundation::HINSTANCE; - use windows::Win32::System::LibraryLoader::GetModuleHandleW; - - if window_handle == 0 { - return Err(error::ProcessingError::InvalidWindowHandle); - } - - // HWND is isize, so cast it - let hwnd_isize = window_handle as isize; - let hwnd_nonzero = match NonZeroIsize::new(hwnd_isize) { - Some(nz) => nz, - None => return Err(error::ProcessingError::InvalidWindowHandle), - }; - - let mut window = Win32WindowHandle::new(hwnd_nonzero); - - // VK_KHR_win32_surface requires hinstance *and* hwnd - // SAFETY: GetModuleHandleW(NULL) is safe - let hinstance = unsafe { GetModuleHandleW(None) } - .map_err(|_| error::ProcessingError::InvalidWindowHandle)?; - - let hinstance_nonzero = NonZeroIsize::new(hinstance.0 as isize) - .ok_or(error::ProcessingError::InvalidWindowHandle)?; - window.hinstance = Some(hinstance_nonzero); - - let display = WindowsDisplayHandle::new(); - - ( - RawWindowHandle::Win32(window), - RawDisplayHandle::Windows(display), - ) - }; - - #[cfg(target_os = "linux")] - let (raw_window_handle, raw_display_handle) = - { todo!("implement linux raw window handle conversion") }; - - let glfw_window = GlfwWindow { - window_handle: raw_window_handle, - display_handle: raw_display_handle, - }; - - let window_wrapper = WindowWrapper::new(glfw_window); - let handle_wrapper = RawHandleWrapper::new(&window_wrapper)?; - - let entity_id = app_mut(|app| { - let mut window_count = app.world_mut().resource_mut::(); - let count = window_count.0; - window_count.0 += 1; - let render_layer = RenderLayers::none().with(count as usize); - - let mut window = app.world_mut().spawn(( - Window { - resolution: WindowResolution::new(width, height) - .with_scale_factor_override(scale_factor), - ..default() - }, - handle_wrapper, - CommandBuffer::default(), - // this doesn't do anything but makes it easier to fetch the render layer for - // meshes to be drawn to this window - render_layer.clone(), - )); - - let window_entity = window.id(); - window.with_children(|parent| { - // processing has a different coordinate system for 2d rendering: - // - origin at top-left - // - x increases to the right, y increases downward - // - coordinate units are in screen pixels - let half_width = width as f32 / 2.0; - let half_height = height as f32 / 2.0; - - let projection = OrthographicProjection { - near: -1000.0, - far: 1000.0, - viewport_origin: Vec2::new(0.0, 0.0), // top left - scaling_mode: bevy::camera::ScalingMode::Fixed { - width: width as f32, - height: height as f32, - }, - scale: 1.0, - ..OrthographicProjection::default_3d() - }; - - parent.spawn(( - Camera3d::default(), - Camera { - target: RenderTarget::Window(WindowRef::Entity(window_entity)), - ..default() - }, - Projection::Orthographic(projection), - // position camera to match coordinate system - Transform::from_xyz(half_width, -half_height, 999.0) - .looking_at(Vec3::new(half_width, -half_height, 0.0), Vec3::Y), - render_layer, - )); - }); - - Ok(window_entity.to_bits()) - })?; - - Ok(entity_id) -} - -pub fn destroy_surface(window_entity: Entity) -> Result<()> { - app_mut(|app| { - if app.world_mut().get::(window_entity).is_some() { - app.world_mut().despawn(window_entity); - let mut window_count = app.world_mut().resource_mut::(); - window_count.0 = window_count.0.saturating_sub(1); - } - Ok(()) - }) -} - -/// Update window size when resized. -pub fn resize_surface(window_entity: Entity, width: u32, height: u32) -> Result<()> { - app_mut(|app| { - if let Some(mut window) = app.world_mut().get_mut::(window_entity) { - window.resolution.set_physical_resolution(width, height); - Ok(()) - } else { - Err(error::ProcessingError::WindowNotFound) - } - }) -} - -/// Initialize the app, if not already initialized. Must be called from the main thread and cannot -/// be called concurrently from multiple threads. -pub fn init() -> Result<()> { - setup_tracing()?; - let is_init = IS_INIT.get().is_some(); - let thread_has_app = APP.with(|app_lock| app_lock.get().is_some()); - if is_init && !thread_has_app { - return Err(error::ProcessingError::AppAccess); - } - if is_init && thread_has_app { - debug!("App already initialized"); - return Ok(()); - } - - APP.with(|app_lock| { - app_lock.get_or_init(|| { - IS_INIT.get_or_init(|| ()); - let mut app = App::new(); - - app.add_plugins( - DefaultPlugins - .build() - .disable::() - .disable::() - .disable::() - .set(WindowPlugin { - primary_window: None, - exit_condition: bevy::window::ExitCondition::DontExit, - ..default() - }), - ); - - // resources - app.init_resource::(); - - // rendering - app.add_systems(First, (clear_transient_meshes, activate_cameras)) - .add_systems(Update, flush_draw_commands.before(AssetEventSystems)); - - // this does not mean, as one might imagine, that the app is "done", but rather is part - // of bevy's plugin lifecycle prior to "starting" the app. we are manually driving the app - // so we don't need to call `app.run()` - app.finish(); - app.cleanup(); - RefCell::new(app) - }); - }); - - Ok(()) -} - -macro_rules! camera_mut { - ($app:expr, $window_entity:expr) => { - $app.world_mut() - .query::<(&mut Camera, &ChildOf)>() - .iter_mut(&mut $app.world_mut()) - .filter_map(|(camera, parent)| { - if parent.parent() == $window_entity { - Some(camera) - } else { - None - } - }) - .next() - .ok_or_else(|| error::ProcessingError::WindowNotFound)? - }; -} - -macro_rules! window_mut { - ($app:expr, $window_entity:expr) => { - $app.world_mut() - .get_entity_mut($window_entity) - .map_err(|_| error::ProcessingError::WindowNotFound)? - }; -} - -pub fn begin_draw(_window_entity: Entity) -> Result<()> { - app_mut(|_app| Ok(())) -} - -pub fn flush(window_entity: Entity) -> Result<()> { - app_mut(|app| { - window_mut!(app, window_entity).insert(Flush); - app.update(); - window_mut!(app, window_entity).remove::(); - - // ensure that the intermediate texture is not cleared - camera_mut!(app, window_entity).clear_color = ClearColorConfig::None; - Ok(()) - }) -} - -pub fn end_draw(window_entity: Entity) -> Result<()> { - // since we are ending the draw, set the camera to write to the output render target - app_mut(|app| { - camera_mut!(app, window_entity).output_mode = CameraOutputMode::Write { - blend_state: None, - clear_color: ClearColorConfig::Default, - }; - Ok(()) - })?; - // flush any remaining draw commands, this ensures that the frame is presented even if there - // is no remaining draw commands - flush(window_entity)?; - // reset to skipping output for the next frame - app_mut(|app| { - camera_mut!(app, window_entity).output_mode = CameraOutputMode::Skip; - Ok(()) - }) -} - -pub fn exit(exit_code: u8) -> Result<()> { - app_mut(|app| { - app.world_mut().write_message(match exit_code { - 0 => AppExit::Success, - _ => AppExit::Error(NonZero::new(exit_code).unwrap()), - }); - - // one final update to process the exit message - app.update(); - Ok(()) - }) -} - -pub fn background_color(window_entity: Entity, color: Color) -> Result<()> { - app_mut(|app| { - let mut camera_query = app.world_mut().query::<(&mut Camera, &ChildOf)>(); - for (mut camera, parent) in camera_query.iter_mut(&mut app.world_mut()) { - if parent.parent() == window_entity { - camera.clear_color = ClearColorConfig::Custom(color); - } - } - Ok(()) - }) -} - -fn setup_tracing() -> Result<()> { - let subscriber = tracing_subscriber::FmtSubscriber::new(); - tracing::subscriber::set_global_default(subscriber)?; - Ok(()) -} - -/// Record a drawing command for a window -pub fn record_command(window_entity: Entity, cmd: DrawCommand) -> Result<()> { - app_mut(|app| { - let mut entity_mut = app.world_mut().entity_mut(window_entity); - if let Some(mut buffer) = entity_mut.get_mut::() { - buffer.push(cmd); - } - - Ok(()) - }) -} diff --git a/libProcessing/renderer/src/render/command.rs b/libProcessing/renderer/src/render/command.rs deleted file mode 100644 index 8965aaea0..000000000 --- a/libProcessing/renderer/src/render/command.rs +++ /dev/null @@ -1,38 +0,0 @@ -use bevy::prelude::*; - -#[derive(Debug, Clone)] -pub enum DrawCommand { - Fill(Color), - NoFill, - StrokeColor(Color), - NoStroke, - StrokeWeight(f32), - Rect { - x: f32, - y: f32, - w: f32, - h: f32, - radii: [f32; 4], // [tl, tr, br, bl] - }, -} - -#[derive(Debug, Default, Component)] -pub struct CommandBuffer { - pub commands: Vec, -} - -impl CommandBuffer { - pub fn new() -> Self { - Self { - commands: Vec::new(), - } - } - - pub fn push(&mut self, cmd: DrawCommand) { - self.commands.push(cmd); - } - - pub fn clear(&mut self) { - self.commands.clear(); - } -} diff --git a/libProcessing/renderer/src/render/material.rs b/libProcessing/renderer/src/render/material.rs deleted file mode 100644 index 9529e8ec4..000000000 --- a/libProcessing/renderer/src/render/material.rs +++ /dev/null @@ -1,22 +0,0 @@ -use bevy::{prelude::*, render::alpha::AlphaMode}; - -#[derive(Clone, PartialEq, Eq, Hash, Debug)] -pub struct MaterialKey { - pub transparent: bool, -} - -impl MaterialKey { - pub fn to_material(&self) -> StandardMaterial { - StandardMaterial { - base_color: Color::WHITE, - unlit: true, - cull_mode: None, - alpha_mode: if self.transparent { - AlphaMode::Blend - } else { - AlphaMode::Opaque - }, - ..default() - } - } -} diff --git a/libProcessing/renderer/src/render/mesh_builder.rs b/libProcessing/renderer/src/render/mesh_builder.rs deleted file mode 100644 index ce3a5ae58..000000000 --- a/libProcessing/renderer/src/render/mesh_builder.rs +++ /dev/null @@ -1,101 +0,0 @@ -use bevy::{ - mesh::{Indices, VertexAttributeValues}, - prelude::*, -}; -use lyon::tessellation::{ - FillVertex, StrokeVertex, VertexId, - geometry_builder::{ - FillGeometryBuilder, GeometryBuilder, GeometryBuilderError, StrokeGeometryBuilder, - }, -}; - -pub struct MeshBuilder<'a> { - mesh: &'a mut Mesh, - color: Color, - begin_vertex_count: u32, -} - -impl<'a> MeshBuilder<'a> { - pub fn new(mesh: &'a mut Mesh, color: Color) -> Self { - Self { - mesh, - color, - begin_vertex_count: 0, - } - } - - fn push_vertex(&mut self, position: [f32; 3]) -> VertexId { - let id = VertexId::from_usize(self.vertex_count()); - - if let Some(VertexAttributeValues::Float32x3(positions)) = - self.mesh.attribute_mut(Mesh::ATTRIBUTE_POSITION) - { - positions.push(position); - } - - if let Some(VertexAttributeValues::Float32x4(colors)) = - self.mesh.attribute_mut(Mesh::ATTRIBUTE_COLOR) - { - colors.push(self.color.to_srgba().to_f32_array()); - } - - if let Some(VertexAttributeValues::Float32x3(normals)) = - self.mesh.attribute_mut(Mesh::ATTRIBUTE_NORMAL) - { - normals.push([0.0, 0.0, 1.0]); // flat normal for 2d - } - - id - } - - fn push_index(&mut self, index: u32) { - if let Some(Indices::U32(indices)) = self.mesh.indices_mut() { - indices.push(index); - } - } - - fn vertex_count(&self) -> usize { - if let Some(VertexAttributeValues::Float32x3(positions)) = - self.mesh.attribute(Mesh::ATTRIBUTE_POSITION) - { - positions.len() - } else { - 0 - } - } -} - -impl<'a> GeometryBuilder for MeshBuilder<'a> { - fn begin_geometry(&mut self) { - self.begin_vertex_count = self.vertex_count() as u32; - } - - fn add_triangle(&mut self, a: VertexId, b: VertexId, c: VertexId) { - self.push_index(a.to_usize() as u32); - self.push_index(b.to_usize() as u32); - self.push_index(c.to_usize() as u32); - } - - fn abort_geometry(&mut self) { - todo!("Implement abort_geometry if needed"); - } -} - -impl<'a> FillGeometryBuilder for MeshBuilder<'a> { - fn add_fill_vertex(&mut self, vertex: FillVertex) -> Result { - let pos = vertex.position(); - let position = [pos.x, pos.y, 0.0]; - Ok(self.push_vertex(position)) - } -} - -impl<'a> StrokeGeometryBuilder for MeshBuilder<'a> { - fn add_stroke_vertex( - &mut self, - vertex: StrokeVertex, - ) -> Result { - let pos = vertex.position(); - let position = [pos.x, pos.y, 0.0]; - Ok(self.push_vertex(position)) - } -} diff --git a/libProcessing/renderer/src/render/mod.rs b/libProcessing/renderer/src/render/mod.rs deleted file mode 100644 index 98222a536..000000000 --- a/libProcessing/renderer/src/render/mod.rs +++ /dev/null @@ -1,238 +0,0 @@ -pub mod command; -pub mod material; -pub mod mesh_builder; -mod primitive; - -use bevy::{camera::visibility::RenderLayers, ecs::system::SystemParam, prelude::*}; -use command::{CommandBuffer, DrawCommand}; -use material::MaterialKey; -use primitive::{TessellationMode, empty_mesh}; - -use crate::{Flush, render::primitive::rect}; - -#[derive(Component)] -pub struct TransientMesh; - -#[derive(SystemParam)] -pub struct RenderContext<'w, 's> { - commands: Commands<'w, 's>, - meshes: ResMut<'w, Assets>, - materials: ResMut<'w, Assets>, - batch: Local<'s, BatchState>, - state: Local<'s, RenderState>, -} - -#[derive(Default)] -struct BatchState { - current_mesh: Option, - material_key: Option, - draw_index: u32, - render_layers: RenderLayers, - surface_entity: Option, -} - -#[derive(Debug)] -pub struct RenderState { - // drawing state - pub fill_color: Option, - pub stroke_color: Option, - pub stroke_weight: f32, -} - -impl Default for RenderState { - fn default() -> Self { - Self { - fill_color: Some(Color::WHITE), - stroke_color: Some(Color::BLACK), - stroke_weight: 1.0, - } - } -} - -impl RenderState { - pub fn new() -> Self { - Self::default() - } - - pub fn has_fill(&self) -> bool { - self.fill_color.is_some() - } - - pub fn has_stroke(&self) -> bool { - self.stroke_color.is_some() - } - - pub fn fill_is_transparent(&self) -> bool { - self.fill_color.map(|c| c.alpha() < 1.0).unwrap_or(false) - } - - pub fn stroke_is_transparent(&self) -> bool { - self.stroke_color.map(|c| c.alpha() < 1.0).unwrap_or(false) - } -} - -pub fn flush_draw_commands( - mut ctx: RenderContext, - mut query: Query<(Entity, &mut CommandBuffer, &RenderLayers), With>, -) { - for (surface_entity, mut cmd_buffer, render_layers) in query.iter_mut() { - let draw_commands = std::mem::take(&mut cmd_buffer.commands); - ctx.batch.render_layers = render_layers.clone(); - ctx.batch.surface_entity = Some(surface_entity); - ctx.batch.draw_index = 0; // Reset draw index for each flush - - for cmd in draw_commands { - match cmd { - DrawCommand::Fill(color) => { - ctx.state.fill_color = Some(color); - } - DrawCommand::NoFill => { - ctx.state.fill_color = None; - } - DrawCommand::StrokeColor(color) => { - ctx.state.stroke_color = Some(color); - } - DrawCommand::NoStroke => { - ctx.state.stroke_color = None; - } - DrawCommand::StrokeWeight(weight) => { - ctx.state.stroke_weight = weight; - } - DrawCommand::Rect { x, y, w, h, radii } => { - add_fill(&mut ctx, |mesh, color| { - rect(mesh, x, y, w, h, radii, color, TessellationMode::Fill) - }); - - add_stroke(&mut ctx, |mesh, color, weight| { - rect( - mesh, - x, - y, - w, - h, - radii, - color, - TessellationMode::Stroke(weight), - ) - }); - } - } - } - - flush_batch(&mut ctx); - } -} - -pub fn activate_cameras( - mut cameras: Query<&mut Camera>, - mut surfaces: Query<&Children, With>, -) { - for mut camera in cameras.iter_mut() { - camera.is_active = false; - } - - for children in surfaces.iter_mut() { - for child in children.iter() { - if let Ok(mut camera) = cameras.get_mut(child) { - camera.is_active = true; - } - } - } -} - -pub fn clear_transient_meshes( - mut commands: Commands, - surfaces: Query<&Children, With>, - transient_meshes: Query<(), With>, -) { - // for all flushing surfaces, despawn all transient meshes that rendered in a previous frame - for children in surfaces.iter() { - for child in children.iter() { - if transient_meshes.contains(child) { - commands.entity(child).despawn(); - } - } - } -} - -fn spawn_mesh(ctx: &mut RenderContext, mesh: Mesh, z_offset: Option) { - let Some(material_key) = &ctx.batch.material_key else { - return; - }; - let Some(surface_entity) = ctx.batch.surface_entity else { - return; - }; - - let mesh_handle = ctx.meshes.add(mesh); - let material_handle = ctx.materials.add(material_key.to_material()); - - let components = ( - Mesh3d(mesh_handle), - MeshMaterial3d(material_handle), - TransientMesh, - ctx.batch.render_layers.clone(), - ); - - let mesh_id = if let Some(z) = z_offset { - ctx.commands - .spawn((components, Transform::from_xyz(0.0, 0.0, z))) - .id() - } else { - ctx.commands.spawn(components).id() - }; - - ctx.commands.entity(surface_entity).add_child(mesh_id); -} - -fn add_fill(ctx: &mut RenderContext, tessellate: impl FnOnce(&mut Mesh, Color)) { - let Some(color) = ctx.state.fill_color else { - return; - }; - let material_key = MaterialKey { - transparent: ctx.state.fill_is_transparent(), - }; - - // when the material changes, flush the current batch - if ctx.batch.material_key.as_ref() != Some(&material_key) { - flush_batch(ctx); - ctx.batch.material_key = Some(material_key); - ctx.batch.current_mesh = Some(empty_mesh()); - } - - // accumulate geometry into the current mega mesh - if let Some(ref mut mesh) = ctx.batch.current_mesh { - tessellate(mesh, color); - } -} - -fn add_stroke(ctx: &mut RenderContext, tessellate: impl FnOnce(&mut Mesh, Color, f32)) { - let Some(color) = ctx.state.stroke_color else { - return; - }; - let stroke_weight = ctx.state.stroke_weight; - let material_key = MaterialKey { - transparent: ctx.state.stroke_is_transparent(), - }; - - // when the material changes, flush the current batch - if ctx.batch.material_key.as_ref() != Some(&material_key) { - flush_batch(ctx); - ctx.batch.material_key = Some(material_key); - ctx.batch.current_mesh = Some(empty_mesh()); - } - - // accumulate geometry into the current mega mesh - if let Some(ref mut mesh) = ctx.batch.current_mesh { - tessellate(mesh, color, stroke_weight); - } -} - -fn flush_batch(ctx: &mut RenderContext) { - if let Some(mesh) = ctx.batch.current_mesh.take() { - // we defensively apply a small z-offset based on draw_index to preserve painter's algorithm - let z_offset = ctx.batch.draw_index as f32 * -0.001; - spawn_mesh(ctx, mesh, Some(z_offset)); - ctx.batch.draw_index += 1; - } - ctx.batch.material_key = None; -} diff --git a/libProcessing/renderer/src/render/primitive/mod.rs b/libProcessing/renderer/src/render/primitive/mod.rs deleted file mode 100644 index 3d47dcd94..000000000 --- a/libProcessing/renderer/src/render/primitive/mod.rs +++ /dev/null @@ -1,58 +0,0 @@ -mod rect; - -use bevy::{ - asset::RenderAssetUsages, - mesh::{Indices, PrimitiveTopology}, - prelude::*, -}; -use lyon::{ - path::Path, - tessellation::{ - FillOptions, FillTessellator, LineCap, LineJoin, StrokeOptions, StrokeTessellator, - }, -}; -pub use rect::rect; - -use super::mesh_builder::MeshBuilder; - -pub enum TessellationMode { - Fill, - Stroke(f32), -} - -pub fn tessellate_path(mesh: &mut Mesh, path: &Path, color: Color, mode: TessellationMode) { - let mut builder = MeshBuilder::new(mesh, color); - match mode { - TessellationMode::Fill => { - let mut tessellator = FillTessellator::new(); - tessellator - .tessellate_path(path, &FillOptions::default(), &mut builder) - .expect("Failed to tessellate fill"); - } - TessellationMode::Stroke(weight) => { - let mut tessellator = StrokeTessellator::new(); - let options = StrokeOptions::default() - .with_line_width(weight) - .with_line_cap(LineCap::Round) - .with_line_join(LineJoin::Round); - - tessellator - .tessellate_path(path, &options, &mut builder) - .expect("Failed to tessellate stroke"); - } - } -} - -pub fn empty_mesh() -> Mesh { - let mut mesh = Mesh::new( - PrimitiveTopology::TriangleList, - RenderAssetUsages::default(), - ); - - mesh.insert_attribute(Mesh::ATTRIBUTE_POSITION, Vec::<[f32; 3]>::new()); - mesh.insert_attribute(Mesh::ATTRIBUTE_COLOR, Vec::<[f32; 4]>::new()); - mesh.insert_attribute(Mesh::ATTRIBUTE_NORMAL, Vec::<[f32; 3]>::new()); - mesh.insert_indices(Indices::U32(Vec::new())); - - mesh -} diff --git a/libProcessing/renderer/src/render/primitive/rect.rs b/libProcessing/renderer/src/render/primitive/rect.rs deleted file mode 100644 index b176df0a2..000000000 --- a/libProcessing/renderer/src/render/primitive/rect.rs +++ /dev/null @@ -1,112 +0,0 @@ -use bevy::{ - mesh::{Indices, VertexAttributeValues}, - prelude::*, -}; -use lyon::{geom::Point, path::Path}; - -use crate::render::primitive::{TessellationMode, tessellate_path}; - -fn rect_path(x: f32, y: f32, w: f32, h: f32, radii: [f32; 4]) -> Path { - let mut path_builder = Path::builder(); - let [tl, tr, br, bl] = radii; - - // tl - path_builder.begin(Point::new(x + tl, y)); - - // tl -> tr - if tr > 0.0 { - path_builder.line_to(Point::new(x + w - tr, y)); - path_builder.quadratic_bezier_to(Point::new(x + w, y), Point::new(x + w, y + tr)); - } else { - path_builder.line_to(Point::new(x + w, y)); - } - - // tr -> br - if br > 0.0 { - path_builder.line_to(Point::new(x + w, y + h - br)); - path_builder.quadratic_bezier_to(Point::new(x + w, y + h), Point::new(x + w - br, y + h)); - } else { - path_builder.line_to(Point::new(x + w, y + h)); - } - - // br -> bl - if bl > 0.0 { - path_builder.line_to(Point::new(x + bl, y + h)); - path_builder.quadratic_bezier_to(Point::new(x, y + h), Point::new(x, y + h - bl)); - } else { - path_builder.line_to(Point::new(x, y + h)); - } - - // bl -> tl - if tl > 0.0 { - path_builder.line_to(Point::new(x, y + tl)); - path_builder.quadratic_bezier_to(Point::new(x, y), Point::new(x + tl, y)); - } - - path_builder.end(true); - path_builder.build() -} - -pub fn rect( - mesh: &mut Mesh, - x: f32, - y: f32, - w: f32, - h: f32, - radii: [f32; 4], // [tl, tr, br, bl] - color: Color, - mode: TessellationMode, -) { - if radii == [0.0; 4] && matches!(mode, TessellationMode::Fill) { - simple_rect(mesh, x, y, w, h, color); - } else { - let path = rect_path(x, y, w, h, radii); - tessellate_path(mesh, &path, color, mode); - } -} - -fn simple_rect(mesh: &mut Mesh, x: f32, y: f32, w: f32, h: f32, color: Color) { - let base_idx = if let Some(VertexAttributeValues::Float32x3(positions)) = - mesh.attribute(Mesh::ATTRIBUTE_POSITION) - { - positions.len() as u32 - } else { - 0 - }; - - if let Some(VertexAttributeValues::Float32x3(positions)) = - mesh.attribute_mut(Mesh::ATTRIBUTE_POSITION) - { - positions.push([x, y, 0.0]); - positions.push([x + w, y, 0.0]); - positions.push([x + w, y + h, 0.0]); - positions.push([x, y + h, 0.0]); - } - - if let Some(VertexAttributeValues::Float32x4(colors)) = - mesh.attribute_mut(Mesh::ATTRIBUTE_COLOR) - { - let color_array = color.to_srgba().to_f32_array(); - for _ in 0..4 { - colors.push(color_array); - } - } - - if let Some(VertexAttributeValues::Float32x3(normals)) = - mesh.attribute_mut(Mesh::ATTRIBUTE_NORMAL) - { - for _ in 0..4 { - normals.push([0.0, 0.0, 1.0]); - } - } - - if let Some(Indices::U32(indices)) = mesh.indices_mut() { - indices.push(base_idx + 0); - indices.push(base_idx + 1); - indices.push(base_idx + 2); - - indices.push(base_idx + 0); - indices.push(base_idx + 2); - indices.push(base_idx + 3); - } -} diff --git a/libprocessing b/libprocessing new file mode 160000 index 000000000..43b7fb186 --- /dev/null +++ b/libprocessing @@ -0,0 +1 @@ +Subproject commit 43b7fb186f9dcdf969e6b7463d48cfef1f894306 From 6eddaf4f6e5716f17ad69b5ee5d50abe527b7801 Mon Sep 17 00:00:00 2001 From: "Moon D." Date: Fri, 21 Nov 2025 16:20:57 -0500 Subject: [PATCH 16/26] --recursive when cloning repo --- BUILD.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BUILD.md b/BUILD.md index e44112537..9d3a08212 100644 --- a/BUILD.md +++ b/BUILD.md @@ -42,7 +42,7 @@ If you don't have them installed, you will need to install [Git](https://git-scm 1. **Clone the repository:** ```bash - git clone https://github.com/processing/processing4.git + git clone --recursive https://github.com/processing/processing4.git cd processing4 ``` From dc359d10d1293f4f2993c94f18b02fdecf42acd0 Mon Sep 17 00:00:00 2001 From: Stef Tervelde Date: Mon, 24 Nov 2025 15:12:42 +0100 Subject: [PATCH 17/26] Enable submodule checkout in Gradle workflow Added support for submodules in the checkout step. --- .github/workflows/pull_request-gradle.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/pull_request-gradle.yml b/.github/workflows/pull_request-gradle.yml index e543205de..836548f9f 100644 --- a/.github/workflows/pull_request-gradle.yml +++ b/.github/workflows/pull_request-gradle.yml @@ -13,6 +13,8 @@ jobs: steps: - name: Checkout Repository uses: actions/checkout@v4 + with: + submodules: true - name: Install Java uses: actions/setup-java@v4 with: @@ -65,6 +67,8 @@ jobs: - name: Checkout Repository uses: actions/checkout@v4 + with: + submodules: true - name: Install Java uses: actions/setup-java@v4 with: @@ -87,4 +91,4 @@ jobs: with: name: processing-${{ matrix.os_prefix }}-${{ matrix.arch }}-pr_${{ github.event.pull_request.number }} retention-days: 5 - path: app/build/compose/binaries/main/${{ matrix.binary }} \ No newline at end of file + path: app/build/compose/binaries/main/${{ matrix.binary }} From 39cca3da54cec9cb8e975be37f1a6153cc43171b Mon Sep 17 00:00:00 2001 From: Stef Tervelde Date: Mon, 24 Nov 2025 15:15:29 +0100 Subject: [PATCH 18/26] Enable submodules in checkout steps Added submodule support to the checkout steps. --- .github/workflows/build-gradle.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-gradle.yml b/.github/workflows/build-gradle.yml index 252e1c805..f88812f0b 100644 --- a/.github/workflows/build-gradle.yml +++ b/.github/workflows/build-gradle.yml @@ -12,6 +12,8 @@ jobs: steps: - name: Checkout Repository uses: actions/checkout@v4 + with: + submodules: true - name: Install Java uses: actions/setup-java@v4 with: @@ -64,6 +66,8 @@ jobs: - name: Checkout Repository uses: actions/checkout@v4 + with: + submodules: true - name: Install Java uses: actions/setup-java@v4 with: @@ -86,4 +90,4 @@ jobs: with: name: processing-${{ matrix.os_prefix }}-${{ matrix.arch }}-br_${{ github.ref_name }} retention-days: 1 - path: app/build/compose/binaries/main/${{ matrix.binary }} \ No newline at end of file + path: app/build/compose/binaries/main/${{ matrix.binary }} From 8400db50aa0ff9d6e1eaefb74197b6c48b7b645b Mon Sep 17 00:00:00 2001 From: "Moon D." Date: Mon, 24 Nov 2025 11:07:00 -0500 Subject: [PATCH 19/26] Wayland support with new WebGPU renderer --- .../processing/webgpu/PGraphicsWebGPU.java | 4 +-- core/src/processing/webgpu/PSurfaceGLFW.java | 31 ++++++++++++++----- core/src/processing/webgpu/PWebGPU.java | 5 +-- 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/core/src/processing/webgpu/PGraphicsWebGPU.java b/core/src/processing/webgpu/PGraphicsWebGPU.java index 3e27967c4..cc6fcde98 100644 --- a/core/src/processing/webgpu/PGraphicsWebGPU.java +++ b/core/src/processing/webgpu/PGraphicsWebGPU.java @@ -11,8 +11,8 @@ public PSurface createSurface() { return surface = new PSurfaceGLFW(this); } - protected void initWebGPUSurface(long windowHandle, int width, int height, float scaleFactor) { - surfaceId = PWebGPU.createSurface(windowHandle, width, height, scaleFactor); + protected void initWebGPUSurface(long windowHandle, long displayHandle, int width, int height, float scaleFactor) { + surfaceId = PWebGPU.createSurface(windowHandle, displayHandle, width, height, scaleFactor); if (surfaceId == 0) { System.err.println("Failed to create WebGPU surface"); } diff --git a/core/src/processing/webgpu/PSurfaceGLFW.java b/core/src/processing/webgpu/PSurfaceGLFW.java index d9591d10e..f80131e19 100644 --- a/core/src/processing/webgpu/PSurfaceGLFW.java +++ b/core/src/processing/webgpu/PSurfaceGLFW.java @@ -1,11 +1,6 @@ package processing.webgpu; -import org.lwjgl.glfw.GLFW; -import org.lwjgl.glfw.GLFWErrorCallback; -import org.lwjgl.glfw.GLFWFramebufferSizeCallback; -import org.lwjgl.glfw.GLFWNativeCocoa; -import org.lwjgl.glfw.GLFWNativeWin32; -import org.lwjgl.glfw.GLFWWindowPosCallback; +import org.lwjgl.glfw.*; import org.lwjgl.system.MemoryUtil; import org.lwjgl.system.Platform; @@ -30,6 +25,7 @@ public class PSurfaceGLFW implements PSurface { protected PGraphics graphics; protected long window; + protected long display; protected boolean running = false; protected boolean paused; @@ -78,6 +74,8 @@ public void initFrame(PApplet sketch) { throw new RuntimeException("Failed to create GLFW window"); } + display = GLFW.glfwGetPrimaryMonitor(); + windowCount.incrementAndGet(); // event callbacks @@ -87,11 +85,12 @@ public void initFrame(PApplet sketch) { PWebGPU.init(); long windowHandle = getWindowHandle(); + long displayHandle = getDisplayHandle(); int width = sketch.sketchWidth(); int height = sketch.sketchHeight(); float scaleFactor = sketch.sketchPixelDensity(); - webgpu.initWebGPUSurface(windowHandle, width, height, scaleFactor); + webgpu.initWebGPUSurface(windowHandle, displayHandle, width, height, scaleFactor); } } @@ -123,6 +122,24 @@ public long getWindowHandle() { return GLFWNativeCocoa.glfwGetCocoaWindow(window); } else if (Platform.get() == Platform.WINDOWS) { return GLFWNativeWin32.glfwGetWin32Window(window); + } else if (Platform.get() == Platform.LINUX) { + // TODO: need to check if x11 or wayland + return GLFWNativeWayland.glfwGetWaylandWindow(window); + } else { + throw new UnsupportedOperationException("Window handle retrieval not implemented for this platform"); + } + } + + public long getDisplayHandle() { + if (Platform.get() == Platform.MACOSX) { + // TODO: Currently unsupported + return 0; + } else if (Platform.get() == Platform.WINDOWS) { + // TODO: Currently unsupported + return 0; + } else if (Platform.get() == Platform.LINUX) { + // TODO: need to check if x11 or wayland + return GLFWNativeWayland.glfwGetWaylandDisplay(); } else { throw new UnsupportedOperationException("Window handle retrieval not implemented for this platform"); } diff --git a/core/src/processing/webgpu/PWebGPU.java b/core/src/processing/webgpu/PWebGPU.java index e0a1a7630..d53dbd9d1 100644 --- a/core/src/processing/webgpu/PWebGPU.java +++ b/core/src/processing/webgpu/PWebGPU.java @@ -38,13 +38,14 @@ public static void init() { * Creates a WebGPU surface from a native window handle. * * @param windowHandle The native window handle + * @param displayHandle The native display handle * @param width Window width in physical pixels * @param height Window height in phsyical pixels * @param scaleFactor os provided scale factor * @return Window ID to use for subsequent operations */ - public static long createSurface(long windowHandle, int width, int height, float scaleFactor) { - long surfaceId = processing_create_surface(windowHandle, width, height, scaleFactor); + public static long createSurface(long windowHandle, long displayHandle, int width, int height, float scaleFactor) { + long surfaceId = processing_create_surface(windowHandle, displayHandle, width, height, scaleFactor); checkError(); return surfaceId; } From eee55b530eccb06159b41859cf4cd35f756e15be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?charlotte=20=F0=9F=8C=B8?= Date: Wed, 26 Nov 2025 10:38:13 -0800 Subject: [PATCH 20/26] Gradle fixes from libprocessing refactor. (#1346) --- core/build.gradle.kts | 42 ++++++++++++++++++++++++++++++++---------- libprocessing | 2 +- 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 7299016a4..54aee7552 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -65,24 +65,44 @@ dependencies { if (enableWebGPU) { val currentPlatform = PlatformUtils.detect() val libprocessingDir = file("${project.rootDir}/libprocessing") + + if (!libprocessingDir.exists()) { + throw GradleException( + "libprocessing submodule directory not found at: ${libprocessingDir.absolutePath}\n" + + "Please initialize the submodule with: git submodule update --init --recursive" + ) + } + val rustTargetDir = file("$libprocessingDir/target") val nativeOutputDir = file("${layout.buildDirectory.get()}/native/${currentPlatform.target}") + val ffiManifestPath = fileTree(libprocessingDir) { + include("**/processing_ffi/Cargo.toml") + }.files.firstOrNull()?.let { it.relativeTo(libprocessingDir).path } + ?: throw GradleException( + "Could not find processing_ffi Cargo.toml in libprocessing.\n" + + "Searched in: ${libprocessingDir.absolutePath}\n" + + "The libprocessing structure may have changed." + ) + val buildRustRelease by tasks.registering(CargoBuildTask::class) { cargoWorkspaceDir.set(libprocessingDir) - manifestPath.set("ffi/Cargo.toml") + manifestPath.set(ffiManifestPath) release.set(true) cargoPath.set(PlatformUtils.getCargoPath()) outputLibrary.set(file("$rustTargetDir/release/${currentPlatform.libName}")) - inputs.files(fileTree("$libprocessingDir/ffi/src")) - inputs.file("$libprocessingDir/ffi/Cargo.toml") - inputs.file("$libprocessingDir/ffi/build.rs") - inputs.file("$libprocessingDir/ffi/cbindgen.toml") - inputs.files(fileTree("$libprocessingDir/renderer/src")) - inputs.file("$libprocessingDir/renderer/Cargo.toml") + inputs.files(fileTree("$libprocessingDir/crates") { + include("**/src/**/*.rs") + include("**/Cargo.toml") + include("**/build.rs") + include("**/cbindgen.toml") + }) inputs.file("$libprocessingDir/Cargo.toml") - outputs.file("$libprocessingDir/ffi/include/processing.h") + inputs.file("$libprocessingDir/Cargo.lock") + + val headerDir = file("$libprocessingDir/${ffiManifestPath}").parentFile.resolve("include") + outputs.file("$headerDir/processing.h") } val copyNativeLibs by tasks.registering(Copy::class) { @@ -110,7 +130,7 @@ if (enableWebGPU) { val cleanRust by tasks.registering(CargoCleanTask::class) { cargoWorkspaceDir.set(libprocessingDir) - manifestPath.set("ffi/Cargo.toml") + manifestPath.set(ffiManifestPath) cargoPath.set(PlatformUtils.getCargoPath()) mustRunAfter(buildRustRelease) @@ -158,7 +178,9 @@ if (enableWebGPU) { dependsOn(downloadJextract, makeJextractExecutable) } - headerFile.set(file("$libprocessingDir/ffi/include/processing.h")) + // Find header file dynamically based on FFI manifest location + val headerDir = file("$libprocessingDir/${ffiManifestPath}").parentFile.resolve("include") + headerFile.set(file("$headerDir/processing.h")) outputDirectory.set(generatedJavaDir) targetPackage.set("processing.ffi") diff --git a/libprocessing b/libprocessing index 43b7fb186..18f514612 160000 --- a/libprocessing +++ b/libprocessing @@ -1 +1 @@ -Subproject commit 43b7fb186f9dcdf969e6b7463d48cfef1f894306 +Subproject commit 18f514612d5f746fafb54488a8bc382771594582 From 408d542a6ca58079cde433c20ea4cb3ac86a8d68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?charlotte=20=F0=9F=8C=B8?= Date: Wed, 28 Jan 2026 09:00:36 -0800 Subject: [PATCH 21/26] Updates from libprocessing. (#1392) --- core/examples/src/main/java/WebGPU.java | 58 --- .../src/main/java/webgpu/AnimatedMesh.java | 63 +++ .../src/main/java/webgpu/BackgroundImage.java | 36 ++ core/examples/src/main/java/webgpu/Box3D.java | 35 ++ .../src/main/java/webgpu/Rectangle.java | 23 + .../src/main/java/webgpu/Transforms.java | 47 ++ .../src/main/java/webgpu/UpdatePixels.java | 74 +++ core/src/processing/core/PApplet.java | 4 +- core/src/processing/core/PGraphics.java | 5 + .../processing/webgpu/PGraphicsWebGPU.java | 325 +++++++++++++- core/src/processing/webgpu/PImageWebGPU.java | 28 ++ core/src/processing/webgpu/PShapeWebGPU.java | 273 +++++++++++ core/src/processing/webgpu/PWebGPU.java | 423 +++++++++++++++++- libprocessing | 2 +- 14 files changed, 1308 insertions(+), 88 deletions(-) delete mode 100644 core/examples/src/main/java/WebGPU.java create mode 100644 core/examples/src/main/java/webgpu/AnimatedMesh.java create mode 100644 core/examples/src/main/java/webgpu/BackgroundImage.java create mode 100644 core/examples/src/main/java/webgpu/Box3D.java create mode 100644 core/examples/src/main/java/webgpu/Rectangle.java create mode 100644 core/examples/src/main/java/webgpu/Transforms.java create mode 100644 core/examples/src/main/java/webgpu/UpdatePixels.java create mode 100644 core/src/processing/webgpu/PImageWebGPU.java create mode 100644 core/src/processing/webgpu/PShapeWebGPU.java diff --git a/core/examples/src/main/java/WebGPU.java b/core/examples/src/main/java/WebGPU.java deleted file mode 100644 index 71ce807ff..000000000 --- a/core/examples/src/main/java/WebGPU.java +++ /dev/null @@ -1,58 +0,0 @@ -import processing.core.PApplet; - -public class WebGPU extends PApplet { - public void settings() { - size(600, 400, WEBGPU); - } - - public void draw() { - background(200); - - noStroke(); - fill(255, 0, 0); - rect(50, 50, 80, 80); - - fill(0, 255, 0); - rect(150, 50, 80, 80); - - fill(0, 0, 255); - rect(250, 50, 80, 80); - - fill(255, 0, 0, 128); - rect(50, 150, 80, 80); - - fill(0, 255, 0, 128); - rect(150, 150, 80, 80); - - fill(0, 0, 255, 128); - rect(250, 150, 80, 80); - - stroke(0); - strokeWeight(4); - fill(255, 200, 0); - rect(50, 250, 80, 80); - - fill(200, 0, 255); - rect(150, 250, 80, 80); - - noFill(); - stroke(255, 0, 255); - strokeWeight(6); - rect(250, 250, 80, 80); - - noStroke(); - fill(255, 0, 0, 100); - rect(400, 100, 100, 100); - - fill(0, 255, 0, 100); - rect(440, 140, 100, 100); - - fill(0, 0, 255, 100); - rect(420, 180, 100, 100); - } - - public static void main(String[] args) { - PApplet.disableAWT = true; - PApplet.main(WebGPU.class.getName()); - } -} diff --git a/core/examples/src/main/java/webgpu/AnimatedMesh.java b/core/examples/src/main/java/webgpu/AnimatedMesh.java new file mode 100644 index 000000000..c1dec3f04 --- /dev/null +++ b/core/examples/src/main/java/webgpu/AnimatedMesh.java @@ -0,0 +1,63 @@ +package webgpu; + +import processing.core.PApplet; + +public class AnimatedMesh extends PApplet { + + int gridSize = 20; + float spacing = 10; + float time = 0; + + public void settings() { + size(600, 600, WEBGPU); + } + + public void setup() { + perspective(PI/3, (float)width/height, 0.1f, 1000); + camera(150, 150, 150, 0, 0, 0, 0, 1, 0); + } + + public void draw() { + background(13, 13, 26); + + float offset = (gridSize * spacing) / 2.0f; + + beginShape(TRIANGLES); + for (int z = 0; z < gridSize - 1; z++) { + for (int x = 0; x < gridSize - 1; x++) { + float px0 = x * spacing - offset; + float pz0 = z * spacing - offset; + float px1 = (x + 1) * spacing - offset; + float pz1 = (z + 1) * spacing - offset; + + float y00 = wave(px0, pz0); + float y10 = wave(px1, pz0); + float y01 = wave(px0, pz1); + float y11 = wave(px1, pz1); + + fill(x * 255.0f / gridSize, 128, z * 255.0f / gridSize); + normal(0, 1, 0); + + vertex(px0, y00, pz0); + vertex(px0, y01, pz1); + vertex(px1, y10, pz0); + + vertex(px1, y10, pz0); + vertex(px0, y01, pz1); + vertex(px1, y11, pz1); + } + } + endShape(); + + time += 0.05f; + } + + float wave(float x, float z) { + return sin(x * 0.1f + time) * cos(z * 0.1f + time) * 20; + } + + public static void main(String[] args) { + PApplet.disableAWT = true; + PApplet.main(AnimatedMesh.class.getName()); + } +} diff --git a/core/examples/src/main/java/webgpu/BackgroundImage.java b/core/examples/src/main/java/webgpu/BackgroundImage.java new file mode 100644 index 000000000..d5386ae9c --- /dev/null +++ b/core/examples/src/main/java/webgpu/BackgroundImage.java @@ -0,0 +1,36 @@ +package webgpu; + +import processing.core.PApplet; +import processing.core.PImage; + +public class BackgroundImage extends PApplet { + + PImage img; + + public void settings() { + size(400, 400, WEBGPU); + } + + public void setup() { + img = createImage(400, 400, RGB); + img.loadPixels(); + for (int y = 0; y < img.height; y++) { + for (int x = 0; x < img.width; x++) { + int r = (int) (x * 255.0 / img.width); + int g = (int) (y * 255.0 / img.height); + int b = 128; + img.pixels[y * img.width + x] = color(r, g, b); + } + } + img.updatePixels(); + } + + public void draw() { + background(img); + } + + public static void main(String[] args) { + PApplet.disableAWT = true; + PApplet.main(BackgroundImage.class.getName()); + } +} diff --git a/core/examples/src/main/java/webgpu/Box3D.java b/core/examples/src/main/java/webgpu/Box3D.java new file mode 100644 index 000000000..2f24b9a93 --- /dev/null +++ b/core/examples/src/main/java/webgpu/Box3D.java @@ -0,0 +1,35 @@ +package webgpu; + +import processing.core.PApplet; + +public class Box3D extends PApplet { + + float angle = 0; + + public void settings() { + size(400, 400, WEBGPU); + } + + public void setup() { + perspective(PI/3, (float)width/height, 0.1f, 1000); + camera(200, 200, 300, 0, 0, 0, 0, 1, 0); + } + + public void draw() { + background(26, 26, 38); + + pushMatrix(); + rotateY(angle); + rotateX(angle * 0.7f); + fill(200, 100, 100); + box(100); + popMatrix(); + + angle += 0.02f; + } + + public static void main(String[] args) { + PApplet.disableAWT = true; + PApplet.main(Box3D.class.getName()); + } +} diff --git a/core/examples/src/main/java/webgpu/Rectangle.java b/core/examples/src/main/java/webgpu/Rectangle.java new file mode 100644 index 000000000..5a9b2c61d --- /dev/null +++ b/core/examples/src/main/java/webgpu/Rectangle.java @@ -0,0 +1,23 @@ +package webgpu; + +import processing.core.PApplet; + +public class Rectangle extends PApplet { + + public void settings() { + size(400, 400, WEBGPU); + } + + public void draw() { + background(51); + + fill(255); + noStroke(); + rect(10, 10, 100, 100); + } + + public static void main(String[] args) { + PApplet.disableAWT = true; + PApplet.main(Rectangle.class.getName()); + } +} diff --git a/core/examples/src/main/java/webgpu/Transforms.java b/core/examples/src/main/java/webgpu/Transforms.java new file mode 100644 index 000000000..781423cd6 --- /dev/null +++ b/core/examples/src/main/java/webgpu/Transforms.java @@ -0,0 +1,47 @@ +package webgpu; + +import processing.core.PApplet; + +public class Transforms extends PApplet { + + float t = 0; + + public void settings() { + size(400, 400, WEBGPU); + } + + public void draw() { + background(26); + + noStroke(); + + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + pushMatrix(); + + translate(50 + j * 100, 50 + i * 100); + + float angle = t + (i + j) * PI / 8.0f; + rotate(angle); + + float s = 0.8f + sin(t * 2.0f + (i * j)) * 0.2f; + scale(s, s); + + float r = j / 3.0f; + float g = i / 3.0f; + fill(r * 255, g * 255, 204); + + rect(-20, -20, 40, 40); + + popMatrix(); + } + } + + t += 0.02f; + } + + public static void main(String[] args) { + PApplet.disableAWT = true; + PApplet.main(Transforms.class.getName()); + } +} diff --git a/core/examples/src/main/java/webgpu/UpdatePixels.java b/core/examples/src/main/java/webgpu/UpdatePixels.java new file mode 100644 index 000000000..9ef2cf5ab --- /dev/null +++ b/core/examples/src/main/java/webgpu/UpdatePixels.java @@ -0,0 +1,74 @@ +package webgpu; + +import processing.core.PApplet; + +public class UpdatePixels extends PApplet { + + static final int RECT_W = 10; + static final int RECT_H = 10; + + boolean firstFrame = true; + + public void settings() { + size(100, 100, WEBGPU); + } + + public void draw() { + background(0); // Black background + + loadPixels(); + + for (int y = 20; y < 20 + RECT_H; y++) { + for (int x = 20; x < 20 + RECT_W; x++) { + pixels[y * width + x] = color(255, 0, 0); + } + } + + for (int y = 60; y < 60 + RECT_H; y++) { + for (int x = 60; x < 60 + RECT_W; x++) { + pixels[y * width + x] = color(0, 0, 255); + } + } + + updatePixels(); + + if (firstFrame) { + firstFrame = false; + + println("Total pixels: " + pixels.length); + + for (int y = 0; y < height; y++) { + StringBuilder row = new StringBuilder(); + for (int x = 0; x < width; x++) { + int idx = y * width + x; + int pixel = pixels[idx]; + float r = red(pixel); + float b = blue(pixel); + float a = alpha(pixel); + + if (r > 127) { + row.append("R"); + } else if (b > 127) { + row.append("B"); + } else if (a > 127) { + row.append("."); + } else { + row.append(" "); + } + } + println(row.toString()); + } + + println("\nSample pixels:"); + println("(25, 25): " + hex(pixels[25 * width + 25])); + println("(65, 65): " + hex(pixels[65 * width + 65])); + println("(0, 0): " + hex(pixels[0])); + println("(50, 50): " + hex(pixels[50 * width + 50])); + } + } + + public static void main(String[] args) { + PApplet.disableAWT = true; + PApplet.main(UpdatePixels.class.getName()); + } +} diff --git a/core/src/processing/core/PApplet.java b/core/src/processing/core/PApplet.java index 9f832d29d..1c94b0f76 100644 --- a/core/src/processing/core/PApplet.java +++ b/core/src/processing/core/PApplet.java @@ -2008,8 +2008,8 @@ protected PGraphics createPrimaryGraphics() { * @see PGraphics */ public PImage createImage(int w, int h, int format) { - PImage image = new PImage(w, h, format); - image.parent = this; // make save() work + PImage image = (g != null) ? g.createImage(w, h, format) : new PImage(w, h, format); + image.parent = this; return image; } diff --git a/core/src/processing/core/PGraphics.java b/core/src/processing/core/PGraphics.java index 0b9f0d2ed..d8e962afc 100644 --- a/core/src/processing/core/PGraphics.java +++ b/core/src/processing/core/PGraphics.java @@ -3830,6 +3830,11 @@ private void smoothWarning(String method) { // IMAGE + public PImage createImage(int w, int h, int format) { + return new PImage(w, h, format); + } + + /** * * Modifies the location from which images are drawn by changing the way in diff --git a/core/src/processing/webgpu/PGraphicsWebGPU.java b/core/src/processing/webgpu/PGraphicsWebGPU.java index cc6fcde98..1afde5b3c 100644 --- a/core/src/processing/webgpu/PGraphicsWebGPU.java +++ b/core/src/processing/webgpu/PGraphicsWebGPU.java @@ -1,10 +1,24 @@ package processing.webgpu; import processing.core.PGraphics; +import processing.core.PImage; +import processing.core.PShape; import processing.core.PSurface; +import java.util.ArrayList; +import java.util.List; + public class PGraphicsWebGPU extends PGraphics { private long surfaceId = 0; + private long graphicsId = 0; + + private long currentGeometry = 0; + private int shapeKind = 0; + private float normalX = 0, normalY = 0, normalZ = 1; + + // immediate mode geometries pending destruction + private final List pendingDestroy = new ArrayList<>(); + @Override public PSurface createSurface() { @@ -15,6 +29,11 @@ protected void initWebGPUSurface(long windowHandle, long displayHandle, int widt surfaceId = PWebGPU.createSurface(windowHandle, displayHandle, width, height, scaleFactor); if (surfaceId == 0) { System.err.println("Failed to create WebGPU surface"); + return; + } + graphicsId = PWebGPU.graphicsCreate(surfaceId, width, height); + if (graphicsId == 0) { + System.err.println("Failed to create WebGPU graphics context"); } } @@ -29,21 +48,34 @@ public void setSize(int w, int h) { @Override public void beginDraw() { super.beginDraw(); + if (graphicsId == 0) { + return; + } + PWebGPU.beginDraw(graphicsId); checkSettings(); - System.out.println("Beginning draw on surfaceId: " + surfaceId); - PWebGPU.beginDraw(surfaceId); } @Override public void flush() { super.flush(); - PWebGPU.flush(surfaceId); + if (graphicsId == 0) { + return; + } + PWebGPU.flush(graphicsId); + + for (long geometryId : pendingDestroy) { + PWebGPU.geometryDestroy(geometryId); + } + pendingDestroy.clear(); } @Override public void endDraw() { super.endDraw(); - PWebGPU.endDraw(surfaceId); + if (graphicsId == 0) { + return; + } + PWebGPU.endDraw(graphicsId); } @Override @@ -58,63 +90,81 @@ public void dispose() { @Override protected void backgroundImpl() { - if (surfaceId == 0) { + if (graphicsId == 0) { return; } - PWebGPU.backgroundColor(surfaceId, backgroundR, backgroundG, backgroundB, backgroundA); + PWebGPU.backgroundColor(graphicsId, backgroundR, backgroundG, backgroundB, backgroundA); + } + + @Override + protected void backgroundImpl(PImage image) { + if (graphicsId == 0) { + return; + } + if (!(image instanceof PImageWebGPU)) { + throw new RuntimeException("WebGPU renderer requires PImageWebGPU. Use createImage()."); + } + PImageWebGPU img = (PImageWebGPU) image; + if (img.getId() == 0) { + img.loadPixels(); + byte[] rgba = pixelsToRGBA(img.pixels); + long imageId = PWebGPU.imageCreate(img.pixelWidth, img.pixelHeight, rgba); + img.setId(imageId); + } + PWebGPU.backgroundImage(graphicsId, img.getId()); } @Override protected void fillFromCalc() { super.fillFromCalc(); - if (surfaceId == 0) { + if (graphicsId == 0) { return; } if (fill) { - PWebGPU.setFill(surfaceId, fillR, fillG, fillB, fillA); + PWebGPU.setFill(graphicsId, fillR, fillG, fillB, fillA); } else { - PWebGPU.noFill(surfaceId); + PWebGPU.noFill(graphicsId); } } @Override protected void strokeFromCalc() { super.strokeFromCalc(); - if (surfaceId == 0) { + if (graphicsId == 0) { return; } if (stroke) { - PWebGPU.setStrokeColor(surfaceId, strokeR, strokeG, strokeB, strokeA); + PWebGPU.setStrokeColor(graphicsId, strokeR, strokeG, strokeB, strokeA); } else { - PWebGPU.noStroke(surfaceId); + PWebGPU.noStroke(graphicsId); } } @Override public void strokeWeight(float weight) { super.strokeWeight(weight); - if (surfaceId == 0) { + if (graphicsId == 0) { return; } - PWebGPU.setStrokeWeight(surfaceId, weight); + PWebGPU.setStrokeWeight(graphicsId, weight); } @Override public void noFill() { super.noFill(); - if (surfaceId == 0) { + if (graphicsId == 0) { return; } - PWebGPU.noFill(surfaceId); + PWebGPU.noFill(graphicsId); } @Override public void noStroke() { super.noStroke(); - if (surfaceId == 0) { + if (graphicsId == 0) { return; } - PWebGPU.noStroke(surfaceId); + PWebGPU.noStroke(graphicsId); } @Override @@ -125,10 +175,243 @@ protected void rectImpl(float x1, float y1, float x2, float y2) { @Override protected void rectImpl(float x1, float y1, float x2, float y2, float tl, float tr, float br, float bl) { - if (surfaceId == 0) { + if (graphicsId == 0) { + return; + } + PWebGPU.rect(graphicsId, x1, y1, x2 - x1, y2 - y1, tl, tr, br, bl); + } + + @Override + public void box(float w, float h, float d) { + if (graphicsId == 0) { + return; + } + long boxGeometry = PWebGPU.geometryBox(w, h, d); + PWebGPU.model(graphicsId, boxGeometry); + pendingDestroy.add(boxGeometry); + } + + @Override + public void pushMatrix() { + if (graphicsId == 0) { + return; + } + PWebGPU.pushMatrix(graphicsId); + } + + @Override + public void popMatrix() { + if (graphicsId == 0) { return; } - // rectImpl receives corner coordinates, so let's convert to x,y,w,h - PWebGPU.rect(surfaceId, x1, y1, x2 - x1, y2 - y1, tl, tr, br, bl); + PWebGPU.popMatrix(graphicsId); + } + + @Override + public void resetMatrix() { + if (graphicsId == 0) { + return; + } + PWebGPU.resetMatrix(graphicsId); + } + + @Override + public void translate(float x, float y) { + if (graphicsId == 0) { + return; + } + PWebGPU.translate(graphicsId, x, y); + } + + @Override + public void rotate(float angle) { + if (graphicsId == 0) { + return; + } + PWebGPU.rotate(graphicsId, angle); + } + + @Override + public void rotateX(float angle) { + if (graphicsId == 0) { + return; + } + PWebGPU.rotateX(graphicsId, angle); + } + + @Override + public void rotateY(float angle) { + if (graphicsId == 0) { + return; + } + PWebGPU.rotateY(graphicsId, angle); + } + + @Override + public void scale(float x, float y) { + if (graphicsId == 0) { + return; + } + PWebGPU.scale(graphicsId, x, y); + } + + @Override + public void shearX(float angle) { + if (graphicsId == 0) { + return; + } + PWebGPU.shearX(graphicsId, angle); + } + + @Override + public void shearY(float angle) { + if (graphicsId == 0) { + return; + } + PWebGPU.shearY(graphicsId, angle); + } + + public PImageWebGPU createImage(int width, int height, int format) { + return new PImageWebGPU(width, height, format); + } + + private byte[] pixelsToRGBA(int[] pixels) { + byte[] rgba = new byte[pixels.length * 4]; + for (int i = 0; i < pixels.length; i++) { + int pixel = pixels[i]; + rgba[i * 4] = (byte) ((pixel >> 16) & 0xFF); + rgba[i * 4 + 1] = (byte) ((pixel >> 8) & 0xFF); + rgba[i * 4 + 2] = (byte) (pixel & 0xFF); + rgba[i * 4 + 3] = (byte) ((pixel >> 24) & 0xFF); + } + return rgba; + } + + public void cameraPosition(float x, float y, float z) { + if (graphicsId == 0) { + return; + } + PWebGPU.cameraPosition(graphicsId, x, y, z); + } + + public void cameraLookAt(float x, float y, float z) { + if (graphicsId == 0) { + return; + } + PWebGPU.cameraLookAt(graphicsId, x, y, z); + } + + @Override + public void camera(float eyeX, float eyeY, float eyeZ, + float centerX, float centerY, float centerZ, + float upX, float upY, float upZ) { + if (graphicsId == 0) { + return; + } + PWebGPU.mode3d(graphicsId); + PWebGPU.cameraPosition(graphicsId, eyeX, eyeY, eyeZ); + PWebGPU.cameraLookAt(graphicsId, centerX, centerY, centerZ); + } + + @Override + public void perspective(float fov, float aspect, float near, float far) { + if (graphicsId == 0) { + return; + } + PWebGPU.mode3d(graphicsId); + PWebGPU.perspective(graphicsId, fov, aspect, near, far); + } + + @Override + public void ortho(float left, float right, float bottom, float top, float near, float far) { + if (graphicsId == 0) { + return; + } + PWebGPU.ortho(graphicsId, left, right, bottom, top, near, far); + } + + @Override + public PShape createShape() { + return new PShapeWebGPU(this, PShape.GEOMETRY); + } + + @Override + public PShape createShape(int type) { + return new PShapeWebGPU(this, type); + } + + public void model(long geometryId) { + if (graphicsId == 0) { + return; + } + PWebGPU.model(graphicsId, geometryId); + } + + @Override + public void beginShape(int kind) { + super.beginShape(kind); + if (graphicsId == 0) { + return; + } + shapeKind = kind; + byte topology = shapeKindToTopology(kind); + currentGeometry = PWebGPU.geometryCreate(topology); + } + + private byte shapeKindToTopology(int kind) { + return switch (kind) { + case POINTS -> PWebGPU.TOPOLOGY_POINT_LIST; + case LINES -> PWebGPU.TOPOLOGY_LINE_LIST; + case LINE_STRIP -> PWebGPU.TOPOLOGY_LINE_STRIP; + case TRIANGLES -> PWebGPU.TOPOLOGY_TRIANGLE_LIST; + case TRIANGLE_STRIP -> PWebGPU.TOPOLOGY_TRIANGLE_STRIP; + case TRIANGLE_FAN, QUADS, QUAD_STRIP, POLYGON -> PWebGPU.TOPOLOGY_TRIANGLE_LIST; + default -> PWebGPU.TOPOLOGY_TRIANGLE_LIST; + }; + } + + @Override + public void normal(float nx, float ny, float nz) { + normalX = nx; + normalY = ny; + normalZ = nz; + } + + @Override + public void vertex(float x, float y) { + vertex(x, y, 0); + } + + @Override + public void vertex(float x, float y, float z) { + if (currentGeometry == 0) { + return; + } + PWebGPU.geometryColor(currentGeometry, fillR, fillG, fillB, fillA); + PWebGPU.geometryNormal(currentGeometry, normalX, normalY, normalZ); + PWebGPU.geometryVertex(currentGeometry, x, y, z); + } + + @Override + public void endShape(int mode) { + if (graphicsId == 0 || currentGeometry == 0) { + return; + } + + if (shapeKind == QUADS) { + int vertexCount = PWebGPU.geometryVertexCount(currentGeometry); + for (int i = 0; i < vertexCount; i += 4) { + PWebGPU.geometryIndex(currentGeometry, i); + PWebGPU.geometryIndex(currentGeometry, i + 1); + PWebGPU.geometryIndex(currentGeometry, i + 2); + PWebGPU.geometryIndex(currentGeometry, i); + PWebGPU.geometryIndex(currentGeometry, i + 2); + PWebGPU.geometryIndex(currentGeometry, i + 3); + } + } + + PWebGPU.model(graphicsId, currentGeometry); + pendingDestroy.add(currentGeometry); + currentGeometry = 0; } } diff --git a/core/src/processing/webgpu/PImageWebGPU.java b/core/src/processing/webgpu/PImageWebGPU.java new file mode 100644 index 000000000..d60d6530a --- /dev/null +++ b/core/src/processing/webgpu/PImageWebGPU.java @@ -0,0 +1,28 @@ +package processing.webgpu; + +import processing.core.PImage; + +public class PImageWebGPU extends PImage { + + protected long id = 0; + + public PImageWebGPU() { + super(); + } + + public PImageWebGPU(int width, int height) { + super(width, height); + } + + public PImageWebGPU(int width, int height, int format) { + super(width, height, format); + } + + public long getId() { + return id; + } + + public void setId(long imageId) { + this.id = imageId; + } +} diff --git a/core/src/processing/webgpu/PShapeWebGPU.java b/core/src/processing/webgpu/PShapeWebGPU.java new file mode 100644 index 000000000..3e25a7add --- /dev/null +++ b/core/src/processing/webgpu/PShapeWebGPU.java @@ -0,0 +1,273 @@ +package processing.webgpu; + +import processing.core.PShape; +import processing.core.PVector; + +/** + * WebGPU implementation of PShape. + */ +public class PShapeWebGPU extends PShape { + + /** Reference to the graphics context */ + protected PGraphicsWebGPU pg; + + /** Native geometry ID (0 = not yet created) */ + protected long geometryId = 0; + + /** Native layout ID for custom vertex attributes */ + protected long layoutId = 0; + + /** Current topology for this shape */ + protected byte topology = PWebGPU.TOPOLOGY_TRIANGLE_LIST; + + /** Track if we're currently building the shape */ + protected boolean building = false; + + /** Pending normal for next vertex */ + protected float normalX, normalY, normalZ; + protected boolean hasNormal = false; + + /** Pending color for next vertex */ + protected float colorR, colorG, colorB, colorA; + protected boolean hasColor = false; + + /** Pending UV for next vertex */ + protected float uvU, uvV; + protected boolean hasUV = false; + + /** + * Create a new WebGPU shape. + */ + public PShapeWebGPU(PGraphicsWebGPU pg, int family) { + this.pg = pg; + this.family = family; + } + + /** + * Map Processing shape kinds to WebGPU topologies. + */ + protected byte kindToTopology(int kind) { + return switch (kind) { + case POINTS -> PWebGPU.TOPOLOGY_POINT_LIST; + case LINES -> PWebGPU.TOPOLOGY_LINE_LIST; + case LINE_STRIP -> PWebGPU.TOPOLOGY_LINE_STRIP; + case TRIANGLES -> PWebGPU.TOPOLOGY_TRIANGLE_LIST; + case TRIANGLE_STRIP -> PWebGPU.TOPOLOGY_TRIANGLE_STRIP; + case TRIANGLE_FAN -> PWebGPU.TOPOLOGY_TRIANGLE_LIST; // Will need tessellation + case QUADS -> PWebGPU.TOPOLOGY_TRIANGLE_LIST; // Will need tessellation + case QUAD_STRIP -> PWebGPU.TOPOLOGY_TRIANGLE_STRIP; + default -> PWebGPU.TOPOLOGY_TRIANGLE_LIST; + }; + } + + @Override + public void beginShape(int kind) { + this.kind = kind; + this.topology = kindToTopology(kind); + + // Create or reset the geometry + if (geometryId != 0) { + PWebGPU.geometryDestroy(geometryId); + } + geometryId = PWebGPU.geometryCreate(topology); + building = true; + + // Reset pending attributes + hasNormal = false; + hasColor = false; + hasUV = false; + } + + @Override + public void endShape(int mode) { + building = false; + // If CLOSE mode and we have a polygon, we might need to add indices + // For now, the geometry is ready to be rendered + } + + @Override + public void normal(float nx, float ny, float nz) { + if (geometryId != 0) { + PWebGPU.geometryNormal(geometryId, nx, ny, nz); + } + normalX = nx; + normalY = ny; + normalZ = nz; + hasNormal = true; + } + + @Override + public void vertex(float x, float y) { + vertex(x, y, 0); + } + + @Override + public void vertex(float x, float y, float z) { + if (geometryId == 0) { + return; + } + if (hasColor) { + PWebGPU.geometryColor(geometryId, colorR, colorG, colorB, colorA); + } + if (hasUV) { + PWebGPU.geometryUv(geometryId, uvU, uvV); + } + PWebGPU.geometryVertex(geometryId, x, y, z); + } + + @Override + public void vertex(float x, float y, float u, float v) { + texture(u, v); + vertex(x, y, 0); + } + + @Override + public void vertex(float x, float y, float z, float u, float v) { + texture(u, v); + vertex(x, y, z); + } + + /** + * Set texture coordinates for the next vertex. + */ + public void texture(float u, float v) { + uvU = u; + uvV = v; + hasUV = true; + } + + /** + * Set the fill color for subsequent vertices. + */ + @Override + public void fill(int rgb) { + colorR = ((rgb >> 16) & 0xFF) / 255f; + colorG = ((rgb >> 8) & 0xFF) / 255f; + colorB = (rgb & 0xFF) / 255f; + colorA = ((rgb >> 24) & 0xFF) / 255f; + hasColor = true; + } + + @Override + public void fill(float gray) { + colorR = colorG = colorB = gray / 255f; + colorA = 1f; + hasColor = true; + } + + @Override + public void fill(float r, float g, float b) { + colorR = r / 255f; + colorG = g / 255f; + colorB = b / 255f; + colorA = 1f; + hasColor = true; + } + + @Override + public void fill(float r, float g, float b, float a) { + colorR = r / 255f; + colorG = g / 255f; + colorB = b / 255f; + colorA = a / 255f; + hasColor = true; + } + + /** + * Add an index for indexed rendering. + */ + public void index(int i) { + if (geometryId != 0) { + PWebGPU.geometryIndex(geometryId, i); + } + } + + @Override + public int getVertexCount() { + if (geometryId == 0) { + return 0; + } + return PWebGPU.geometryVertexCount(geometryId); + } + + /** + * Get the index count for this shape. + */ + public int getIndexCount() { + if (geometryId == 0) { + return 0; + } + return PWebGPU.geometryIndexCount(geometryId); + } + + @Override + public void setVertex(int index, float x, float y, float z) { + if (geometryId != 0) { + PWebGPU.geometrySetVertex(geometryId, index, x, y, z); + } + } + + @Override + public void setNormal(int index, float nx, float ny, float nz) { + if (geometryId != 0) { + PWebGPU.geometrySetNormal(geometryId, index, nx, ny, nz); + } + } + + /** + * Set the color of a specific vertex. + */ + public void setColor(int index, float r, float g, float b, float a) { + if (geometryId != 0) { + PWebGPU.geometrySetColor(geometryId, index, r, g, b, a); + } + } + + /** + * Set the UV coordinates of a specific vertex. + */ + public void setUv(int index, float u, float v) { + if (geometryId != 0) { + PWebGPU.geometrySetUv(geometryId, index, u, v); + } + } + + /** + * Get the native geometry ID for direct rendering. + */ + public long getGeometryId() { + return geometryId; + } + + /** + * Draw this shape using the associated graphics context. + */ + public void draw() { + if (geometryId != 0 && pg != null) { + pg.model(geometryId); + } + } + + /** + * Release native resources. + */ + public void dispose() { + if (geometryId != 0) { + PWebGPU.geometryDestroy(geometryId); + geometryId = 0; + } + if (layoutId != 0) { + PWebGPU.geometryLayoutDestroy(layoutId); + layoutId = 0; + } + } + + /** + * Create a box geometry. + */ + public static PShapeWebGPU createBox(PGraphicsWebGPU pg, float width, float height, float depth) { + PShapeWebGPU shape = new PShapeWebGPU(pg, GEOMETRY); + shape.geometryId = PWebGPU.geometryBox(width, height, depth); + return shape; + } +} diff --git a/core/src/processing/webgpu/PWebGPU.java b/core/src/processing/webgpu/PWebGPU.java index d53dbd9d1..85182ed36 100644 --- a/core/src/processing/webgpu/PWebGPU.java +++ b/core/src/processing/webgpu/PWebGPU.java @@ -45,7 +45,7 @@ public static void init() { * @return Window ID to use for subsequent operations */ public static long createSurface(long windowHandle, long displayHandle, int width, int height, float scaleFactor) { - long surfaceId = processing_create_surface(windowHandle, displayHandle, width, height, scaleFactor); + long surfaceId = processing_surface_create(windowHandle, displayHandle, width, height, scaleFactor); checkError(); return surfaceId; } @@ -56,7 +56,7 @@ public static long createSurface(long windowHandle, long displayHandle, int widt * @param surfaceId The window ID returned from createSurface */ public static void destroySurface(long surfaceId) { - processing_destroy_surface(surfaceId); + processing_surface_destroy(surfaceId); checkError(); } @@ -68,13 +68,27 @@ public static void destroySurface(long surfaceId) { * @param height New physical window height in pixels */ public static void windowResized(long surfaceId, int width, int height) { - processing_resize_surface(surfaceId, width, height); + processing_surface_resize(surfaceId, width, height); checkError(); } - - public static void beginDraw(long surfaceId) { - processing_begin_draw(surfaceId); + /** + * Creates a graphics context for the given surface. + * This must be called after createSurface before any drawing operations. + * + * @param surfaceId The surface ID returned from createSurface + * @param width Graphics width in pixels + * @param height Graphics height in pixels + * @return Graphics ID to use for drawing operations + */ + public static long graphicsCreate(long surfaceId, int width, int height) { + long graphicsId = processing_graphics_create(surfaceId, width, height); + checkError(); + return graphicsId; + } + + public static void beginDraw(long graphicsId) { + processing_begin_draw(graphicsId); checkError(); } @@ -159,6 +173,403 @@ public static void rect(long surfaceId, float x, float y, float w, float h, checkError(); } + /** + * Push the current transformation matrix onto the stack. + */ + public static void pushMatrix(long surfaceId) { + processing_push_matrix(surfaceId); + checkError(); + } + + /** + * Pop the transformation matrix from the stack. + */ + public static void popMatrix(long surfaceId) { + processing_pop_matrix(surfaceId); + checkError(); + } + + /** + * Reset the transformation matrix to identity. + */ + public static void resetMatrix(long surfaceId) { + processing_reset_matrix(surfaceId); + checkError(); + } + + /** + * Translate the coordinate system. + */ + public static void translate(long surfaceId, float x, float y) { + processing_translate(surfaceId, x, y); + checkError(); + } + + /** + * Rotate around the X axis. + */ + public static void rotateX(long surfaceId, float angle) { + processing_rotate_x(surfaceId, angle); + checkError(); + } + + /** + * Rotate around the Y axis. + */ + public static void rotateY(long surfaceId, float angle) { + processing_rotate_y(surfaceId, angle); + checkError(); + } + + /** + * Rotate around the Z axis. + */ + public static void rotateZ(long surfaceId, float angle) { + processing_rotate_z(surfaceId, angle); + checkError(); + } + + /** + * Rotate the coordinate system. + */ + public static void rotate(long surfaceId, float angle) { + rotateZ(surfaceId, angle); + } + + /** + * Scale the coordinate system. + */ + public static void scale(long surfaceId, float x, float y) { + processing_scale(surfaceId, x, y); + checkError(); + } + + /** + * Shear along the X axis. + */ + public static void shearX(long surfaceId, float angle) { + processing_shear_x(surfaceId, angle); + checkError(); + } + + /** + * Shear along the Y axis. + */ + public static void shearY(long surfaceId, float angle) { + processing_shear_y(surfaceId, angle); + checkError(); + } + + /** + * Create an image from raw pixel data. + * + * @param width Image width in pixels + * @param height Image height in pixels + * @param data RGBA pixel data (4 bytes per pixel) + * @return Image ID for subsequent operations, or 0 on failure + */ + public static long imageCreate(int width, int height, byte[] data) { + try (Arena arena = Arena.ofConfined()) { + MemorySegment dataSegment = arena.allocateFrom(java.lang.foreign.ValueLayout.JAVA_BYTE, data); + long imageId = processing_image_create(width, height, dataSegment, data.length); + checkError(); + return imageId; + } + } + + /** + * Load an image from a file path. + * + * @param path Path to the image file + * @return Image ID for subsequent operations, or 0 on failure + */ + public static long imageLoad(String path) { + try (Arena arena = Arena.ofConfined()) { + MemorySegment pathSegment = arena.allocateFrom(path); + long imageId = processing_image_load(pathSegment); + checkError(); + return imageId; + } + } + + /** + * Resize an image. + * + * @param imageId The image ID returned from imageCreate or imageLoad + * @param newWidth New width in pixels + * @param newHeight New height in pixels + */ + public static void imageResize(long imageId, int newWidth, int newHeight) { + processing_image_resize(imageId, newWidth, newHeight); + checkError(); + } + + /** + * Read back pixel data from an image into a buffer. + * + * @param imageId The image ID returned from imageCreate or imageLoad + * @param buffer Buffer to receive Color data (must be width * height elements) + */ + public static void imageReadback(long imageId, float[] buffer) { + try (Arena arena = Arena.ofConfined()) { + int numPixels = buffer.length / 4; + MemorySegment colorBuffer = Color.allocateArray(numPixels, arena); + processing_image_readback(imageId, colorBuffer, numPixels); + checkError(); + + for (int i = 0; i < numPixels; i++) { + MemorySegment color = Color.asSlice(colorBuffer, i); + buffer[i * 4] = Color.r(color); + buffer[i * 4 + 1] = Color.g(color); + buffer[i * 4 + 2] = Color.b(color); + buffer[i * 4 + 3] = Color.a(color); + } + } + } + + /** + * Set the background to an image. + * + * @param surfaceId The surface ID + * @param imageId The image ID to use as background + */ + public static void backgroundImage(long surfaceId, long imageId) { + processing_background_image(surfaceId, imageId); + checkError(); + } + + /** + * Switch to 3D rendering mode. + */ + public static void mode3d(long surfaceId) { + processing_mode_3d(surfaceId); + checkError(); + } + + /** + * Switch to 2D rendering mode. + */ + public static void mode2d(long surfaceId) { + processing_mode_2d(surfaceId); + checkError(); + } + + /** + * Set the camera position. + */ + public static void cameraPosition(long surfaceId, float x, float y, float z) { + processing_camera_position(surfaceId, x, y, z); + checkError(); + } + + /** + * Set where the camera is looking at. + */ + public static void cameraLookAt(long surfaceId, float targetX, float targetY, float targetZ) { + processing_camera_look_at(surfaceId, targetX, targetY, targetZ); + checkError(); + } + + /** + * Set perspective projection. + */ + public static void perspective(long surfaceId, float fov, float aspect, float near, float far) { + processing_perspective(surfaceId, fov, aspect, near, far); + checkError(); + } + + /** + * Set orthographic projection. + */ + public static void ortho(long surfaceId, float left, float right, float bottom, float top, float near, float far) { + processing_ortho(surfaceId, left, right, bottom, top, near, far); + checkError(); + } + + /** Topology constants */ + public static final byte TOPOLOGY_POINT_LIST = 0; + public static final byte TOPOLOGY_LINE_LIST = 1; + public static final byte TOPOLOGY_LINE_STRIP = 2; + public static final byte TOPOLOGY_TRIANGLE_LIST = 3; + public static final byte TOPOLOGY_TRIANGLE_STRIP = 4; + + /** Attribute format constants */ + public static final byte ATTR_FORMAT_FLOAT = 1; + public static final byte ATTR_FORMAT_FLOAT2 = 2; + public static final byte ATTR_FORMAT_FLOAT3 = 3; + public static final byte ATTR_FORMAT_FLOAT4 = 4; + + public static long geometryLayoutCreate() { + long layoutId = processing_geometry_layout_create(); + checkError(); + return layoutId; + } + + public static void geometryLayoutAddPosition(long layoutId) { + processing_geometry_layout_add_position(layoutId); + checkError(); + } + + public static void geometryLayoutAddNormal(long layoutId) { + processing_geometry_layout_add_normal(layoutId); + checkError(); + } + + public static void geometryLayoutAddColor(long layoutId) { + processing_geometry_layout_add_color(layoutId); + checkError(); + } + + public static void geometryLayoutAddUv(long layoutId) { + processing_geometry_layout_add_uv(layoutId); + checkError(); + } + + public static void geometryLayoutAddAttribute(long layoutId, long attrId) { + processing_geometry_layout_add_attribute(layoutId, attrId); + checkError(); + } + + public static void geometryLayoutDestroy(long layoutId) { + processing_geometry_layout_destroy(layoutId); + checkError(); + } + + public static long geometryCreate(byte topology) { + long geoId = processing_geometry_create(topology); + checkError(); + return geoId; + } + + public static long geometryCreateWithLayout(long layoutId, byte topology) { + long geoId = processing_geometry_create_with_layout(layoutId, topology); + checkError(); + return geoId; + } + + public static long geometryBox(float width, float height, float depth) { + long geoId = processing_geometry_box(width, height, depth); + checkError(); + return geoId; + } + + public static void geometryDestroy(long geoId) { + processing_geometry_destroy(geoId); + checkError(); + } + + public static void geometryNormal(long geoId, float nx, float ny, float nz) { + processing_geometry_normal(geoId, nx, ny, nz); + checkError(); + } + + public static void geometryColor(long geoId, float r, float g, float b, float a) { + processing_geometry_color(geoId, r, g, b, a); + checkError(); + } + + public static void geometryUv(long geoId, float u, float v) { + processing_geometry_uv(geoId, u, v); + checkError(); + } + + public static void geometryVertex(long geoId, float x, float y, float z) { + processing_geometry_vertex(geoId, x, y, z); + checkError(); + } + + public static void geometryIndex(long geoId, int i) { + processing_geometry_index(geoId, i); + checkError(); + } + + public static long geometryAttributeCreate(String name, byte format) { + try (Arena arena = Arena.ofConfined()) { + MemorySegment nameSegment = arena.allocateFrom(name); + long attrId = processing_geometry_attribute_create(nameSegment, format); + checkError(); + return attrId; + } + } + + public static void geometryAttributeDestroy(long attrId) { + processing_geometry_attribute_destroy(attrId); + checkError(); + } + + public static long geometryAttributePosition() { + return processing_geometry_attribute_position(); + } + + public static long geometryAttributeNormal() { + return processing_geometry_attribute_normal(); + } + + public static long geometryAttributeColor() { + return processing_geometry_attribute_color(); + } + + public static long geometryAttributeUv() { + return processing_geometry_attribute_uv(); + } + + public static void geometryAttributeFloat(long geoId, long attrId, float v) { + processing_geometry_attribute_float(geoId, attrId, v); + checkError(); + } + + public static void geometryAttributeFloat2(long geoId, long attrId, float x, float y) { + processing_geometry_attribute_float2(geoId, attrId, x, y); + checkError(); + } + + public static void geometryAttributeFloat3(long geoId, long attrId, float x, float y, float z) { + processing_geometry_attribute_float3(geoId, attrId, x, y, z); + checkError(); + } + + public static void geometryAttributeFloat4(long geoId, long attrId, float x, float y, float z, float w) { + processing_geometry_attribute_float4(geoId, attrId, x, y, z, w); + checkError(); + } + + public static int geometryVertexCount(long geoId) { + int count = processing_geometry_vertex_count(geoId); + checkError(); + return count; + } + + public static int geometryIndexCount(long geoId) { + int count = processing_geometry_index_count(geoId); + checkError(); + return count; + } + + public static void geometrySetVertex(long geoId, int index, float x, float y, float z) { + processing_geometry_set_vertex(geoId, index, x, y, z); + checkError(); + } + + public static void geometrySetNormal(long geoId, int index, float nx, float ny, float nz) { + processing_geometry_set_normal(geoId, index, nx, ny, nz); + checkError(); + } + + public static void geometrySetColor(long geoId, int index, float r, float g, float b, float a) { + processing_geometry_set_color(geoId, index, r, g, b, a); + checkError(); + } + + public static void geometrySetUv(long geoId, int index, float u, float v) { + processing_geometry_set_uv(geoId, index, u, v); + checkError(); + } + + public static void model(long surfaceId, long geoId) { + processing_model(surfaceId, geoId); + checkError(); + } + /** * Checks for errors from the native library and throws a PWebGPUException if an error occurred. */ diff --git a/libprocessing b/libprocessing index 18f514612..f39d1ba1e 160000 --- a/libprocessing +++ b/libprocessing @@ -1 +1 @@ -Subproject commit 18f514612d5f746fafb54488a8bc382771594582 +Subproject commit f39d1ba1e042f4353e87cb3c37cada711d60e924 From 4127dc05a7cbe9c4bc90d5baba2f39adc5bb598b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?charlotte=20=F0=9F=8C=B8?= Date: Sat, 2 May 2026 14:07:44 -0700 Subject: [PATCH 22/26] Updates from libprocessing. --- .../processing/webgpu/PGraphicsWebGPU.java | 310 +++++--- core/src/processing/webgpu/PSurfaceGLFW.java | 125 ++- core/src/processing/webgpu/PWebGPU.java | 727 ++++++++++++------ libprocessing | 2 +- 4 files changed, 834 insertions(+), 330 deletions(-) diff --git a/core/src/processing/webgpu/PGraphicsWebGPU.java b/core/src/processing/webgpu/PGraphicsWebGPU.java index 1afde5b3c..ecbcbcb78 100644 --- a/core/src/processing/webgpu/PGraphicsWebGPU.java +++ b/core/src/processing/webgpu/PGraphicsWebGPU.java @@ -9,14 +9,13 @@ import java.util.List; public class PGraphicsWebGPU extends PGraphics { - private long surfaceId = 0; + protected long surfaceId = 0; private long graphicsId = 0; private long currentGeometry = 0; private int shapeKind = 0; private float normalX = 0, normalY = 0, normalZ = 1; - // immediate mode geometries pending destruction private final List pendingDestroy = new ArrayList<>(); @@ -37,6 +36,10 @@ protected void initWebGPUSurface(long windowHandle, long displayHandle, int widt } } + public long getSurfaceId() { + return surfaceId; + } + @Override public void setSize(int w, int h) { super.setSize(w, h); @@ -88,6 +91,8 @@ public void dispose() { PWebGPU.exit(); } + // ── Background ────────────────────────────────────────────────────── + @Override protected void backgroundImpl() { if (graphicsId == 0) { @@ -114,6 +119,8 @@ protected void backgroundImpl(PImage image) { PWebGPU.backgroundImage(graphicsId, img.getId()); } + // ── Fill / stroke ─────────────────────────────────────────────────── + @Override protected void fillFromCalc() { super.fillFromCalc(); @@ -168,185 +175,169 @@ public void noStroke() { } @Override - protected void rectImpl(float x1, float y1, float x2, float y2) { - rectImpl(x1, y1, x2, y2, 0, 0, 0, 0); - } - - @Override - protected void rectImpl(float x1, float y1, float x2, float y2, - float tl, float tr, float br, float bl) { + public void strokeCap(int cap) { + super.strokeCap(cap); if (graphicsId == 0) { return; } - PWebGPU.rect(graphicsId, x1, y1, x2 - x1, y2 - y1, tl, tr, br, bl); + byte nativeCap = switch (cap) { + case ROUND -> PWebGPU.STROKE_CAP_ROUND; + case SQUARE -> PWebGPU.STROKE_CAP_SQUARE; + case PROJECT -> PWebGPU.STROKE_CAP_PROJECT; + default -> PWebGPU.STROKE_CAP_ROUND; + }; + PWebGPU.setStrokeCap(graphicsId, nativeCap); } @Override - public void box(float w, float h, float d) { + public void strokeJoin(int join) { + super.strokeJoin(join); if (graphicsId == 0) { return; } - long boxGeometry = PWebGPU.geometryBox(w, h, d); - PWebGPU.model(graphicsId, boxGeometry); - pendingDestroy.add(boxGeometry); + byte nativeJoin = switch (join) { + case ROUND -> PWebGPU.STROKE_JOIN_ROUND; + case MITER -> PWebGPU.STROKE_JOIN_MITER; + case BEVEL -> PWebGPU.STROKE_JOIN_BEVEL; + default -> PWebGPU.STROKE_JOIN_ROUND; + }; + PWebGPU.setStrokeJoin(graphicsId, nativeJoin); } - @Override - public void pushMatrix() { - if (graphicsId == 0) { - return; - } - PWebGPU.pushMatrix(graphicsId); - } + // ── Blend mode ────────────────────────────────────────────────────── @Override - public void popMatrix() { + public void blendMode(int mode) { + super.blendMode(mode); if (graphicsId == 0) { return; } - PWebGPU.popMatrix(graphicsId); + byte nativeMode = switch (mode) { + case BLEND -> PWebGPU.BLEND_MODE_BLEND; + case ADD -> PWebGPU.BLEND_MODE_ADD; + case SUBTRACT -> PWebGPU.BLEND_MODE_SUBTRACT; + case DARKEST -> PWebGPU.BLEND_MODE_DARKEST; + case LIGHTEST -> PWebGPU.BLEND_MODE_LIGHTEST; + case DIFFERENCE -> PWebGPU.BLEND_MODE_DIFFERENCE; + case EXCLUSION -> PWebGPU.BLEND_MODE_EXCLUSION; + case MULTIPLY -> PWebGPU.BLEND_MODE_MULTIPLY; + case SCREEN -> PWebGPU.BLEND_MODE_SCREEN; + case REPLACE -> PWebGPU.BLEND_MODE_REPLACE; + default -> PWebGPU.BLEND_MODE_BLEND; + }; + PWebGPU.setBlendMode(graphicsId, nativeMode); } - @Override - public void resetMatrix() { - if (graphicsId == 0) { - return; - } - PWebGPU.resetMatrix(graphicsId); - } + // ── 2D primitives ─────────────────────────────────────────────────── @Override - public void translate(float x, float y) { - if (graphicsId == 0) { - return; - } - PWebGPU.translate(graphicsId, x, y); + protected void rectImpl(float x1, float y1, float x2, float y2) { + rectImpl(x1, y1, x2, y2, 0, 0, 0, 0); } @Override - public void rotate(float angle) { + protected void rectImpl(float x1, float y1, float x2, float y2, + float tl, float tr, float br, float bl) { if (graphicsId == 0) { return; } - PWebGPU.rotate(graphicsId, angle); + PWebGPU.rect(graphicsId, x1, y1, x2 - x1, y2 - y1, tl, tr, br, bl); } @Override - public void rotateX(float angle) { + protected void ellipseImpl(float a, float b, float c, float d) { if (graphicsId == 0) { return; } - PWebGPU.rotateX(graphicsId, angle); + PWebGPU.ellipse(graphicsId, a, b, c, d); } @Override - public void rotateY(float angle) { + protected void arcImpl(float a, float b, float c, float d, + float start, float stop, int mode) { if (graphicsId == 0) { return; } - PWebGPU.rotateY(graphicsId, angle); + PWebGPU.arc(graphicsId, a, b, c, d, start, stop, (byte) mode); } @Override - public void scale(float x, float y) { + public void line(float x1, float y1, float x2, float y2) { if (graphicsId == 0) { return; } - PWebGPU.scale(graphicsId, x, y); + PWebGPU.line(graphicsId, x1, y1, x2, y2); } @Override - public void shearX(float angle) { + public void point(float x, float y) { if (graphicsId == 0) { return; } - PWebGPU.shearX(graphicsId, angle); + PWebGPU.point(graphicsId, x, y); } @Override - public void shearY(float angle) { + public void triangle(float x1, float y1, float x2, float y2, float x3, float y3) { if (graphicsId == 0) { return; } - PWebGPU.shearY(graphicsId, angle); - } - - public PImageWebGPU createImage(int width, int height, int format) { - return new PImageWebGPU(width, height, format); - } - - private byte[] pixelsToRGBA(int[] pixels) { - byte[] rgba = new byte[pixels.length * 4]; - for (int i = 0; i < pixels.length; i++) { - int pixel = pixels[i]; - rgba[i * 4] = (byte) ((pixel >> 16) & 0xFF); - rgba[i * 4 + 1] = (byte) ((pixel >> 8) & 0xFF); - rgba[i * 4 + 2] = (byte) (pixel & 0xFF); - rgba[i * 4 + 3] = (byte) ((pixel >> 24) & 0xFF); - } - return rgba; + PWebGPU.triangle(graphicsId, x1, y1, x2, y2, x3, y3); } - public void cameraPosition(float x, float y, float z) { + @Override + public void quad(float x1, float y1, float x2, float y2, + float x3, float y3, float x4, float y4) { if (graphicsId == 0) { return; } - PWebGPU.cameraPosition(graphicsId, x, y, z); + PWebGPU.quad(graphicsId, x1, y1, x2, y2, x3, y3, x4, y4); } - public void cameraLookAt(float x, float y, float z) { - if (graphicsId == 0) { - return; - } - PWebGPU.cameraLookAt(graphicsId, x, y, z); - } + // ── Curves ────────────────────────────────────────────────────────── @Override - public void camera(float eyeX, float eyeY, float eyeZ, - float centerX, float centerY, float centerZ, - float upX, float upY, float upZ) { + public void bezier(float x1, float y1, float x2, float y2, + float x3, float y3, float x4, float y4) { if (graphicsId == 0) { return; } - PWebGPU.mode3d(graphicsId); - PWebGPU.cameraPosition(graphicsId, eyeX, eyeY, eyeZ); - PWebGPU.cameraLookAt(graphicsId, centerX, centerY, centerZ); + PWebGPU.bezier(graphicsId, x1, y1, x2, y2, x3, y3, x4, y4); } @Override - public void perspective(float fov, float aspect, float near, float far) { + public void curve(float x1, float y1, float x2, float y2, + float x3, float y3, float x4, float y4) { if (graphicsId == 0) { return; } - PWebGPU.mode3d(graphicsId); - PWebGPU.perspective(graphicsId, fov, aspect, near, far); + PWebGPU.curve(graphicsId, x1, y1, x2, y2, x3, y3, x4, y4); } + // ── 3D shapes ─────────────────────────────────────────────────────── + @Override - public void ortho(float left, float right, float bottom, float top, float near, float far) { + public void box(float w, float h, float d) { if (graphicsId == 0) { return; } - PWebGPU.ortho(graphicsId, left, right, bottom, top, near, far); - } - - @Override - public PShape createShape() { - return new PShapeWebGPU(this, PShape.GEOMETRY); + long boxGeometry = PWebGPU.geometryBox(w, h, d); + PWebGPU.model(graphicsId, boxGeometry); + pendingDestroy.add(boxGeometry); } @Override - public PShape createShape(int type) { - return new PShapeWebGPU(this, type); - } - - public void model(long geometryId) { + public void sphere(float r) { if (graphicsId == 0) { return; } - PWebGPU.model(graphicsId, geometryId); + long sphereGeometry = PWebGPU.geometrySphere(r, sphereDetailU, sphereDetailV); + PWebGPU.model(graphicsId, sphereGeometry); + pendingDestroy.add(sphereGeometry); } + // ── Vertex shapes ─────────────────────────────────────────────────── + @Override public void beginShape(int kind) { super.beginShape(kind); @@ -414,4 +405,137 @@ public void endShape(int mode) { pendingDestroy.add(currentGeometry); currentGeometry = 0; } + + // ── Transform matrix ──────────────────────────────────────────────── + + @Override + public void pushMatrix() { + if (graphicsId == 0) { + return; + } + PWebGPU.pushMatrix(graphicsId); + } + + @Override + public void popMatrix() { + if (graphicsId == 0) { + return; + } + PWebGPU.popMatrix(graphicsId); + } + + @Override + public void resetMatrix() { + if (graphicsId == 0) { + return; + } + PWebGPU.resetMatrix(graphicsId); + } + + @Override + public void translate(float x, float y) { + if (graphicsId == 0) { + return; + } + PWebGPU.translate(graphicsId, x, y); + } + + @Override + public void rotate(float angle) { + if (graphicsId == 0) { + return; + } + PWebGPU.rotate(graphicsId, angle); + } + + @Override + public void scale(float x, float y) { + if (graphicsId == 0) { + return; + } + PWebGPU.scale(graphicsId, x, y); + } + + @Override + public void shearX(float angle) { + if (graphicsId == 0) { + return; + } + PWebGPU.shearX(graphicsId, angle); + } + + @Override + public void shearY(float angle) { + if (graphicsId == 0) { + return; + } + PWebGPU.shearY(graphicsId, angle); + } + + // ── 3D camera / projection ────────────────────────────────────────── + + @Override + public void camera(float eyeX, float eyeY, float eyeZ, + float centerX, float centerY, float centerZ, + float upX, float upY, float upZ) { + if (graphicsId == 0) { + return; + } + PWebGPU.mode3d(graphicsId); + // TODO: camera up vector is not yet exposed by libprocessing FFI + } + + @Override + public void perspective(float fov, float aspect, float near, float far) { + if (graphicsId == 0) { + return; + } + PWebGPU.mode3d(graphicsId); + PWebGPU.perspective(graphicsId, fov, aspect, near, far); + } + + @Override + public void ortho(float left, float right, float bottom, float top, float near, float far) { + if (graphicsId == 0) { + return; + } + PWebGPU.ortho(graphicsId, left, right, bottom, top, near, far); + } + + // ── Images / shapes ───────────────────────────────────────────────── + + public PImageWebGPU createImage(int width, int height, int format) { + return new PImageWebGPU(width, height, format); + } + + @Override + public PShape createShape() { + return new PShapeWebGPU(this, PShape.GEOMETRY); + } + + @Override + public PShape createShape(int type) { + return new PShapeWebGPU(this, type); + } + + public void model(long geometryId) { + if (graphicsId == 0) { + return; + } + PWebGPU.model(graphicsId, geometryId); + } + + // ── Helpers ────────────────────────────────────────────────────────── + + private byte[] pixelsToRGBA(int[] pixels) { + byte[] rgba = new byte[pixels.length * 4]; + for (int i = 0; i < pixels.length; i++) { + int pixel = pixels[i]; + rgba[i * 4] = (byte) ((pixel >> 16) & 0xFF); + rgba[i * 4 + 1] = (byte) ((pixel >> 8) & 0xFF); + rgba[i * 4 + 2] = (byte) (pixel & 0xFF); + rgba[i * 4 + 3] = (byte) ((pixel >> 24) & 0xFF); + } + return rgba; + } } diff --git a/core/src/processing/webgpu/PSurfaceGLFW.java b/core/src/processing/webgpu/PSurfaceGLFW.java index f80131e19..110955559 100644 --- a/core/src/processing/webgpu/PSurfaceGLFW.java +++ b/core/src/processing/webgpu/PSurfaceGLFW.java @@ -16,9 +16,6 @@ import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; -/** - * GLFW-based surface implementation for WebGPU. - */ public class PSurfaceGLFW implements PSurface { protected PApplet sketch; @@ -40,6 +37,13 @@ public class PSurfaceGLFW implements PSurface { private GLFWFramebufferSizeCallback framebufferSizeCallback; private GLFWWindowPosCallback windowPosCallback; + private GLFWCursorPosCallback cursorPosCallback; + private GLFWMouseButtonCallback mouseButtonCallback; + private GLFWScrollCallback scrollCallback; + private GLFWKeyCallback keyCallback; + private GLFWCharCallback charCallback; + private GLFWCursorEnterCallback cursorEnterCallback; + private GLFWWindowFocusCallback windowFocusCallback; public PSurfaceGLFW(PGraphics graphics) { this.graphics = graphics; @@ -64,7 +68,7 @@ public void initFrame(PApplet sketch) { } GLFW.glfwDefaultWindowHints(); - GLFW.glfwWindowHint(GLFW.GLFW_CLIENT_API, GLFW.GLFW_NO_API); // no opengl + GLFW.glfwWindowHint(GLFW.GLFW_CLIENT_API, GLFW.GLFW_NO_API); GLFW.glfwWindowHint(GLFW.GLFW_VISIBLE, GLFW.GLFW_FALSE); GLFW.glfwWindowHint(GLFW.GLFW_RESIZABLE, GLFW.GLFW_FALSE); @@ -78,7 +82,6 @@ public void initFrame(PApplet sketch) { windowCount.incrementAndGet(); - // event callbacks initListeners(); if (graphics instanceof PGraphicsWebGPU webgpu) { @@ -95,6 +98,8 @@ public void initFrame(PApplet sketch) { } protected void initListeners() { + long surfaceId = getSurfaceId(); + framebufferSizeCallback = GLFW.glfwSetFramebufferSizeCallback(window, (window, width, height) -> { if (sketch != null) { @@ -109,7 +114,74 @@ protected void initListeners() { } }); - // TODO: all the callbacks + cursorPosCallback = GLFW.glfwSetCursorPosCallback(window, + (window, xpos, ypos) -> { + if (surfaceId != 0) { + PWebGPU.inputMouseMove(surfaceId, (float) xpos, (float) ypos); + } + }); + + mouseButtonCallback = GLFW.glfwSetMouseButtonCallback(window, + (window, button, action, mods) -> { + if (surfaceId != 0) { + byte btn = switch (button) { + case GLFW.GLFW_MOUSE_BUTTON_LEFT -> 0; + case GLFW.GLFW_MOUSE_BUTTON_MIDDLE -> 1; + case GLFW.GLFW_MOUSE_BUTTON_RIGHT -> 2; + default -> -1; + }; + if (btn >= 0) { + PWebGPU.inputMouseButton(surfaceId, btn, action == GLFW.GLFW_PRESS); + } + } + }); + + scrollCallback = GLFW.glfwSetScrollCallback(window, + (window, xoffset, yoffset) -> { + if (surfaceId != 0) { + PWebGPU.inputScroll(surfaceId, (float) xoffset, (float) yoffset); + } + }); + + keyCallback = GLFW.glfwSetKeyCallback(window, + (window, key, scancode, action, mods) -> { + if (surfaceId != 0 && action != GLFW.GLFW_REPEAT) { + PWebGPU.inputKey(surfaceId, key, action == GLFW.GLFW_PRESS); + } + }); + + charCallback = GLFW.glfwSetCharCallback(window, + (window, codepoint) -> { + // char callback doesn't give us a key code, so pass 0 + if (surfaceId != 0) { + PWebGPU.inputChar(surfaceId, 0, codepoint); + } + }); + + cursorEnterCallback = GLFW.glfwSetCursorEnterCallback(window, + (window, entered) -> { + if (surfaceId != 0) { + if (entered) { + PWebGPU.inputCursorEnter(surfaceId); + } else { + PWebGPU.inputCursorLeave(surfaceId); + } + } + }); + + windowFocusCallback = GLFW.glfwSetWindowFocusCallback(window, + (window, focused) -> { + if (surfaceId != 0) { + PWebGPU.inputFocus(surfaceId, focused); + } + }); + } + + private long getSurfaceId() { + if (graphics instanceof PGraphicsWebGPU webgpu) { + return webgpu.getSurfaceId(); + } + return 0; } @Override @@ -132,10 +204,8 @@ public long getWindowHandle() { public long getDisplayHandle() { if (Platform.get() == Platform.MACOSX) { - // TODO: Currently unsupported return 0; } else if (Platform.get() == Platform.WINDOWS) { - // TODO: Currently unsupported return 0; } else if (Platform.get() == Platform.LINUX) { // TODO: need to check if x11 or wayland @@ -197,7 +267,6 @@ public void placeWindow(int[] location, int[] editorLocation) { y = editorLocation[1]; if (x - sketch.sketchWidth() < 10) { - // doesn't fit, center on screen instead long monitor = GLFW.glfwGetPrimaryMonitor(); var vidmode = GLFW.glfwGetVideoMode(monitor); if (vidmode != null) { @@ -209,7 +278,6 @@ public void placeWindow(int[] location, int[] editorLocation) { } } } else { - // center on primary monitor long monitor = GLFW.glfwGetPrimaryMonitor(); var vidmode = GLFW.glfwGetVideoMode(monitor); if (vidmode != null) { @@ -295,19 +363,16 @@ public boolean openLink(String url) { @Override public void selectInput(String prompt, String callback, File file, Object callbackObject) { - // TODO: select input without awt throw new UnsupportedOperationException("File dialogs not yet implemented for WebGPU"); } @Override public void selectOutput(String prompt, String callback, File file, Object callbackObject) { - // TODO: file dialogs without awt throw new UnsupportedOperationException("File dialogs not yet implemented for WebGPU"); } @Override public void selectFolder(String prompt, String callback, File file, Object callbackObject) { - // TODO: folder selection without awt throw new UnsupportedOperationException("Folder selection not yet implemented for WebGPU"); } @@ -333,16 +398,15 @@ protected void runDrawLoop() { checkPause(); GLFW.glfwPollEvents(); + PWebGPU.inputFlush(); if (GLFW.glfwWindowShouldClose(window)) { sketch.exit(); break; } - // render! sketch.handleDraw(); - // frame pacing long afterTime = System.nanoTime(); long timeDiff = afterTime - beforeTime; long sleepTime = (frameRatePeriod - timeDiff) - overSleepTime; @@ -361,7 +425,6 @@ protected void runDrawLoop() { beforeTime = System.nanoTime(); } - // cleanup sketch.dispose(); } @@ -417,7 +480,6 @@ public boolean stopThread() { } } } finally { - // run destructors always freeCallbacks(); } @@ -433,9 +495,36 @@ private void freeCallbacks() { windowPosCallback.free(); windowPosCallback = null; } + if (cursorPosCallback != null) { + cursorPosCallback.free(); + cursorPosCallback = null; + } + if (mouseButtonCallback != null) { + mouseButtonCallback.free(); + mouseButtonCallback = null; + } + if (scrollCallback != null) { + scrollCallback.free(); + scrollCallback = null; + } + if (keyCallback != null) { + keyCallback.free(); + keyCallback = null; + } + if (charCallback != null) { + charCallback.free(); + charCallback = null; + } + if (cursorEnterCallback != null) { + cursorEnterCallback.free(); + cursorEnterCallback = null; + } + if (windowFocusCallback != null) { + windowFocusCallback.free(); + windowFocusCallback = null; + } } - @Override public boolean isStopped() { return !running; diff --git a/core/src/processing/webgpu/PWebGPU.java b/core/src/processing/webgpu/PWebGPU.java index 85182ed36..fd3b5c751 100644 --- a/core/src/processing/webgpu/PWebGPU.java +++ b/core/src/processing/webgpu/PWebGPU.java @@ -9,265 +9,514 @@ import static processing.ffi.processing_h.*; import processing.ffi.Color; -/** - * PWebGPU provides the native interface layer for libprocessing's WebGPU support. - */ public class PWebGPU { static { ensureLoaded(); } - /** - * Ensure the native library is loaded. - */ public static void ensureLoaded() { NativeLibrary.ensureLoaded(); } - /** - * Initializes the WebGPU subsystem. Must be called before any other WebGPU methods. - * This should be called from the same thread that will call update(). - */ + // ── Init / lifecycle ──────────────────────────────────────────────── + public static void init() { processing_init(); checkError(); } - /** - * Creates a WebGPU surface from a native window handle. - * - * @param windowHandle The native window handle - * @param displayHandle The native display handle - * @param width Window width in physical pixels - * @param height Window height in phsyical pixels - * @param scaleFactor os provided scale factor - * @return Window ID to use for subsequent operations - */ + public static void exit() { + processing_exit((byte) 0); + checkError(); + } + + // ── Surface ───────────────────────────────────────────────────────── + public static long createSurface(long windowHandle, long displayHandle, int width, int height, float scaleFactor) { long surfaceId = processing_surface_create(windowHandle, displayHandle, width, height, scaleFactor); checkError(); return surfaceId; } - /** - * Destroys a WebGPU surface. - * - * @param surfaceId The window ID returned from createSurface - */ public static void destroySurface(long surfaceId) { processing_surface_destroy(surfaceId); checkError(); } - /** - * Updates a window's size. - * - * @param surfaceId The window ID returned from createSurface - * @param width New physical window width in pixels - * @param height New physical window height in pixels - */ public static void windowResized(long surfaceId, int width, int height) { processing_surface_resize(surfaceId, width, height); checkError(); } - /** - * Creates a graphics context for the given surface. - * This must be called after createSurface before any drawing operations. - * - * @param surfaceId The surface ID returned from createSurface - * @param width Graphics width in pixels - * @param height Graphics height in pixels - * @return Graphics ID to use for drawing operations - */ + // ── Graphics context ──────────────────────────────────────────────── + public static long graphicsCreate(long surfaceId, int width, int height) { long graphicsId = processing_graphics_create(surfaceId, width, height); checkError(); return graphicsId; } + public static void graphicsDestroy(long graphicsId) { + processing_graphics_destroy(graphicsId); + checkError(); + } + public static void beginDraw(long graphicsId) { processing_begin_draw(graphicsId); checkError(); } - public static void flush(long surfaceId) { - processing_flush(surfaceId); + public static void flush(long graphicsId) { + processing_flush(graphicsId); checkError(); } - public static void endDraw(long surfaceId) { - processing_end_draw(surfaceId); + public static void endDraw(long graphicsId) { + processing_end_draw(graphicsId); checkError(); } - /** - * Cleans up the WebGPU subsystem. Should be called on application exit. - */ - public static void exit() { - processing_exit((byte) 0); + // ── Background ────────────────────────────────────────────────────── + + public static void backgroundColor(long graphicsId, float r, float g, float b, float a) { + try (Arena arena = Arena.ofConfined()) { + MemorySegment color = allocateColor(arena, r, g, b, a); + processing_background_color(graphicsId, color); + checkError(); + } + } + + public static void backgroundImage(long graphicsId, long imageId) { + processing_background_image(graphicsId, imageId); checkError(); } - public static void backgroundColor(long surfaceId, float r, float g, float b, float a) { - try (Arena arena = Arena.ofConfined()) { - MemorySegment color = Color.allocate(arena); + // ── Color mode ────────────────────────────────────────────────────── + + public static final byte COLOR_SPACE_SRGB = 0; + public static final byte COLOR_SPACE_HSB = 1; + public static final byte COLOR_SPACE_LINEAR = 2; + + public static void colorMode(long graphicsId, byte space, float max1, float max2, float max3, float maxAlpha) { + processing_color_mode(graphicsId, space, max1, max2, max3, maxAlpha); + checkError(); + } - Color.r(color, r); - Color.g(color, g); - Color.b(color, b); - Color.a(color, a); + // ── Fill / stroke ─────────────────────────────────────────────────── - processing_background_color(surfaceId, color); + public static void setFill(long graphicsId, float r, float g, float b, float a) { + try (Arena arena = Arena.ofConfined()) { + MemorySegment color = allocateColor(arena, r, g, b, a); + processing_set_fill(graphicsId, color); checkError(); } } - /** - * Set the fill color. - */ - public static void setFill(long surfaceId, float r, float g, float b, float a) { - processing_set_fill(surfaceId, r, g, b, a); + public static void setStrokeColor(long graphicsId, float r, float g, float b, float a) { + try (Arena arena = Arena.ofConfined()) { + MemorySegment color = allocateColor(arena, r, g, b, a); + processing_set_stroke_color(graphicsId, color); + checkError(); + } + } + + public static void setStrokeWeight(long graphicsId, float weight) { + processing_set_stroke_weight(graphicsId, weight); + checkError(); + } + + public static void noFill(long graphicsId) { + processing_no_fill(graphicsId); + checkError(); + } + + public static void noStroke(long graphicsId) { + processing_no_stroke(graphicsId); + checkError(); + } + + // ── Stroke style ──────────────────────────────────────────────────── + + public static final byte STROKE_CAP_ROUND = 0; + public static final byte STROKE_CAP_SQUARE = 1; + public static final byte STROKE_CAP_PROJECT = 2; + + public static final byte STROKE_JOIN_ROUND = 0; + public static final byte STROKE_JOIN_MITER = 1; + public static final byte STROKE_JOIN_BEVEL = 2; + + public static void setStrokeCap(long graphicsId, byte cap) { + processing_set_stroke_cap(graphicsId, cap); checkError(); } - /** - * Set the stroke color. - */ - public static void setStrokeColor(long surfaceId, float r, float g, float b, float a) { - processing_set_stroke_color(surfaceId, r, g, b, a); + public static void setStrokeJoin(long graphicsId, byte join) { + processing_set_stroke_join(graphicsId, join); checkError(); } - /** - * Set the stroke weight. - */ - public static void setStrokeWeight(long surfaceId, float weight) { - processing_set_stroke_weight(surfaceId, weight); + // ── Shape modes ───────────────────────────────────────────────────── + + public static void rectMode(long graphicsId, byte mode) { + processing_rect_mode(graphicsId, mode); checkError(); } - /** - * Disable fill for subsequent shapes. - */ - public static void noFill(long surfaceId) { - processing_no_fill(surfaceId); + public static void ellipseMode(long graphicsId, byte mode) { + processing_ellipse_mode(graphicsId, mode); checkError(); } - /** - * Disable stroke for subsequent shapes. - */ - public static void noStroke(long surfaceId) { - processing_no_stroke(surfaceId); + // ── Blend modes ───────────────────────────────────────────────────── + + public static final byte BLEND_MODE_BLEND = 0; + public static final byte BLEND_MODE_ADD = 1; + public static final byte BLEND_MODE_SUBTRACT = 2; + public static final byte BLEND_MODE_DARKEST = 3; + public static final byte BLEND_MODE_LIGHTEST = 4; + public static final byte BLEND_MODE_DIFFERENCE = 5; + public static final byte BLEND_MODE_EXCLUSION = 6; + public static final byte BLEND_MODE_MULTIPLY = 7; + public static final byte BLEND_MODE_SCREEN = 8; + public static final byte BLEND_MODE_REPLACE = 9; + + public static void setBlendMode(long graphicsId, byte mode) { + processing_set_blend_mode(graphicsId, mode); checkError(); } - /** - * Draw a rectangle. - */ - public static void rect(long surfaceId, float x, float y, float w, float h, + // ── 2D drawing matrix ─────────────────────────────────────────────── + + public static void pushMatrix(long graphicsId) { + processing_push_matrix(graphicsId); + checkError(); + } + + public static void popMatrix(long graphicsId) { + processing_pop_matrix(graphicsId); + checkError(); + } + + public static void resetMatrix(long graphicsId) { + processing_reset_matrix(graphicsId); + checkError(); + } + + public static void translate(long graphicsId, float x, float y) { + processing_translate(graphicsId, x, y); + checkError(); + } + + public static void rotate(long graphicsId, float angle) { + processing_rotate(graphicsId, angle); + checkError(); + } + + public static void scale(long graphicsId, float x, float y) { + processing_scale(graphicsId, x, y); + checkError(); + } + + public static void shearX(long graphicsId, float angle) { + processing_shear_x(graphicsId, angle); + checkError(); + } + + public static void shearY(long graphicsId, float angle) { + processing_shear_y(graphicsId, angle); + checkError(); + } + + // ── 2D primitives ─────────────────────────────────────────────────── + + public static void rect(long graphicsId, float x, float y, float w, float h, float tl, float tr, float br, float bl) { - processing_rect(surfaceId, x, y, w, h, tl, tr, br, bl); + processing_rect(graphicsId, x, y, w, h, tl, tr, br, bl); + checkError(); + } + + public static void ellipse(long graphicsId, float cx, float cy, float w, float h) { + processing_ellipse(graphicsId, cx, cy, w, h); + checkError(); + } + + public static void circle(long graphicsId, float cx, float cy, float d) { + processing_circle(graphicsId, cx, cy, d); + checkError(); + } + + public static void line(long graphicsId, float x1, float y1, float x2, float y2) { + processing_line(graphicsId, x1, y1, x2, y2); + checkError(); + } + + public static void triangle(long graphicsId, float x1, float y1, float x2, float y2, + float x3, float y3) { + processing_triangle(graphicsId, x1, y1, x2, y2, x3, y3); + checkError(); + } + + public static void quad(long graphicsId, float x1, float y1, float x2, float y2, + float x3, float y3, float x4, float y4) { + processing_quad(graphicsId, x1, y1, x2, y2, x3, y3, x4, y4); + checkError(); + } + + public static void point(long graphicsId, float x, float y) { + processing_point(graphicsId, x, y); + checkError(); + } + + public static void square(long graphicsId, float x, float y, float s) { + processing_square(graphicsId, x, y, s); + checkError(); + } + + public static void arc(long graphicsId, float cx, float cy, float w, float h, + float start, float stop, byte mode) { + processing_arc(graphicsId, cx, cy, w, h, start, stop, mode); + checkError(); + } + + public static void bezier(long graphicsId, float x1, float y1, float x2, float y2, + float x3, float y3, float x4, float y4) { + processing_bezier(graphicsId, x1, y1, x2, y2, x3, y3, x4, y4); + checkError(); + } + + public static void curve(long graphicsId, float x1, float y1, float x2, float y2, + float x3, float y3, float x4, float y4) { + processing_curve(graphicsId, x1, y1, x2, y2, x3, y3, x4, y4); + checkError(); + } + + // ── 3D primitives ─────────────────────────────────────────────────── + + public static void cylinder(long graphicsId, float radius, float height, int detail) { + processing_cylinder(graphicsId, radius, height, detail); + checkError(); + } + + public static void cone(long graphicsId, float radius, float height, int detail) { + processing_cone(graphicsId, radius, height, detail); + checkError(); + } + + public static void torus(long graphicsId, float radius, float tubeRadius, int majorSegments, int minorSegments) { + processing_torus(graphicsId, radius, tubeRadius, majorSegments, minorSegments); + checkError(); + } + + public static void plane(long graphicsId, float width, float height) { + processing_plane(graphicsId, width, height); + checkError(); + } + + public static void capsule(long graphicsId, float radius, float length, int detail) { + processing_capsule(graphicsId, radius, length, detail); + checkError(); + } + + public static void conicalFrustum(long graphicsId, float radiusTop, float radiusBottom, float height, int detail) { + processing_conical_frustum(graphicsId, radiusTop, radiusBottom, height, detail); + checkError(); + } + + public static void tetrahedron(long graphicsId, float radius) { + processing_tetrahedron(graphicsId, radius); checkError(); } - /** - * Push the current transformation matrix onto the stack. - */ - public static void pushMatrix(long surfaceId) { - processing_push_matrix(surfaceId); + // ── Vertex shapes ─────────────────────────────────────────────────── + + public static void beginShape(long graphicsId, byte kind) { + processing_begin_shape(graphicsId, kind); + checkError(); + } + + public static void endShape(long graphicsId, boolean close) { + processing_end_shape(graphicsId, close); + checkError(); + } + + public static void shapeVertex(long graphicsId, float x, float y) { + processing_vertex(graphicsId, x, y); + checkError(); + } + + public static void bezierVertex(long graphicsId, float cx1, float cy1, float cx2, float cy2, float x, float y) { + processing_bezier_vertex(graphicsId, cx1, cy1, cx2, cy2, x, y); + checkError(); + } + + public static void quadraticVertex(long graphicsId, float cx, float cy, float x, float y) { + processing_quadratic_vertex(graphicsId, cx, cy, x, y); + checkError(); + } + + public static void curveVertex(long graphicsId, float x, float y) { + processing_curve_vertex(graphicsId, x, y); + checkError(); + } + + public static void beginContour(long graphicsId) { + processing_begin_contour(graphicsId); + checkError(); + } + + public static void endContour(long graphicsId) { + processing_end_contour(graphicsId); + checkError(); + } + + // ── 3D mode / projection ──────────────────────────────────────────── + + public static void mode3d(long graphicsId) { + processing_mode_3d(graphicsId); + checkError(); + } + + public static void mode2d(long graphicsId) { + processing_mode_2d(graphicsId); + checkError(); + } + + public static void perspective(long graphicsId, float fov, float aspect, float near, float far) { + processing_perspective(graphicsId, fov, aspect, near, far); + checkError(); + } + + public static void ortho(long graphicsId, float left, float right, float bottom, float top, float near, float far) { + processing_ortho(graphicsId, left, right, bottom, top, near, far); + checkError(); + } + + // ── Entity transforms (3D objects: lights, geometry, etc.) ────────── + + public static void transformSetPosition(long entityId, float x, float y, float z) { + processing_transform_set_position(entityId, x, y, z); checkError(); } - /** - * Pop the transformation matrix from the stack. - */ - public static void popMatrix(long surfaceId) { - processing_pop_matrix(surfaceId); + public static void transformTranslate(long entityId, float x, float y, float z) { + processing_transform_translate(entityId, x, y, z); checkError(); } - /** - * Reset the transformation matrix to identity. - */ - public static void resetMatrix(long surfaceId) { - processing_reset_matrix(surfaceId); + public static void transformSetRotation(long entityId, float x, float y, float z) { + processing_transform_set_rotation(entityId, x, y, z); checkError(); } - /** - * Translate the coordinate system. - */ - public static void translate(long surfaceId, float x, float y) { - processing_translate(surfaceId, x, y); + public static void transformRotateX(long entityId, float angle) { + processing_transform_rotate_x(entityId, angle); checkError(); } - /** - * Rotate around the X axis. - */ - public static void rotateX(long surfaceId, float angle) { - processing_rotate_x(surfaceId, angle); + public static void transformRotateY(long entityId, float angle) { + processing_transform_rotate_y(entityId, angle); checkError(); } - /** - * Rotate around the Y axis. - */ - public static void rotateY(long surfaceId, float angle) { - processing_rotate_y(surfaceId, angle); + public static void transformRotateZ(long entityId, float angle) { + processing_transform_rotate_z(entityId, angle); checkError(); } - /** - * Rotate around the Z axis. - */ - public static void rotateZ(long surfaceId, float angle) { - processing_rotate_z(surfaceId, angle); + public static void transformRotateAxis(long entityId, float angle, float axisX, float axisY, float axisZ) { + processing_transform_rotate_axis(entityId, angle, axisX, axisY, axisZ); checkError(); } - /** - * Rotate the coordinate system. - */ - public static void rotate(long surfaceId, float angle) { - rotateZ(surfaceId, angle); + public static void transformSetScale(long entityId, float x, float y, float z) { + processing_transform_set_scale(entityId, x, y, z); + checkError(); } - /** - * Scale the coordinate system. - */ - public static void scale(long surfaceId, float x, float y) { - processing_scale(surfaceId, x, y); + public static void transformScale(long entityId, float x, float y, float z) { + processing_transform_scale(entityId, x, y, z); checkError(); } - /** - * Shear along the X axis. - */ - public static void shearX(long surfaceId, float angle) { - processing_shear_x(surfaceId, angle); + public static void transformLookAt(long entityId, float targetX, float targetY, float targetZ) { + processing_transform_look_at(entityId, targetX, targetY, targetZ); checkError(); } - /** - * Shear along the Y axis. - */ - public static void shearY(long surfaceId, float angle) { - processing_shear_y(surfaceId, angle); + public static void transformReset(long entityId) { + processing_transform_reset(entityId); checkError(); } - /** - * Create an image from raw pixel data. - * - * @param width Image width in pixels - * @param height Image height in pixels - * @param data RGBA pixel data (4 bytes per pixel) - * @return Image ID for subsequent operations, or 0 on failure - */ + // ── Lights ────────────────────────────────────────────────────────── + + public static long lightCreateDirectional(long graphicsId, float r, float g, float b, float a, float illuminance) { + try (Arena arena = Arena.ofConfined()) { + MemorySegment color = allocateColor(arena, r, g, b, a); + long id = processing_light_create_directional(graphicsId, color, illuminance); + checkError(); + return id; + } + } + + public static long lightCreatePoint(long graphicsId, float r, float g, float b, float a, + float intensity, float range, float radius) { + try (Arena arena = Arena.ofConfined()) { + MemorySegment color = allocateColor(arena, r, g, b, a); + long id = processing_light_create_point(graphicsId, color, intensity, range, radius); + checkError(); + return id; + } + } + + public static long lightCreateSpot(long graphicsId, float r, float g, float b, float a, + float intensity, float range, float radius, + float innerAngle, float outerAngle) { + try (Arena arena = Arena.ofConfined()) { + MemorySegment color = allocateColor(arena, r, g, b, a); + long id = processing_light_create_spot(graphicsId, color, intensity, range, radius, innerAngle, outerAngle); + checkError(); + return id; + } + } + + // ── Materials ─────────────────────────────────────────────────────── + + public static long materialCreatePbr() { + long id = processing_material_create_pbr(); + checkError(); + return id; + } + + public static void materialSetFloat(long matId, String name, float value) { + try (Arena arena = Arena.ofConfined()) { + MemorySegment nameSegment = arena.allocateFrom(name); + processing_material_set_float(matId, nameSegment, value); + checkError(); + } + } + + public static void materialSetFloat4(long matId, String name, float r, float g, float b, float a) { + try (Arena arena = Arena.ofConfined()) { + MemorySegment nameSegment = arena.allocateFrom(name); + processing_material_set_float4(matId, nameSegment, r, g, b, a); + checkError(); + } + } + + public static void materialDestroy(long matId) { + processing_material_destroy(matId); + checkError(); + } + + public static void material(long graphicsId, long matId) { + processing_material(graphicsId, matId); + checkError(); + } + + // ── Images ────────────────────────────────────────────────────────── + public static long imageCreate(int width, int height, byte[] data) { try (Arena arena = Arena.ofConfined()) { MemorySegment dataSegment = arena.allocateFrom(java.lang.foreign.ValueLayout.JAVA_BYTE, data); @@ -277,12 +526,6 @@ public static long imageCreate(int width, int height, byte[] data) { } } - /** - * Load an image from a file path. - * - * @param path Path to the image file - * @return Image ID for subsequent operations, or 0 on failure - */ public static long imageLoad(String path) { try (Arena arena = Arena.ofConfined()) { MemorySegment pathSegment = arena.allocateFrom(path); @@ -292,24 +535,11 @@ public static long imageLoad(String path) { } } - /** - * Resize an image. - * - * @param imageId The image ID returned from imageCreate or imageLoad - * @param newWidth New width in pixels - * @param newHeight New height in pixels - */ public static void imageResize(long imageId, int newWidth, int newHeight) { processing_image_resize(imageId, newWidth, newHeight); checkError(); } - /** - * Read back pixel data from an image into a buffer. - * - * @param imageId The image ID returned from imageCreate or imageLoad - * @param buffer Buffer to receive Color data (must be width * height elements) - */ public static void imageReadback(long imageId, float[] buffer) { try (Arena arena = Arena.ofConfined()) { int numPixels = buffer.length / 4; @@ -319,81 +549,127 @@ public static void imageReadback(long imageId, float[] buffer) { for (int i = 0; i < numPixels; i++) { MemorySegment color = Color.asSlice(colorBuffer, i); - buffer[i * 4] = Color.r(color); - buffer[i * 4 + 1] = Color.g(color); - buffer[i * 4 + 2] = Color.b(color); + buffer[i * 4] = Color.c1(color); + buffer[i * 4 + 1] = Color.c2(color); + buffer[i * 4 + 2] = Color.c3(color); buffer[i * 4 + 3] = Color.a(color); } } } - /** - * Set the background to an image. - * - * @param surfaceId The surface ID - * @param imageId The image ID to use as background - */ - public static void backgroundImage(long surfaceId, long imageId) { - processing_background_image(surfaceId, imageId); + // ── Input: event ingestion (called by PSurfaceGLFW) ───────────────── + + public static void inputMouseMove(long surfaceId, float x, float y) { + processing_input_mouse_move(surfaceId, x, y); + checkError(); + } + + public static void inputMouseButton(long surfaceId, byte button, boolean pressed) { + processing_input_mouse_button(surfaceId, button, pressed); + checkError(); + } + + public static void inputScroll(long surfaceId, float x, float y) { + processing_input_scroll(surfaceId, x, y); checkError(); } - /** - * Switch to 3D rendering mode. - */ - public static void mode3d(long surfaceId) { - processing_mode_3d(surfaceId); + public static void inputKey(long surfaceId, int keyCode, boolean pressed) { + processing_input_key(surfaceId, keyCode, pressed); checkError(); } - /** - * Switch to 2D rendering mode. - */ - public static void mode2d(long surfaceId) { - processing_mode_2d(surfaceId); + public static void inputChar(long surfaceId, int keyCode, int codepoint) { + processing_input_char(surfaceId, keyCode, codepoint); checkError(); } - /** - * Set the camera position. - */ - public static void cameraPosition(long surfaceId, float x, float y, float z) { - processing_camera_position(surfaceId, x, y, z); + public static void inputCursorEnter(long surfaceId) { + processing_input_cursor_enter(surfaceId); checkError(); } - /** - * Set where the camera is looking at. - */ - public static void cameraLookAt(long surfaceId, float targetX, float targetY, float targetZ) { - processing_camera_look_at(surfaceId, targetX, targetY, targetZ); + public static void inputCursorLeave(long surfaceId) { + processing_input_cursor_leave(surfaceId); checkError(); } - /** - * Set perspective projection. - */ - public static void perspective(long surfaceId, float fov, float aspect, float near, float far) { - processing_perspective(surfaceId, fov, aspect, near, far); + public static void inputFocus(long surfaceId, boolean focused) { + processing_input_focus(surfaceId, focused); checkError(); } - /** - * Set orthographic projection. - */ - public static void ortho(long surfaceId, float left, float right, float bottom, float top, float near, float far) { - processing_ortho(surfaceId, left, right, bottom, top, near, far); + public static void inputFlush() { + processing_input_flush(); checkError(); } - /** Topology constants */ + // ── Input: state queries ──────────────────────────────────────────── + + public static float mouseX(long surfaceId) { + return processing_mouse_x(surfaceId); + } + + public static float mouseY(long surfaceId) { + return processing_mouse_y(surfaceId); + } + + public static float pmouseX(long surfaceId) { + return processing_pmouse_x(surfaceId); + } + + public static float pmouseY(long surfaceId) { + return processing_pmouse_y(surfaceId); + } + + public static boolean mouseIsPressed() { + return processing_mouse_is_pressed(); + } + + public static byte mouseButton() { + return processing_mouse_button(); + } + + public static boolean keyIsPressed() { + return processing_key_is_pressed(); + } + + public static boolean keyIsDown(int keyCode) { + return processing_key_is_down(keyCode); + } + + public static boolean keyJustPressed(int keyCode) { + return processing_key_just_pressed(keyCode); + } + + public static int key() { + return processing_key(); + } + + public static int keyCode() { + return processing_key_code(); + } + + public static float movedX() { + return processing_moved_x(); + } + + public static float movedY() { + return processing_moved_y(); + } + + public static float mouseWheel() { + return processing_mouse_wheel(); + } + + // ── Geometry ──────────────────────────────────────────────────────── + public static final byte TOPOLOGY_POINT_LIST = 0; public static final byte TOPOLOGY_LINE_LIST = 1; public static final byte TOPOLOGY_LINE_STRIP = 2; public static final byte TOPOLOGY_TRIANGLE_LIST = 3; public static final byte TOPOLOGY_TRIANGLE_STRIP = 4; - /** Attribute format constants */ public static final byte ATTR_FORMAT_FLOAT = 1; public static final byte ATTR_FORMAT_FLOAT2 = 2; public static final byte ATTR_FORMAT_FLOAT3 = 3; @@ -453,6 +729,12 @@ public static long geometryBox(float width, float height, float depth) { return geoId; } + public static long geometrySphere(float radius, int sectors, int stacks) { + long geoId = processing_geometry_sphere(radius, sectors, stacks); + checkError(); + return geoId; + } + public static void geometryDestroy(long geoId) { processing_geometry_destroy(geoId); checkError(); @@ -565,14 +847,23 @@ public static void geometrySetUv(long geoId, int index, float u, float v) { checkError(); } - public static void model(long surfaceId, long geoId) { - processing_model(surfaceId, geoId); + public static void model(long graphicsId, long geoId) { + processing_model(graphicsId, geoId); checkError(); } - /** - * Checks for errors from the native library and throws a PWebGPUException if an error occurred. - */ + // ── Helpers ────────────────────────────────────────────────────────── + + private static MemorySegment allocateColor(Arena arena, float r, float g, float b, float a) { + MemorySegment color = Color.allocate(arena); + Color.c1(color, r); + Color.c2(color, g); + Color.c3(color, b); + Color.a(color, a); + Color.space(color, COLOR_SPACE_SRGB); + return color; + } + private static void checkError() { MemorySegment ret = processing_check_error(); if (ret.equals(NULL)) { diff --git a/libprocessing b/libprocessing index f39d1ba1e..a9f077459 160000 --- a/libprocessing +++ b/libprocessing @@ -1 +1 @@ -Subproject commit f39d1ba1e042f4353e87cb3c37cada711d60e924 +Subproject commit a9f0774597a81afe2cfccac07c99f81eada253e6 From 67ac86458afd40f16926d4aa42a931bd30fb61f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?charlotte=20=F0=9F=8C=B8?= Date: Sat, 2 May 2026 17:02:07 -0700 Subject: [PATCH 23/26] Fixes for compat with main 17. --- app/build.gradle.kts | 24 +++++++++---- build.gradle.kts | 22 ++++++++---- core/build.gradle.kts | 36 ++++++++++--------- core/src/processing/webgpu/PSurfaceGLFW.java | 6 ++-- .../main/kotlin/ProcessingLibraryPlugin.kt | 3 +- gradle/plugins/settings.gradle.kts | 2 +- java/src/processing/mode/java/JavaBuild.java | 6 ++++ .../processing/mode/java/PreprocService.java | 2 +- .../processing/mode/java/runner/Runner.java | 5 +-- 9 files changed, 68 insertions(+), 38 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 56e22e0fc..4eeaafa05 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -5,7 +5,9 @@ import org.jetbrains.compose.ExperimentalComposeLibrary import org.jetbrains.compose.desktop.application.dsl.TargetFormat import org.jetbrains.compose.desktop.application.tasks.AbstractJPackageTask import org.jetbrains.compose.internal.de.undercouch.gradle.tasks.download.Download -import processing.gradle.SignResourcesTask +import java.io.FileOutputStream +import java.util.zip.ZipEntry +import java.util.zip.ZipOutputStream // TODO: Update to 2.10.20 and add hot-reloading: https://github.com/JetBrains/compose-hot-reload @@ -433,8 +435,15 @@ tasks.register("includeJavaMode") { duplicatesStrategy = DuplicatesStrategy.EXCLUDE dirPermissions { unix("rwx------") } } +val enableWebGPU = findProperty("enableWebGPU")?.toString()?.toBoolean() ?: false + tasks.register("includeJdk") { - from(Jvm.current().javaHome.absolutePath) + val jdkVersion = if (enableWebGPU) 24 else 17 + val jdkHome = project.the().launcherFor { + languageVersion.set(JavaLanguageVersion.of(jdkVersion)) + }.map { it.metadata.installationPath.asFile } + + from(jdkHome) destinationDir = composeResources("jdk").get().asFile fileTree(destinationDir).files.forEach { file -> @@ -517,7 +526,7 @@ tasks.register("includeProcessingResources"){ finalizedBy("signResources") } -tasks.register("signResources") { +tasks.register("signResources") { onlyIf { OperatingSystem.current().isMacOsX && @@ -562,10 +571,11 @@ tasks.register("signResources") { exclude("*.jar") exclude("*.so") exclude("*.dll") - }.forEach{ file -> - exec { - commandLine("codesign", "--timestamp", "--force", "--deep","--options=runtime", "--sign", "Developer ID Application", file) - } + }.forEach{ f -> + ProcessBuilder("codesign", "--timestamp", "--force", "--deep", "--options=runtime", "--sign", "Developer ID Application", f.absolutePath) + .inheritIO() + .start() + .waitFor() } jars.forEach { file -> FileOutputStream(File(file.parentFile, file.nameWithoutExtension)).use { fos -> diff --git a/build.gradle.kts b/build.gradle.kts index c93745c1a..4ed046a24 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -12,23 +12,31 @@ plugins { // Can be deleted after the migration to Gradle is complete layout.buildDirectory = file(".build") -val enableWebGPU = findProperty("enableWebGPU")?.toString()?.toBoolean() ?: true +val enableWebGPU = findProperty("enableWebGPU")?.toString()?.toBoolean() ?: false +val javaVersion = if (enableWebGPU) "24" else "17" +val kotlinJvmTarget = if (enableWebGPU) { + org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_24 +} else { + org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17 +} allprojects { tasks.withType().configureEach { - val javaVersion = if (enableWebGPU) "24" else "17" sourceCompatibility = javaVersion targetCompatibility = javaVersion } tasks.withType().configureEach { compilerOptions { - val kotlinTarget = if (enableWebGPU) { - org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_24 - } else { - org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17 + jvmTarget.set(kotlinJvmTarget) + } + } + + plugins.withType { + extensions.configure { + toolchain { + languageVersion.set(JavaLanguageVersion.of(javaVersion.toInt())) } - jvmTarget.set(kotlinTarget) } } } diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 0767e9560..4a97dde41 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -12,7 +12,7 @@ repositories { maven { url = uri("https://jogamp.org/deployment/maven") } } -val enableWebGPU = findProperty("enableWebGPU")?.toString()?.toBoolean() ?: true +val enableWebGPU = findProperty("enableWebGPU")?.toString()?.toBoolean() ?: false sourceSets{ main{ @@ -40,25 +40,27 @@ dependencies { implementation(libs.jogl) implementation(libs.gluegen) - val lwjglVersion = "3.3.6" - val lwjglNatives = when { - System.getProperty("os.name").lowercase().contains("mac") -> { - if (System.getProperty("os.arch").contains("aarch64")) { - "natives-macos-arm64" - } else { - "natives-macos" + if (enableWebGPU) { + val lwjglVersion = "3.3.6" + val lwjglNatives = when { + System.getProperty("os.name").lowercase().contains("mac") -> { + if (System.getProperty("os.arch").contains("aarch64")) { + "natives-macos-arm64" + } else { + "natives-macos" + } } + System.getProperty("os.name").lowercase().contains("win") -> "natives-windows" + System.getProperty("os.name").lowercase().contains("linux") -> "natives-linux" + else -> "natives-linux" } - System.getProperty("os.name").lowercase().contains("win") -> "natives-windows" - System.getProperty("os.name").lowercase().contains("linux") -> "natives-linux" - else -> "natives-linux" - } - implementation(platform("org.lwjgl:lwjgl-bom:$lwjglVersion")) - implementation("org.lwjgl", "lwjgl") - implementation("org.lwjgl", "lwjgl-glfw") - runtimeOnly("org.lwjgl", "lwjgl", classifier = lwjglNatives) - runtimeOnly("org.lwjgl", "lwjgl-glfw", classifier = lwjglNatives) + implementation(platform("org.lwjgl:lwjgl-bom:$lwjglVersion")) + implementation("org.lwjgl", "lwjgl") + implementation("org.lwjgl", "lwjgl-glfw") + runtimeOnly("org.lwjgl", "lwjgl", classifier = lwjglNatives) + runtimeOnly("org.lwjgl", "lwjgl-glfw", classifier = lwjglNatives) + } testImplementation(libs.junit) } diff --git a/core/src/processing/webgpu/PSurfaceGLFW.java b/core/src/processing/webgpu/PSurfaceGLFW.java index 110955559..49cecdb63 100644 --- a/core/src/processing/webgpu/PSurfaceGLFW.java +++ b/core/src/processing/webgpu/PSurfaceGLFW.java @@ -394,7 +394,7 @@ protected void runDrawLoop() { sketch.start(); - while (running && !sketch.finished) { + while (running) { checkPause(); GLFW.glfwPollEvents(); @@ -405,7 +405,9 @@ protected void runDrawLoop() { break; } - sketch.handleDraw(); + if (!sketch.finished) { + sketch.handleDraw(); + } long afterTime = System.nanoTime(); long timeDiff = afterTime - beforeTime; diff --git a/gradle/plugins/library/src/main/kotlin/ProcessingLibraryPlugin.kt b/gradle/plugins/library/src/main/kotlin/ProcessingLibraryPlugin.kt index 4514f581f..d1df93f75 100644 --- a/gradle/plugins/library/src/main/kotlin/ProcessingLibraryPlugin.kt +++ b/gradle/plugins/library/src/main/kotlin/ProcessingLibraryPlugin.kt @@ -36,8 +36,9 @@ class ProcessingLibraryPlugin : Plugin { target.dependencies.add("compileOnly", "org.processing:core:$processingVersion") } } + val javaVersionOverride = target.findProperty("enableWebGPU")?.toString()?.toBoolean()?.let { if (it) 24 else 17 } ?: 17 target.extensions.configure(JavaPluginExtension::class.java) { extension -> - extension.toolchain.languageVersion.set(JavaLanguageVersion.of(17)) + extension.toolchain.languageVersion.set(JavaLanguageVersion.of(javaVersionOverride)) } target.plugins.withType(JavaPlugin::class.java) { diff --git a/gradle/plugins/settings.gradle.kts b/gradle/plugins/settings.gradle.kts index ab39f6aca..dc4f98668 100644 --- a/gradle/plugins/settings.gradle.kts +++ b/gradle/plugins/settings.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0" + id("org.gradle.toolchains.foojay-resolver-convention") version "1.0.0" } include("library") \ No newline at end of file diff --git a/java/src/processing/mode/java/JavaBuild.java b/java/src/processing/mode/java/JavaBuild.java index b696ab0e2..af802c66f 100644 --- a/java/src/processing/mode/java/JavaBuild.java +++ b/java/src/processing/mode/java/JavaBuild.java @@ -66,6 +66,7 @@ public class JavaBuild { private boolean foundMain = false; private String classPath; protected String sketchClassName; + protected String sketchRenderer; /** * This will include the code folder, any library folders, etc. that might @@ -118,6 +119,7 @@ public String build(File srcFolder, File binFolder, boolean sizeWarning) throws // that will bubble up to whomever called build(). if (Compiler.compile(this)) { sketchClassName = classNameFound; + sketchRenderer = result.getSketchRenderer(); return classNameFound; } return null; @@ -128,6 +130,10 @@ public String getSketchClassName() { return sketchClassName; } + public String getSketchRenderer() { + return sketchRenderer; + } + /** * Build all the code for this sketch. diff --git a/java/src/processing/mode/java/PreprocService.java b/java/src/processing/mode/java/PreprocService.java index 410cff02f..a8a4a0c1c 100644 --- a/java/src/processing/mode/java/PreprocService.java +++ b/java/src/processing/mode/java/PreprocService.java @@ -667,7 +667,7 @@ private void setupParser(boolean resolveBindings, String className, if (resolveBindings) { parser.setUnitName(className); - parser.setEnvironment(classPathArray, null, null, false); + parser.setEnvironment(classPathArray, null, null, true); parser.setResolveBindings(true); } } diff --git a/java/src/processing/mode/java/runner/Runner.java b/java/src/processing/mode/java/runner/Runner.java index de8ef2857..d0bded04d 100644 --- a/java/src/processing/mode/java/runner/Runner.java +++ b/java/src/processing/mode/java/runner/Runner.java @@ -343,8 +343,9 @@ protected StringList getMachineParams() { //params.append("-Dcom.apple.mrj.application.apple.menu.about.name=" + // build.getSketchClassName()); - // required for GLFW and Metal when using WebGPU - params.append("-XstartOnFirstThread"); + if ("WEBGPU".equals(build.getSketchRenderer())) { + params.append("-XstartOnFirstThread"); + } } /* if (Platform.isWindows()) { From 079b8799455057d91768481ec5b626e0470addad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?charlotte=20=F0=9F=8C=B8?= Date: Sat, 2 May 2026 17:04:41 -0700 Subject: [PATCH 24/26] Fixup docs. --- BUILD.md | 47 +++++++++++++++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/BUILD.md b/BUILD.md index b893b3844..68dbe1f51 100644 --- a/BUILD.md +++ b/BUILD.md @@ -12,9 +12,9 @@ First, [download the IntelliJ IDEA Community Edition](https://www.jetbrains.com/ 1. Clone the Processing4 repository to your machine locally 1. Open the cloned repository in IntelliJ IDEA CE 1. When prompted, select **Trust Project**. You can preview the project in Safe Mode but you won't be able to build Processing. -1. IntelliJ may ask if you want to load Gradle project. If you allow this, make sure you are using JDK version 25. +1. IntelliJ may ask if you want to load Gradle project. If you allow this, make sure you are using JDK version 17. 1. In the main menu, go to File > Project Structure > Project Settings > Project. -1. In the SDK Dropdown option, select a JDK version 25 or Download the jdk +1. In the SDK Dropdown option, select a JDK version 17 or Download the jdk 1. Click the green Run Icon in the top right of the window. This is also where you can find the option to debug Processing. 1. Logs can be found in the `Build` or `Debug` pane on the bottom left of the window @@ -46,43 +46,58 @@ If you don't have them installed, you will need to install [Git](https://git-scm cd processing4 ``` -2. **Install Temurin JDK 25:** +2. **Install Temurin JDK 17:** Processing requires the Temurin distribution of OpenJDK. -You can download it from [Adoptium](https://adoptium.net/), from [GitHub releases](https://github.com/adoptium/temurin25-binaries/releases), +You can download it from [Adoptium](https://adoptium.net/), from [GitHub releases](https://github.com/adoptium/temurin17-binaries/releases), or find it in the package manager for your platform. ### macOS: ```bash -brew install --cask temurin@25 +brew install --cask temurin@17 ```` ### Windows (using winget): ```bash -winget install --id=EclipseAdoptium.Temurin.25.JDK -e +winget install --id=EclipseAdoptium.Temurin.17.JDK -e ``` ### SDKMAN! [SDKMAN!](https://sdkman.io/) is a useful tool for developers working on multiple versions of the JVM. -## Install `jextract` +## WebGPU Support (Optional) -`jextract` is a tool included in the JDK that generates Java bindings from C header files. -It is required to build Processing when using WebGPU. You can download it [here](https://jdk.java.net/jextract/) -or install it using SDKMAN!: +To build Processing with the experimental WebGPU renderer, you need JDK 24+, Rust, and jextract. + +### Install Temurin JDK 24 + +```bash +brew install --cask temurin@24 # macOS +``` + +### Install `jextract` + +`jextract` generates Java bindings from C header files. +You can download it [here](https://jdk.java.net/jextract/) or install it using SDKMAN!: ```bash sdk install jextract ```` +### Build with WebGPU + +```bash +./gradlew build -PenableWebGPU=true +``` + 3. **Set the `JAVA_HOME` environment variable:** -It may be necessary to set the `JAVA_HOME` environment variable to point to your Temurin JDK 25 installation. +It may be necessary to set the `JAVA_HOME` environment variable to point to your Temurin JDK installation. ```bash - export JAVA_HOME=/path/to/temurin/jdk-25/ + export JAVA_HOME=/path/to/temurin/jdk-17/ ``` ### Build, Run, and Package Processing @@ -161,18 +176,18 @@ If you are specifically trying to run the `Processing CLI`, you can test command If you’re building Processing using IntelliJ IDEA and something’s not working, here are a few things that might help: -### Use the Correct JDK (temurin-25) +### Use the Correct JDK (temurin-17) -Make sure IntelliJ is using **temurin-25**, not another version. +Make sure IntelliJ is using **temurin-17**, not another version. If building with WebGPU (`-PenableWebGPU=true`), use **temurin-24** instead. 1. Go to **File > Project Structure > Project** -2. Set the **Project SDK** to: `temurin-25"` +2. Set the **Project SDK** to: `temurin-17` ![JDK Selection](.github/media/troubleshooting-Intellij-setting-djk-version-manually.png) If it is not already installed, you can download it by: 1. Clicking the SDK input field and then selecting the `Download JDK...` option from the menu -2. Select Version: `25`, Vendor: `Eclipse Temurin (AdoptOpenJDK HotSpot)` +2. Select Version: `17`, Vendor: `Eclipse Temurin (AdoptOpenJDK HotSpot)` ![JDK Download](.github/media/troubleshooting-Intellij-download-jdk.png) From 601af336491f739b36011547e701a841c444084b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?charlotte=20=F0=9F=8C=B8?= Date: Sun, 3 May 2026 10:26:16 -0700 Subject: [PATCH 25/26] Upgrade to jdk-25. --- BUILD.md | 8 ++++---- app/build.gradle.kts | 2 +- gradle/libs.versions.toml | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/BUILD.md b/BUILD.md index 68dbe1f51..7b1fc792c 100644 --- a/BUILD.md +++ b/BUILD.md @@ -69,12 +69,12 @@ winget install --id=EclipseAdoptium.Temurin.17.JDK -e ## WebGPU Support (Optional) -To build Processing with the experimental WebGPU renderer, you need JDK 24+, Rust, and jextract. +To build Processing with the experimental WebGPU renderer, you need JDK 25, Rust, and jextract. -### Install Temurin JDK 24 +### Install Temurin JDK 25 ```bash -brew install --cask temurin@24 # macOS +brew install --cask temurin@25 # macOS ``` ### Install `jextract` @@ -178,7 +178,7 @@ If you’re building Processing using IntelliJ IDEA and something’s not workin ### Use the Correct JDK (temurin-17) -Make sure IntelliJ is using **temurin-17**, not another version. If building with WebGPU (`-PenableWebGPU=true`), use **temurin-24** instead. +Make sure IntelliJ is using **temurin-17**, not another version. If building with WebGPU (`-PenableWebGPU=true`), use **temurin-25** instead. 1. Go to **File > Project Structure > Project** 2. Set the **Project SDK** to: `temurin-17` diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 4eeaafa05..f19051afa 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -438,7 +438,7 @@ tasks.register("includeJavaMode") { val enableWebGPU = findProperty("enableWebGPU")?.toString()?.toBoolean() ?: false tasks.register("includeJdk") { - val jdkVersion = if (enableWebGPU) 24 else 17 + val jdkVersion = if (enableWebGPU) 25 else 17 val jdkHome = project.the().launcherFor { languageVersion.set(JavaLanguageVersion.of(jdkVersion)) }.map { it.metadata.installationPath.asFile } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 49d41db2a..4455f9204 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,5 +1,5 @@ [versions] -kotlin = "2.2.20" +kotlin = "2.3.21" compose-plugin = "1.9.1" jogl = "2.6.0" antlr = "4.13.2" From 4b3a06a86eff80305ee8d076c1a14013875a4126 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?charlotte=20=F0=9F=8C=B8?= Date: Sun, 3 May 2026 10:26:25 -0700 Subject: [PATCH 26/26] Upgrade to jdk-25. --- build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 4ed046a24..ca163e476 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -13,9 +13,9 @@ plugins { layout.buildDirectory = file(".build") val enableWebGPU = findProperty("enableWebGPU")?.toString()?.toBoolean() ?: false -val javaVersion = if (enableWebGPU) "24" else "17" +val javaVersion = if (enableWebGPU) "25" else "17" val kotlinJvmTarget = if (enableWebGPU) { - org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_24 + org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_25 } else { org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17 }