diff --git a/.gitattributes b/.gitattributes index 0deaf2f3b..1ddf66bc3 100644 --- a/.gitattributes +++ b/.gitattributes @@ -7,6 +7,8 @@ rust/crates/truapi-server/src/wasm/generated_bridge.rs linguist-generated=true ios/truapi-host/Sources/TrUAPIHost/truapi*.swift linguist-generated=true ios/truapi-host/Sources/TrUAPIHost/Resources/truapi-container.js linguist-generated=true ios/truapi-host/Sources/truapi*FFI/include/** linguist-generated=true +ios/truapi-host/Sources/TrUAPIHost/pvm_runtime.swift linguist-generated=true +ios/truapi-host/Sources/pvm_runtimeFFI/include/** linguist-generated=true ios/truapi-provider/Sources/TrUAPIProvider/truapi_provider.swift linguist-generated=true ios/*-provider/Sources/*FFI/include/** linguist-generated=true diff --git a/CLAUDE.md b/CLAUDE.md index d82e81527..d9fa2b81d 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -14,6 +14,8 @@ rust/crates/ truapi-platform/ Host syscall traits (storage, navigation, consent, ...) truapi-provider/ network provider backends (WebSocket RPC or smoldot light-client) truapi-server/ Rust runtime hosts implement; ships as WASM (browser/node) + truapi-pvm-host/ reviewed bridge pinned to paritytech/pvm-host-runtime; + re-exports native APIs and optional browser assets js/packages/ truapi/ @parity/truapi TS package; generated TS lives under ignored paths truapi-host/ @parity/truapi-host: WASM-backed host runtime. Subpath entries: @@ -44,6 +46,11 @@ scripts/truapi-host-installer.sh .github/consumers.json maps each released package to the repos notified by a bump issue ``` +The PolkaVM runtime implementation, GPU wire crate, browser package, and ABI +contract live in `paritytech/pvm-host-runtime`. Changes here update only the +`truapi-pvm-host` bridge pin and host integration; do not copy runtime source or +browser workers back into this repository. + ### Crate + binding invariants - `truapi` is canonical; runtime crates re-export rather than redefine. New diff --git a/Cargo.lock b/Cargo.lock index 5a3f46235..b7369dd28 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -81,7 +81,7 @@ version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -92,7 +92,7 @@ checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" dependencies = [ "anstyle", "once_cell_polyfill", - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -1475,7 +1475,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -2620,6 +2620,12 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +[[package]] +name = "leb128fmt" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" + [[package]] name = "libc" version = "0.2.189" @@ -2857,7 +2863,7 @@ version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -3148,6 +3154,12 @@ version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" +[[package]] +name = "picosimd" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7823ffd00d2b55ebe51750a19f47f2a33cb1f1d135f5cba893379b81c4d44856" + [[package]] name = "pin-project" version = "1.1.13" @@ -3201,6 +3213,78 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" +[[package]] +name = "polkavm" +version = "0.37.0" +source = "git+https://github.com/paritytech/polkavm.git?rev=3df1d0309c4c81a1aad0a755d83570d203bba1d9#3df1d0309c4c81a1aad0a755d83570d203bba1d9" +dependencies = [ + "libc", + "log", + "picosimd", + "polkavm-assembler 0.37.0 (git+https://github.com/paritytech/polkavm.git?rev=3df1d0309c4c81a1aad0a755d83570d203bba1d9)", + "polkavm-common 0.37.0 (git+https://github.com/paritytech/polkavm.git?rev=3df1d0309c4c81a1aad0a755d83570d203bba1d9)", + "polkavm-linux-raw 0.37.0 (git+https://github.com/paritytech/polkavm.git?rev=3df1d0309c4c81a1aad0a755d83570d203bba1d9)", +] + +[[package]] +name = "polkavm" +version = "0.37.0" +source = "git+https://github.com/paritytech/polkavm.git?rev=e06cce9da5c6d3f72458168876ea304e27992094#e06cce9da5c6d3f72458168876ea304e27992094" +dependencies = [ + "libc", + "log", + "picosimd", + "polkavm-assembler 0.37.0 (git+https://github.com/paritytech/polkavm.git?rev=e06cce9da5c6d3f72458168876ea304e27992094)", + "polkavm-common 0.37.0 (git+https://github.com/paritytech/polkavm.git?rev=e06cce9da5c6d3f72458168876ea304e27992094)", + "polkavm-linux-raw 0.37.0 (git+https://github.com/paritytech/polkavm.git?rev=e06cce9da5c6d3f72458168876ea304e27992094)", +] + +[[package]] +name = "polkavm-assembler" +version = "0.37.0" +source = "git+https://github.com/paritytech/polkavm.git?rev=3df1d0309c4c81a1aad0a755d83570d203bba1d9#3df1d0309c4c81a1aad0a755d83570d203bba1d9" +dependencies = [ + "log", +] + +[[package]] +name = "polkavm-assembler" +version = "0.37.0" +source = "git+https://github.com/paritytech/polkavm.git?rev=e06cce9da5c6d3f72458168876ea304e27992094#e06cce9da5c6d3f72458168876ea304e27992094" +dependencies = [ + "log", +] + +[[package]] +name = "polkavm-common" +version = "0.37.0" +source = "git+https://github.com/paritytech/polkavm.git?rev=3df1d0309c4c81a1aad0a755d83570d203bba1d9#3df1d0309c4c81a1aad0a755d83570d203bba1d9" +dependencies = [ + "log", + "picosimd", + "polkavm-assembler 0.37.0 (git+https://github.com/paritytech/polkavm.git?rev=3df1d0309c4c81a1aad0a755d83570d203bba1d9)", +] + +[[package]] +name = "polkavm-common" +version = "0.37.0" +source = "git+https://github.com/paritytech/polkavm.git?rev=e06cce9da5c6d3f72458168876ea304e27992094#e06cce9da5c6d3f72458168876ea304e27992094" +dependencies = [ + "log", + "picosimd", + "polkavm-assembler 0.37.0 (git+https://github.com/paritytech/polkavm.git?rev=e06cce9da5c6d3f72458168876ea304e27992094)", +] + +[[package]] +name = "polkavm-linux-raw" +version = "0.37.0" +source = "git+https://github.com/paritytech/polkavm.git?rev=3df1d0309c4c81a1aad0a755d83570d203bba1d9#3df1d0309c4c81a1aad0a755d83570d203bba1d9" + +[[package]] +name = "polkavm-linux-raw" +version = "0.37.0" +source = "git+https://github.com/paritytech/polkavm.git?rev=e06cce9da5c6d3f72458168876ea304e27992094#e06cce9da5c6d3f72458168876ea304e27992094" + [[package]] name = "polling" version = "3.11.0" @@ -3318,6 +3402,39 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "pvm-gpu-wire" +version = "0.1.6" +source = "git+https://github.com/paritytech/pvm-host-runtime.git?rev=86d4d78e8bdd4a6c8b024d5895607e6a7b19c180#86d4d78e8bdd4a6c8b024d5895607e6a7b19c180" + +[[package]] +name = "pvm-motion-wire" +version = "0.1.6" +source = "git+https://github.com/paritytech/pvm-host-runtime.git?rev=86d4d78e8bdd4a6c8b024d5895607e6a7b19c180#86d4d78e8bdd4a6c8b024d5895607e6a7b19c180" + +[[package]] +name = "pvm-runtime" +version = "0.1.6" +source = "git+https://github.com/paritytech/pvm-host-runtime.git?rev=86d4d78e8bdd4a6c8b024d5895607e6a7b19c180#86d4d78e8bdd4a6c8b024d5895607e6a7b19c180" +dependencies = [ + "anyhow", + "log", + "polkavm 0.37.0 (git+https://github.com/paritytech/polkavm.git?rev=3df1d0309c4c81a1aad0a755d83570d203bba1d9)", + "polkavm 0.37.0 (git+https://github.com/paritytech/polkavm.git?rev=e06cce9da5c6d3f72458168876ea304e27992094)", + "pvm-gpu-wire", + "pvm-motion-wire", + "serde", + "serde_json", + "thiserror 1.0.69", + "uniffi", + "wasm-encoder", +] + +[[package]] +name = "pvm-runtime-assets" +version = "0.1.6" +source = "git+https://github.com/paritytech/pvm-host-runtime.git?rev=86d4d78e8bdd4a6c8b024d5895607e6a7b19c180#86d4d78e8bdd4a6c8b024d5895607e6a7b19c180" + [[package]] name = "qrcode" version = "0.14.1" @@ -3377,7 +3494,7 @@ dependencies = [ "once_cell", "socket2", "tracing", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -3658,7 +3775,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -4408,7 +4525,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3d1e2c7f27f8d4cb10542a02c49005dbd6e93095799d6f3be745fae9f8fedd4" dependencies = [ "libc", - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -4755,7 +4872,7 @@ dependencies = [ "getrandom 0.4.3", "once_cell", "rustix", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -5266,6 +5383,14 @@ dependencies = [ "webpki-roots 0.26.11", ] +[[package]] +name = "truapi-pvm-host" +version = "0.1.0" +dependencies = [ + "pvm-runtime", + "pvm-runtime-assets", +] + [[package]] name = "truapi-server" version = "0.1.0" @@ -5306,6 +5431,7 @@ dependencies = [ "tracing-subscriber", "truapi", "truapi-platform", + "truapi-pvm-host", "unicode-normalization", "uniffi", "url", @@ -5820,6 +5946,16 @@ version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c31d56021e873866c968588ed85ccdf56db5c426e44afdb4618c39895104b920" +[[package]] +name = "wasm-encoder" +version = "0.240.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06d642d8c5ecc083aafe9ceb32809276a304547a3a6eeecceb5d8152598bc71f" +dependencies = [ + "leb128fmt", + "wasmparser 0.240.0", +] + [[package]] name = "wasmi" version = "0.40.0" @@ -5833,7 +5969,7 @@ dependencies = [ "wasmi_collections", "wasmi_core", "wasmi_ir", - "wasmparser", + "wasmparser 0.221.3", ] [[package]] @@ -5870,6 +6006,17 @@ dependencies = [ "bitflags", ] +[[package]] +name = "wasmparser" +version = "0.240.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b722dcf61e0ea47440b53ff83ccb5df8efec57a69d150e4f24882e4eba7e24a4" +dependencies = [ + "bitflags", + "indexmap", + "semver", +] + [[package]] name = "web-sys" version = "0.3.103" @@ -5957,7 +6104,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] diff --git a/Makefile b/Makefile index e4a7687db..47b937cfe 100644 --- a/Makefile +++ b/Makefile @@ -238,9 +238,9 @@ uniffi-kotlin: ## Regenerate Kotlin UniFFI bindings from the truapi-server cdyli --language kotlin \ --out-dir $(UNIFFI_KOTLIN_OUT) -# Android ABIs to cross-compile the cdylib for. arm64 + armv7 cover physical -# devices; x86_64 covers the emulator on Intel/Apple-silicon hosts. -ANDROID_ABIS ?= arm64-v8a armeabi-v7a x86_64 +# Android ABIs supported by both TrUAPI and PolkaVM. arm64 covers physical +# devices; x86_64 covers emulators. PolkaVM does not support 32-bit armv7. +ANDROID_ABIS ?= arm64-v8a x86_64 ANDROID_JNILIBS := android/truapi-host/src/main/jniLibs android-jni: ## Cross-compile libtruapi_server.so for Android ABIs into jniLibs (needs cargo-ndk + NDK). @@ -444,7 +444,8 @@ xcframework: uniffi ## Build truapi_server.xcframework for iOS device + simulato rm -rf $(XCFRAMEWORK_OUT) $(XCFRAMEWORK_HEADERS) mkdir -p $(XCFRAMEWORK_HEADERS) cp $(UNIFFI_SWIFT_TMP)/truapiFFI.h $(UNIFFI_SWIFT_TMP)/truapi_platformFFI.h \ - $(UNIFFI_SWIFT_TMP)/truapi_serverFFI.h $(XCFRAMEWORK_HEADERS)/ + $(UNIFFI_SWIFT_TMP)/truapi_serverFFI.h $(UNIFFI_SWIFT_TMP)/pvm_runtimeFFI.h \ + $(XCFRAMEWORK_HEADERS)/ cp $(UNIFFI_SWIFT_TMP)/truapi_serverFFI.modulemap $(XCFRAMEWORK_HEADERS)/module.modulemap slices=""; \ for target in $(XCFRAMEWORK_TARGETS); do \ diff --git a/Package.swift b/Package.swift index 8d53ea063..6a2eccabf 100644 --- a/Package.swift +++ b/Package.swift @@ -81,11 +81,18 @@ let package = Package( pkgConfig: nil, providers: [] ), + .systemLibrary( + name: "pvm_runtimeFFI", + path: "ios/truapi-host/Sources/pvm_runtimeFFI/include", + pkgConfig: nil, + providers: [] + ), binaryTarget, .target( name: "TrUAPIHost", dependencies: [ - "truapiFFI", "truapi_platformFFI", "truapi_serverFFI", "truapi_serverFFI_binary", + "truapiFFI", "truapi_platformFFI", "truapi_serverFFI", + "pvm_runtimeFFI", "truapi_serverFFI_binary", ], path: "ios/truapi-host/Sources/TrUAPIHost", resources: [.copy("Resources/truapi-container.js")] diff --git a/README.md b/README.md index 06282047d..5fdd6ecc9 100644 --- a/README.md +++ b/README.md @@ -70,6 +70,7 @@ rust/crates/ truapi-platform/ Host syscall traits used by truapi-server (storage, navigation, consent, ...) truapi-provider/ Network provider backends (WebSocket RPC or smoldot light-client) truapi-server/ Host runtime: dispatcher, typed SCALE logic, chain signing, WASM surface + truapi-pvm-host/ Reviewed bridge to one immutable pvm-host-runtime release js/packages/ truapi/ @parity/truapi TypeScript client truapi-host/ @parity/truapi-host: WASM-backed host runtime; entries `.` @@ -92,6 +93,12 @@ scripts/codegen.sh Regenerate the TS client from the Rust source scripts/battery.sh Run the generated battery against both headless CLI host roles ``` +The PolkaVM application runtime, GPU wire contract, browser workers, and +reproducible browser assets live in +[`paritytech/pvm-host-runtime`](https://github.com/paritytech/pvm-host-runtime). +Hosts integrate through `truapi-pvm-host`, which pins one reviewed runtime +source revision and exposes the matching native API and browser asset set. + The Swift host adapter (the `TrUAPIHost` SPM package over the truapi-server UniFFI core) lives under [`ios/truapi-host/`](ios/truapi-host), with its SPM manifest at the repo root (`Package.swift`) so apps can consume it as a git-URL diff --git a/deny.toml b/deny.toml index 1a454ec77..70e49d675 100644 --- a/deny.toml +++ b/deny.toml @@ -41,6 +41,11 @@ exceptions = [ # BSL-1.0 is permissive, but scope it so it cannot spread to other crates. { name = "clipboard-win", allow = ["BSL-1.0"] }, { name = "error-code", allow = ["BSL-1.0"] }, + # The host-neutral PVM runtime and wire protocol are intentionally MPL-2.0 + # so their Rust and browser implementations retain file-level copyleft. + { name = "pvm-gpu-wire", allow = ["MPL-2.0"] }, + { name = "pvm-runtime", allow = ["MPL-2.0"] }, + { name = "pvm-runtime-assets", allow = ["MPL-2.0"] }, { name = "uniffi", allow = ["MPL-2.0"] }, { name = "uniffi_bindgen", allow = ["MPL-2.0"] }, { name = "uniffi_checksum_derive", allow = ["MPL-2.0"] }, diff --git a/docs/issue-drafts/pointer-capture-control.md b/docs/issue-drafts/pointer-capture-control.md new file mode 100644 index 000000000..509573f68 --- /dev/null +++ b/docs/issue-drafts/pointer-capture-control.md @@ -0,0 +1,146 @@ +# Add host-mediated pointer capture to TrUAPI + +## Status + +Parked prototype note. Do not start an RFC or implementation from this draft +yet. Current hosts capture non-Tri2D surfaces after a primary click, which is +sufficient for the existing game prototypes. Revisit only after prototypes +demonstrate that products need runtime capture/release control beyond the +host's click-to-capture and Escape-to-release policy. + +## Summary + +Pointer lock is host functionality. A product should request and release it through TrUAPI rather than declaring a separate `relative-pointer` feature in its manifest. The host owns the application surface, enforces user activation, calls the platform pointer-lock API, and reports lifecycle changes. High-frequency movement remains on the bounded device-input data path. + +This separates three concerns: + +- The App manifest declares ordinary `pointer` input support. +- TrUAPI controls whether pointer lock is free, armed, or captured. +- Request denial is a call error, and an older host reports the protocol's + standard unsupported-method error. +- The runtime input ABI delivers absolute positions while free and relative + deltas while captured. + +## Motivation + +Graphics profile is not a pointer policy. Some framebuffer and WebGPU products are first-person games that need unbounded relative motion; others are cursor-driven tools that must leave the system pointer free. Defaulting all non-Tri2D surfaces to pointer lock surprises cursor-driven products, while a static manifest feature cannot express when a mixed menu/game product wants capture. + +Pointer lock also cannot be delegated to sandboxed product code. Browser and native hosts own the trusted surface and must preserve an unconditional escape path. + +## Proposed control plane + +Names are placeholders for the RFC: + +```ts +input.pointerCapture.request(): Promise> + +input.pointerCapture.release(): Promise> + +input.pointerCapture.subscribe(): Subscription< + \"free\" | \"armed\" | \"captured\" +> +``` + +The subscription follows the existing `theme.subscribe()` and +`locale.subscribe()` convention: it emits the current state immediately and +then every transition. A separate `status()` request would duplicate the first +subscription item. + +A browser generally cannot honor `request()` immediately because pointer lock +requires a transient user activation. In that case `request()` returns +`armed`; the host acquires lock on the next eligible primary click on the +requesting product's active surface. + +`release()` is idempotent and always permitted. Escape always releases capture +and is consumed by the host for that transition rather than forwarded to the +product as a key press. + +`denied` is a request error rather than a durable capture state: after denial +the surface remains `free`. A host that predates these methods already has a +standard answer—the TrUAPI protocol-error frame for an unknown discriminant—so +`unsupported` does not belong in the domain state enum. + +## Fit with the existing TrUAPI architecture + +The API should be a small `Input` method group, backed by an optional +`PointerCaptureHost` platform callback. The TrUAPI server is product-scoped, so +the callback already runs in the identity and lifecycle context of the calling +product. Web, desktop, and other surface-owning hosts implement the callback; +CLI or non-pointer hosts omit it and receive the existing `Unsupported` +behavior. + +This should not be added to `HostDevicePermissionRequest`. RFC 0002 defines +device permission decisions as indefinitely persisted grants or denials, often +paired with an operating-system permission. Pointer lock is transient surface +state, requires a current user gesture, and must always be releasable. A future +host policy may gate the request, but the first API does not need a persisted +permission. + +The RFC must allocate new append-only wire discriminants for request, release, +and the subscription lifecycle. Existing discriminants cannot be reused. + +## Input data plane + +Pointer movement does not travel through TrUAPI. The existing bounded runtime input channel remains the data plane: + +- Free pointer: event type `5`, absolute canvas `x`/`y`. +- Captured pointer: event type `6`, signed relative `dx`/`dy`. +- Buttons: event types `3` and `4` in either state. + +Hosts should discard the first cursor-warp sample after lock acquisition, reject non-finite or implausible discontinuities, and coalesce high-rate deltas to the runtime's bounded update cadence. + +The browser operation is Pointer Lock (`requestPointerLock()`), not DOM pointer capture (`setPointerCapture()`). DOM pointer capture only preserves event routing during a drag and does not provide an unbounded relative pointer. + +## Host invariants + +- Pointer lock defaults to off for every graphics profile. +- Only the product bound to the active verified surface may request capture. +- Capture requires a real user gesture on that surface. +- A product cannot suppress Escape release. +- Losing focus, replacing the product, navigating, or destroying the surface releases capture. +- Relative events are emitted only while the surface actually owns pointer lock. +- Request denial and every state transition are observable by the product so it + can stop mouse-look or present fallback controls. +- Hosts that predate the API return TrUAPI's standard unsupported-method error; + products decide whether keyboard, touch, or controller input is an acceptable + fallback. + +## Manifest relationship + +No separate `relative-pointer` manifest feature is required. TrUAPI already +provides generic unsupported-method handling, the runtime request expresses +current intent, and the host remains the authority. + +A future RFC may revisit install-time metadata if hosts need to warn that a product cannot function without pointer lock. Such metadata would describe compatibility or user experience; it would not replace runtime request/release control. + +## Future user policy + +A host may eventually expose a per-product policy such as `Ask`, `Allow`, or `Block`, plus a global `Never allow pointer lock` setting. This is intentionally deferred. + +If added, the setting should authorize or deny product requests; it should not force an arbitrary cursor-driven product into relative mode. The policy should be scoped to a verified product identity, show a visible capture indicator, and preserve Escape as an unconditional release path. + +## Revisit criteria + +Keep the existing host behavior while prototypes mature. Promote this note to +an RFC only when at least one real product demonstrates a concrete need such +as: + +- a cursor-driven framebuffer or WebGPU surface that must never capture; +- a mixed menu/game product that must release and reacquire capture without + relying on Escape and a new click; +- a cross-host inconsistency that cannot be fixed as host policy; +- a product that needs to observe capture denial or loss to provide a usable + fallback. + +If one of those cases appears, the RFC should specify request, release, the +immediate state subscription, wire ids, user-gesture semantics, and errors. +Only after that should the shared Rust core, host callbacks, Epoca, Dotli, and +products be changed. + +## Unresolved questions + +- Whether `request()` should be a one-shot request or remain armed across Escape release until the product cancels it. +- Whether capture permission persists per product, per publisher, per artifact version, or only for the current session. +- Whether native hosts need a distinct result for operating-system policy denial. +- Whether products need an optional install-time declaration that pointer lock is essential rather than merely supported. +- Whether a host should expose a standard visual indicator or leave presentation to each host implementation. diff --git a/ios/truapi-host/Sources/TrUAPIHost/pvm_runtime.swift b/ios/truapi-host/Sources/TrUAPIHost/pvm_runtime.swift new file mode 100644 index 000000000..28f61dc43 --- /dev/null +++ b/ios/truapi-host/Sources/TrUAPIHost/pvm_runtime.swift @@ -0,0 +1,1880 @@ +// This file was autogenerated by some hot garbage in the `uniffi` crate. +// Trust me, you don't want to mess with it! + +// swiftlint:disable all +import Foundation + +// Depending on the consumer's build setup, the low-level FFI code +// might be in a separate module, or it might be compiled inline into +// this module. This is a bit of light hackery to work with both. +#if canImport(pvm_runtimeFFI) +import pvm_runtimeFFI +#endif + +fileprivate extension RustBuffer { + // Allocate a new buffer, copying the contents of a `UInt8` array. + init(bytes: [UInt8]) { + let rbuf = bytes.withUnsafeBufferPointer { ptr in + RustBuffer.from(ptr) + } + self.init(capacity: rbuf.capacity, len: rbuf.len, data: rbuf.data) + } + + static func empty() -> RustBuffer { + RustBuffer(capacity: 0, len:0, data: nil) + } + + static func from(_ ptr: UnsafeBufferPointer) -> RustBuffer { + try! rustCall { ffi_pvm_runtime_rustbuffer_from_bytes(ForeignBytes(bufferPointer: ptr), $0) } + } + + // Frees the buffer in place. + // The buffer must not be used after this is called. + func deallocate() { + try! rustCall { ffi_pvm_runtime_rustbuffer_free(self, $0) } + } +} + +fileprivate extension ForeignBytes { + init(bufferPointer: UnsafeBufferPointer) { + self.init(len: Int32(bufferPointer.count), data: bufferPointer.baseAddress) + } + + init(rawBufferPointer: UnsafeRawBufferPointer) { + self.init( + len: Int32(rawBufferPointer.count), + data: rawBufferPointer.baseAddress?.assumingMemoryBound(to: UInt8.self) + ) + } +} + +// Converter for `&[u8]` / `[ByRef] bytes` arguments. +// +// Conforms to `FfiConverter` so the compiler enforces the full converter +// method set. Only the scope-bound `lower(_:_body:)` overload is sound — +// zero-copy byte buffers only flow foreign -> Rust, and only in argument +// position. The four protocol-witness methods (`lift`, `lower`, `read`, +// `write`) `fatalError` at runtime if anyone reaches them. +// +// The scope-bound `lower` takes a closure because the `ForeignBytes` +// pointer is only guaranteed valid for the duration of +// `Data.withUnsafeBytes`. Callers must run the full FFI call inside +// the closure body. +fileprivate enum FfiConverterByRefBytes: FfiConverter { + typealias SwiftType = Data + typealias FfiType = ForeignBytes + + static func lower(_ value: Data, _ body: (ForeignBytes) throws -> R) rethrows -> R { + return try value.withUnsafeBytes { rawBuf in + try body(ForeignBytes(rawBufferPointer: rawBuf)) + } + } + + static func lower(_ value: Data) -> ForeignBytes { + fatalError("ByRef bytes cannot use the plain lower: returning ForeignBytes escapes the Data.withUnsafeBytes scope. Use the scope-bound lower(_:_body:) overload instead.") + } + + static func lift(_ value: ForeignBytes) throws -> Data { + fatalError("ByRef bytes cannot be lifted: zero-copy &[u8] only flows foreign->Rust") + } + + static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Data { + fatalError("ByRef bytes cannot be read from a buffer: zero-copy &[u8] is only supported in argument position, not nested in records/options/etc.") + } + + static func write(_ value: Data, into buf: inout [UInt8]) { + fatalError("ByRef bytes cannot be written to a buffer: zero-copy &[u8] is only supported in argument position, not nested in records/options/etc.") + } +} + +// For every type used in the interface, we provide helper methods for conveniently +// lifting and lowering that type from C-compatible data, and for reading and writing +// values of that type in a buffer. + +// Helper classes/extensions that don't change. +// Someday, this will be in a library of its own. + +fileprivate extension Data { + init(rustBuffer: RustBuffer) { + self.init( + bytesNoCopy: rustBuffer.data!, + count: Int(rustBuffer.len), + deallocator: .none + ) + } +} + +// Define reader functionality. Normally this would be defined in a class or +// struct, but we use standalone functions instead in order to make external +// types work. +// +// With external types, one swift source file needs to be able to call the read +// method on another source file's FfiConverter, but then what visibility +// should Reader have? +// - If Reader is fileprivate, then this means the read() must also +// be fileprivate, which doesn't work with external types. +// - If Reader is internal/public, we'll get compile errors since both source +// files will try define the same type. +// +// Instead, the read() method and these helper functions input a tuple of data + +fileprivate func createReader(data: Data) -> (data: Data, offset: Data.Index) { + (data: data, offset: 0) +} + +// Reads an integer at the current offset, in big-endian order, and advances +// the offset on success. Throws if reading the integer would move the +// offset past the end of the buffer. +fileprivate func readInt(_ reader: inout (data: Data, offset: Data.Index)) throws -> T { + let range = reader.offset...size + guard reader.data.count >= range.upperBound else { + throw UniffiInternalError.bufferOverflow + } + if T.self == UInt8.self { + let value = reader.data[reader.offset] + reader.offset += 1 + return value as! T + } + var value: T = 0 + let _ = withUnsafeMutableBytes(of: &value, { reader.data.copyBytes(to: $0, from: range)}) + reader.offset = range.upperBound + return value.bigEndian +} + +// Reads an arbitrary number of bytes, to be used to read +// raw bytes, this is useful when lifting strings +fileprivate func readBytes(_ reader: inout (data: Data, offset: Data.Index), count: Int) throws -> Array { + let range = reader.offset..<(reader.offset+count) + guard reader.data.count >= range.upperBound else { + throw UniffiInternalError.bufferOverflow + } + var value = [UInt8](repeating: 0, count: count) + value.withUnsafeMutableBufferPointer({ buffer in + reader.data.copyBytes(to: buffer, from: range) + }) + reader.offset = range.upperBound + return value +} + +// Reads a float at the current offset. +fileprivate func readFloat(_ reader: inout (data: Data, offset: Data.Index)) throws -> Float { + return Float(bitPattern: try readInt(&reader)) +} + +// Reads a float at the current offset. +fileprivate func readDouble(_ reader: inout (data: Data, offset: Data.Index)) throws -> Double { + return Double(bitPattern: try readInt(&reader)) +} + +// Indicates if the offset has reached the end of the buffer. +fileprivate func hasRemaining(_ reader: (data: Data, offset: Data.Index)) -> Bool { + return reader.offset < reader.data.count +} + +// Define writer functionality. Normally this would be defined in a class or +// struct, but we use standalone functions instead in order to make external +// types work. See the above discussion on Readers for details. + +fileprivate func createWriter() -> [UInt8] { + return [] +} + +fileprivate func writeBytes(_ writer: inout [UInt8], _ byteArr: S) where S: Sequence, S.Element == UInt8 { + writer.append(contentsOf: byteArr) +} + +// Writes an integer in big-endian order. +// +// Warning: make sure what you are trying to write +// is in the correct type! +fileprivate func writeInt(_ writer: inout [UInt8], _ value: T) { + var value = value.bigEndian + withUnsafeBytes(of: &value) { writer.append(contentsOf: $0) } +} + +fileprivate func writeFloat(_ writer: inout [UInt8], _ value: Float) { + writeInt(&writer, value.bitPattern) +} + +fileprivate func writeDouble(_ writer: inout [UInt8], _ value: Double) { + writeInt(&writer, value.bitPattern) +} + +// Protocol for types that transfer other types across the FFI. This is +// analogous to the Rust trait of the same name. +fileprivate protocol FfiConverter { + associatedtype FfiType + associatedtype SwiftType + + static func lift(_ value: FfiType) throws -> SwiftType + static func lower(_ value: SwiftType) -> FfiType + static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType + static func write(_ value: SwiftType, into buf: inout [UInt8]) +} + +// Types conforming to `Primitive` pass themselves directly over the FFI. +fileprivate protocol FfiConverterPrimitive: FfiConverter where FfiType == SwiftType { } + +extension FfiConverterPrimitive { +#if swift(>=5.8) + @_documentation(visibility: private) +#endif + public static func lift(_ value: FfiType) throws -> SwiftType { + return value + } + +#if swift(>=5.8) + @_documentation(visibility: private) +#endif + public static func lower(_ value: SwiftType) -> FfiType { + return value + } +} + +// Types conforming to `FfiConverterRustBuffer` lift and lower into a `RustBuffer`. +// Used for complex types where it's hard to write a custom lift/lower. +fileprivate protocol FfiConverterRustBuffer: FfiConverter where FfiType == RustBuffer {} + +extension FfiConverterRustBuffer { +#if swift(>=5.8) + @_documentation(visibility: private) +#endif + public static func lift(_ buf: RustBuffer) throws -> SwiftType { + var reader = createReader(data: Data(rustBuffer: buf)) + let value = try read(from: &reader) + if hasRemaining(reader) { + throw UniffiInternalError.incompleteData + } + buf.deallocate() + return value + } + +#if swift(>=5.8) + @_documentation(visibility: private) +#endif + public static func lower(_ value: SwiftType) -> RustBuffer { + var writer = createWriter() + write(value, into: &writer) + return RustBuffer(bytes: writer) + } +} +// An error type for FFI errors. These errors occur at the UniFFI level, not +// the library level. +fileprivate enum UniffiInternalError: LocalizedError { + case bufferOverflow + case incompleteData + case unexpectedOptionalTag + case unexpectedEnumCase + case unexpectedNullPointer + case unexpectedRustCallStatusCode + case unexpectedRustCallError + case unexpectedStaleHandle + case rustPanic(_ message: String) + + public var errorDescription: String? { + switch self { + case .bufferOverflow: return "Reading the requested value would read past the end of the buffer" + case .incompleteData: return "The buffer still has data after lifting its containing value" + case .unexpectedOptionalTag: return "Unexpected optional tag; should be 0 or 1" + case .unexpectedEnumCase: return "Raw enum value doesn't match any cases" + case .unexpectedNullPointer: return "Raw pointer value was null" + case .unexpectedRustCallStatusCode: return "Unexpected RustCallStatus code" + case .unexpectedRustCallError: return "CALL_ERROR but no errorClass specified" + case .unexpectedStaleHandle: return "The object in the handle map has been dropped already" + case let .rustPanic(message): return message + } + } +} + +fileprivate extension NSLock { + func withLock(f: () throws -> T) rethrows -> T { + self.lock() + defer { self.unlock() } + return try f() + } +} + +fileprivate let CALL_SUCCESS: Int8 = 0 +fileprivate let CALL_ERROR: Int8 = 1 +fileprivate let CALL_UNEXPECTED_ERROR: Int8 = 2 +fileprivate let CALL_CANCELLED: Int8 = 3 + +fileprivate extension RustCallStatus { + init() { + self.init( + code: CALL_SUCCESS, + errorBuf: RustBuffer.init( + capacity: 0, + len: 0, + data: nil + ) + ) + } +} + +private func rustCall(_ callback: (UnsafeMutablePointer) -> T) throws -> T { + let neverThrow: ((RustBuffer) throws -> Never)? = nil + return try makeRustCall(callback, errorHandler: neverThrow) +} + +private func rustCallWithError( + _ errorHandler: @escaping (RustBuffer) throws -> E, + _ callback: (UnsafeMutablePointer) -> T) throws -> T { + try makeRustCall(callback, errorHandler: errorHandler) +} + +private func makeRustCall( + _ callback: (UnsafeMutablePointer) -> T, + errorHandler: ((RustBuffer) throws -> E)? +) throws -> T { + uniffiEnsurePvmRuntimeInitialized() + var callStatus = RustCallStatus.init() + let returnedVal = callback(&callStatus) + try uniffiCheckCallStatus(callStatus: callStatus, errorHandler: errorHandler) + return returnedVal +} + +private func uniffiCheckCallStatus( + callStatus: RustCallStatus, + errorHandler: ((RustBuffer) throws -> E)? +) throws { + switch callStatus.code { + case CALL_SUCCESS: + return + + case CALL_ERROR: + if let errorHandler = errorHandler { + throw try errorHandler(callStatus.errorBuf) + } else { + callStatus.errorBuf.deallocate() + throw UniffiInternalError.unexpectedRustCallError + } + + case CALL_UNEXPECTED_ERROR: + // When the rust code sees a panic, it tries to construct a RustBuffer + // with the message. But if that code panics, then it just sends back + // an empty buffer. + if callStatus.errorBuf.len > 0 { + throw UniffiInternalError.rustPanic(try FfiConverterString.lift(callStatus.errorBuf)) + } else { + callStatus.errorBuf.deallocate() + throw UniffiInternalError.rustPanic("Rust panic") + } + + case CALL_CANCELLED: + fatalError("Cancellation not supported yet") + + default: + throw UniffiInternalError.unexpectedRustCallStatusCode + } +} + +private func uniffiTraitInterfaceCall( + callStatus: UnsafeMutablePointer, + makeCall: () throws -> T, + writeReturn: (T) -> () +) { + do { + try writeReturn(makeCall()) + } catch let error { + callStatus.pointee.code = CALL_UNEXPECTED_ERROR + callStatus.pointee.errorBuf = FfiConverterString.lower(String(describing: error)) + } +} + +private func uniffiTraitInterfaceCallWithError( + callStatus: UnsafeMutablePointer, + makeCall: () throws -> T, + writeReturn: (T) -> (), + lowerError: (E) -> RustBuffer +) { + do { + try writeReturn(makeCall()) + } catch let error as E { + callStatus.pointee.code = CALL_ERROR + callStatus.pointee.errorBuf = lowerError(error) + } catch { + callStatus.pointee.code = CALL_UNEXPECTED_ERROR + callStatus.pointee.errorBuf = FfiConverterString.lower(String(describing: error)) + } +} +// Initial value and increment amount for handles. +// These ensure that SWIFT handles always have the lowest bit set +fileprivate let UNIFFI_HANDLEMAP_INITIAL: UInt64 = 1 +fileprivate let UNIFFI_HANDLEMAP_DELTA: UInt64 = 2 + +fileprivate final class UniffiHandleMap: @unchecked Sendable { + // All mutation happens with this lock held, which is why we implement @unchecked Sendable. + private let lock = NSLock() + private var map: [UInt64: T] = [:] + private var currentHandle: UInt64 = UNIFFI_HANDLEMAP_INITIAL + + func insert(obj: T) -> UInt64 { + lock.withLock { + return doInsert(obj) + } + } + + // Low-level insert function, this assumes `lock` is held. + private func doInsert(_ obj: T) -> UInt64 { + let handle = currentHandle + currentHandle += UNIFFI_HANDLEMAP_DELTA + map[handle] = obj + return handle + } + + func get(handle: UInt64) throws -> T { + try lock.withLock { + guard let obj = map[handle] else { + throw UniffiInternalError.unexpectedStaleHandle + } + return obj + } + } + + func clone(handle: UInt64) throws -> UInt64 { + try lock.withLock { + guard let obj = map[handle] else { + throw UniffiInternalError.unexpectedStaleHandle + } + return doInsert(obj) + } + } + + @discardableResult + func remove(handle: UInt64) throws -> T { + try lock.withLock { + guard let obj = map.removeValue(forKey: handle) else { + throw UniffiInternalError.unexpectedStaleHandle + } + return obj + } + } + + var count: Int { + get { + map.count + } + } +} + + +// Public interface members begin here. + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterUInt8: FfiConverterPrimitive { + typealias FfiType = UInt8 + typealias SwiftType = UInt8 + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> UInt8 { + return try lift(readInt(&buf)) + } + + public static func write(_ value: UInt8, into buf: inout [UInt8]) { + writeInt(&buf, lower(value)) + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterUInt16: FfiConverterPrimitive { + typealias FfiType = UInt16 + typealias SwiftType = UInt16 + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> UInt16 { + return try lift(readInt(&buf)) + } + + public static func write(_ value: SwiftType, into buf: inout [UInt8]) { + writeInt(&buf, lower(value)) + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterInt16: FfiConverterPrimitive { + typealias FfiType = Int16 + typealias SwiftType = Int16 + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Int16 { + return try lift(readInt(&buf)) + } + + public static func write(_ value: Int16, into buf: inout [UInt8]) { + writeInt(&buf, lower(value)) + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterUInt32: FfiConverterPrimitive { + typealias FfiType = UInt32 + typealias SwiftType = UInt32 + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> UInt32 { + return try lift(readInt(&buf)) + } + + public static func write(_ value: SwiftType, into buf: inout [UInt8]) { + writeInt(&buf, lower(value)) + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterUInt64: FfiConverterPrimitive { + typealias FfiType = UInt64 + typealias SwiftType = UInt64 + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> UInt64 { + return try lift(readInt(&buf)) + } + + public static func write(_ value: SwiftType, into buf: inout [UInt8]) { + writeInt(&buf, lower(value)) + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterFloat: FfiConverterPrimitive { + typealias FfiType = Float + typealias SwiftType = Float + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Float { + return try lift(readFloat(&buf)) + } + + public static func write(_ value: Float, into buf: inout [UInt8]) { + writeFloat(&buf, lower(value)) + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterBool : FfiConverter { + typealias FfiType = Int8 + typealias SwiftType = Bool + + public static func lift(_ value: Int8) throws -> Bool { + return value != 0 + } + + public static func lower(_ value: Bool) -> Int8 { + return value ? 1 : 0 + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Bool { + return try lift(readInt(&buf)) + } + + public static func write(_ value: Bool, into buf: inout [UInt8]) { + writeInt(&buf, lower(value)) + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterString: FfiConverter { + typealias SwiftType = String + typealias FfiType = RustBuffer + + public static func lift(_ value: RustBuffer) throws -> String { + defer { + value.deallocate() + } + if value.data == nil { + return String() + } + let bytes = UnsafeBufferPointer(start: value.data!, count: Int(value.len)) + // Use Swift's native UTF-8 decoder; `String(bytes:encoding:.utf8)` goes + // through Foundation's NSString and silently strips a leading U+FEFF BOM. + // Invalid UTF-8 substitutes U+FFFD instead of trapping (unreachable + // given Rust's `String` invariant). + return String(decoding: bytes, as: UTF8.self) + } + + public static func lower(_ value: String) -> RustBuffer { + return value.utf8CString.withUnsafeBufferPointer { ptr in + // The swift string gives us int8_t, we want uint8_t. + ptr.withMemoryRebound(to: UInt8.self) { ptr in + // The swift string gives us a trailing null byte, we don't want it. + let buf = UnsafeBufferPointer(rebasing: ptr.prefix(upTo: ptr.count - 1)) + return RustBuffer.from(buf) + } + } + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> String { + let len: Int32 = try readInt(&buf) + // See `lift` above for why we avoid Foundation's NSString-backed decoder here. + return String(decoding: try readBytes(&buf, count: Int(len)), as: UTF8.self) + } + + public static func write(_ value: String, into buf: inout [UInt8]) { + let len = Int32(value.utf8.count) + writeInt(&buf, len) + writeBytes(&buf, value.utf8) + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterData: FfiConverterRustBuffer { + typealias SwiftType = Data + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Data { + let len: Int32 = try readInt(&buf) + return Data(try readBytes(&buf, count: Int(len))) + } + + public static func write(_ value: Data, into buf: inout [UInt8]) { + let len = Int32(value.count) + writeInt(&buf, len) + writeBytes(&buf, value) + } +} + + + + +public protocol NativePvmRuntimeProtocol: AnyObject, Sendable { + + func backend() throws -> String + + func clearMotionTilt() throws + + func gpuReady() throws -> Bool + + func `init`() throws + + func isExited() throws -> Bool + + func lastGasUsed() throws -> UInt64 + + func sendGpuEvent(bytes: Data) throws + + func sendInput(eventType: NativePvmInputEventType, code: UInt8, x: UInt16, y: UInt16) throws + + func setGpuCapabilities(bytes: Data) throws + + func setMotionTilt(sample: NativePvmMotionTiltSample) throws + + func takeAudio() throws -> NativePvmAudioChunk? + + func takeFrame() throws -> NativePvmFrame? + + func takeGpuBatch() throws -> NativePvmGpuBatch? + + func takeLog() throws -> String? + + func takeSave() throws -> Data? + + func takeTri2d() throws -> NativePvmTri2dFrame? + + func update() throws + +} +open class NativePvmRuntime: NativePvmRuntimeProtocol, @unchecked Sendable { + fileprivate let handle: UInt64 + + /// Used to instantiate a [FFIObject] without an actual handle, for fakes in tests, mostly. +#if swift(>=5.8) + @_documentation(visibility: private) +#endif + public struct NoHandle { + public init() {} + } + + // TODO: We'd like this to be `private` but for Swifty reasons, + // we can't implement `FfiConverter` without making this `required` and we can't + // make it `required` without making it `public`. +#if swift(>=5.8) + @_documentation(visibility: private) +#endif + required public init(unsafeFromHandle handle: UInt64) { + self.handle = handle + } + + // This constructor can be used to instantiate a fake object. + // - Parameter noHandle: Placeholder value so we can have a constructor separate from the default empty one that may be implemented for classes extending [FFIObject]. + // + // - Warning: + // Any object instantiated with this constructor cannot be passed to an actual Rust-backed object. Since there isn't a backing handle the FFI lower functions will crash. +#if swift(>=5.8) + @_documentation(visibility: private) +#endif + public init(noHandle: NoHandle) { + self.handle = 0 + } + +#if swift(>=5.8) + @_documentation(visibility: private) +#endif + public func uniffiCloneHandle() -> UInt64 { + return try! rustCall { uniffi_pvm_runtime_fn_clone_nativepvmruntime(self.handle, $0) } + } +public convenience init(program: Data, assets: [NativePvmAsset], presentation: NativePvmPresentationProfile, audioEnabled: Bool, maxGasPerUpdate: UInt64)throws { + let handle = + try rustCallWithError(FfiConverterTypeNativePvmError_lift) { + uniffiCallStatus in + uniffi_pvm_runtime_fn_constructor_nativepvmruntime_new( + FfiConverterData.lower(program), + FfiConverterSequenceTypeNativePvmAsset.lower(assets), + FfiConverterTypeNativePvmPresentationProfile_lower(presentation), + FfiConverterBool.lower(audioEnabled), + FfiConverterUInt64.lower(maxGasPerUpdate),uniffiCallStatus + ) +} + self.init(unsafeFromHandle: handle) +} + + deinit { + if handle == 0 { + // Mock objects have handle=0 don't try to free them + return + } + + try! rustCall { uniffi_pvm_runtime_fn_free_nativepvmruntime(handle, $0) } + } + + + + +open func backend()throws -> String { + return try FfiConverterString.lift(try rustCallWithError(FfiConverterTypeNativePvmError_lift) { + uniffiCallStatus in + uniffi_pvm_runtime_fn_method_nativepvmruntime_backend( + self.uniffiCloneHandle(),uniffiCallStatus + ) +}) +} + +open func clearMotionTilt()throws {try rustCallWithError(FfiConverterTypeNativePvmError_lift) { + uniffiCallStatus in + uniffi_pvm_runtime_fn_method_nativepvmruntime_clear_motion_tilt( + self.uniffiCloneHandle(),uniffiCallStatus + ) +} +} + +open func gpuReady()throws -> Bool { + return try FfiConverterBool.lift(try rustCallWithError(FfiConverterTypeNativePvmError_lift) { + uniffiCallStatus in + uniffi_pvm_runtime_fn_method_nativepvmruntime_gpu_ready( + self.uniffiCloneHandle(),uniffiCallStatus + ) +}) +} + +open func `init`()throws {try rustCallWithError(FfiConverterTypeNativePvmError_lift) { + uniffiCallStatus in + uniffi_pvm_runtime_fn_method_nativepvmruntime_init( + self.uniffiCloneHandle(),uniffiCallStatus + ) +} +} + +open func isExited()throws -> Bool { + return try FfiConverterBool.lift(try rustCallWithError(FfiConverterTypeNativePvmError_lift) { + uniffiCallStatus in + uniffi_pvm_runtime_fn_method_nativepvmruntime_is_exited( + self.uniffiCloneHandle(),uniffiCallStatus + ) +}) +} + +open func lastGasUsed()throws -> UInt64 { + return try FfiConverterUInt64.lift(try rustCallWithError(FfiConverterTypeNativePvmError_lift) { + uniffiCallStatus in + uniffi_pvm_runtime_fn_method_nativepvmruntime_last_gas_used( + self.uniffiCloneHandle(),uniffiCallStatus + ) +}) +} + +open func sendGpuEvent(bytes: Data)throws {try rustCallWithError(FfiConverterTypeNativePvmError_lift) { + uniffiCallStatus in + uniffi_pvm_runtime_fn_method_nativepvmruntime_send_gpu_event( + self.uniffiCloneHandle(), + FfiConverterData.lower(bytes),uniffiCallStatus + ) +} +} + +open func sendInput(eventType: NativePvmInputEventType, code: UInt8, x: UInt16, y: UInt16)throws {try rustCallWithError(FfiConverterTypeNativePvmError_lift) { + uniffiCallStatus in + uniffi_pvm_runtime_fn_method_nativepvmruntime_send_input( + self.uniffiCloneHandle(), + FfiConverterTypeNativePvmInputEventType_lower(eventType), + FfiConverterUInt8.lower(code), + FfiConverterUInt16.lower(x), + FfiConverterUInt16.lower(y),uniffiCallStatus + ) +} +} + +open func setGpuCapabilities(bytes: Data)throws {try rustCallWithError(FfiConverterTypeNativePvmError_lift) { + uniffiCallStatus in + uniffi_pvm_runtime_fn_method_nativepvmruntime_set_gpu_capabilities( + self.uniffiCloneHandle(), + FfiConverterData.lower(bytes),uniffiCallStatus + ) +} +} + +open func setMotionTilt(sample: NativePvmMotionTiltSample)throws {try rustCallWithError(FfiConverterTypeNativePvmError_lift) { + uniffiCallStatus in + uniffi_pvm_runtime_fn_method_nativepvmruntime_set_motion_tilt( + self.uniffiCloneHandle(), + FfiConverterTypeNativePvmMotionTiltSample_lower(sample),uniffiCallStatus + ) +} +} + +open func takeAudio()throws -> NativePvmAudioChunk? { + return try FfiConverterOptionTypeNativePvmAudioChunk.lift(try rustCallWithError(FfiConverterTypeNativePvmError_lift) { + uniffiCallStatus in + uniffi_pvm_runtime_fn_method_nativepvmruntime_take_audio( + self.uniffiCloneHandle(),uniffiCallStatus + ) +}) +} + +open func takeFrame()throws -> NativePvmFrame? { + return try FfiConverterOptionTypeNativePvmFrame.lift(try rustCallWithError(FfiConverterTypeNativePvmError_lift) { + uniffiCallStatus in + uniffi_pvm_runtime_fn_method_nativepvmruntime_take_frame( + self.uniffiCloneHandle(),uniffiCallStatus + ) +}) +} + +open func takeGpuBatch()throws -> NativePvmGpuBatch? { + return try FfiConverterOptionTypeNativePvmGpuBatch.lift(try rustCallWithError(FfiConverterTypeNativePvmError_lift) { + uniffiCallStatus in + uniffi_pvm_runtime_fn_method_nativepvmruntime_take_gpu_batch( + self.uniffiCloneHandle(),uniffiCallStatus + ) +}) +} + +open func takeLog()throws -> String? { + return try FfiConverterOptionString.lift(try rustCallWithError(FfiConverterTypeNativePvmError_lift) { + uniffiCallStatus in + uniffi_pvm_runtime_fn_method_nativepvmruntime_take_log( + self.uniffiCloneHandle(),uniffiCallStatus + ) +}) +} + +open func takeSave()throws -> Data? { + return try FfiConverterOptionData.lift(try rustCallWithError(FfiConverterTypeNativePvmError_lift) { + uniffiCallStatus in + uniffi_pvm_runtime_fn_method_nativepvmruntime_take_save( + self.uniffiCloneHandle(),uniffiCallStatus + ) +}) +} + +open func takeTri2d()throws -> NativePvmTri2dFrame? { + return try FfiConverterOptionTypeNativePvmTri2dFrame.lift(try rustCallWithError(FfiConverterTypeNativePvmError_lift) { + uniffiCallStatus in + uniffi_pvm_runtime_fn_method_nativepvmruntime_take_tri2d( + self.uniffiCloneHandle(),uniffiCallStatus + ) +}) +} + +open func update()throws {try rustCallWithError(FfiConverterTypeNativePvmError_lift) { + uniffiCallStatus in + uniffi_pvm_runtime_fn_method_nativepvmruntime_update( + self.uniffiCloneHandle(),uniffiCallStatus + ) +} +} + + + +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeNativePvmRuntime: FfiConverter { + typealias FfiType = UInt64 + typealias SwiftType = NativePvmRuntime + + public static func lift(_ handle: UInt64) throws -> NativePvmRuntime { + return NativePvmRuntime(unsafeFromHandle: handle) + } + + public static func lower(_ value: NativePvmRuntime) -> UInt64 { + return value.uniffiCloneHandle() + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> NativePvmRuntime { + let handle: UInt64 = try readInt(&buf) + return try lift(handle) + } + + public static func write(_ value: NativePvmRuntime, into buf: inout [UInt8]) { + writeInt(&buf, lower(value)) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeNativePvmRuntime_lift(_ handle: UInt64) throws -> NativePvmRuntime { + return try FfiConverterTypeNativePvmRuntime.lift(handle) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeNativePvmRuntime_lower(_ value: NativePvmRuntime) -> UInt64 { + return FfiConverterTypeNativePvmRuntime.lower(value) +} + + + + +public struct NativePvmAsset: Equatable, Hashable { + public var path: String + public var bytes: Data + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(path: String, bytes: Data) { + self.path = path + self.bytes = bytes + } + + + + +} + +#if compiler(>=6) +extension NativePvmAsset: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeNativePvmAsset: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> NativePvmAsset { + return + try NativePvmAsset( + path: FfiConverterString.read(from: &buf), + bytes: FfiConverterData.read(from: &buf) + ) + } + + public static func write(_ value: NativePvmAsset, into buf: inout [UInt8]) { + FfiConverterString.write(value.path, into: &buf) + FfiConverterData.write(value.bytes, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeNativePvmAsset_lift(_ buf: RustBuffer) throws -> NativePvmAsset { + return try FfiConverterTypeNativePvmAsset.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeNativePvmAsset_lower(_ value: NativePvmAsset) -> RustBuffer { + return FfiConverterTypeNativePvmAsset.lower(value) +} + + +public struct NativePvmAudioChunk: Equatable, Hashable { + public var samples: [Int16] + public var sampleRate: UInt32 + public var channels: UInt32 + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(samples: [Int16], sampleRate: UInt32, channels: UInt32) { + self.samples = samples + self.sampleRate = sampleRate + self.channels = channels + } + + + + +} + +#if compiler(>=6) +extension NativePvmAudioChunk: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeNativePvmAudioChunk: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> NativePvmAudioChunk { + return + try NativePvmAudioChunk( + samples: FfiConverterSequenceInt16.read(from: &buf), + sampleRate: FfiConverterUInt32.read(from: &buf), + channels: FfiConverterUInt32.read(from: &buf) + ) + } + + public static func write(_ value: NativePvmAudioChunk, into buf: inout [UInt8]) { + FfiConverterSequenceInt16.write(value.samples, into: &buf) + FfiConverterUInt32.write(value.sampleRate, into: &buf) + FfiConverterUInt32.write(value.channels, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeNativePvmAudioChunk_lift(_ buf: RustBuffer) throws -> NativePvmAudioChunk { + return try FfiConverterTypeNativePvmAudioChunk.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeNativePvmAudioChunk_lower(_ value: NativePvmAudioChunk) -> RustBuffer { + return FfiConverterTypeNativePvmAudioChunk.lower(value) +} + + +public struct NativePvmFrame: Equatable, Hashable { + public var width: UInt32 + public var height: UInt32 + public var argb: Data + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(width: UInt32, height: UInt32, argb: Data) { + self.width = width + self.height = height + self.argb = argb + } + + + + +} + +#if compiler(>=6) +extension NativePvmFrame: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeNativePvmFrame: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> NativePvmFrame { + return + try NativePvmFrame( + width: FfiConverterUInt32.read(from: &buf), + height: FfiConverterUInt32.read(from: &buf), + argb: FfiConverterData.read(from: &buf) + ) + } + + public static func write(_ value: NativePvmFrame, into buf: inout [UInt8]) { + FfiConverterUInt32.write(value.width, into: &buf) + FfiConverterUInt32.write(value.height, into: &buf) + FfiConverterData.write(value.argb, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeNativePvmFrame_lift(_ buf: RustBuffer) throws -> NativePvmFrame { + return try FfiConverterTypeNativePvmFrame.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeNativePvmFrame_lower(_ value: NativePvmFrame) -> RustBuffer { + return FfiConverterTypeNativePvmFrame.lower(value) +} + + +public struct NativePvmGpuBatch: Equatable, Hashable { + public var bytes: Data + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(bytes: Data) { + self.bytes = bytes + } + + + + +} + +#if compiler(>=6) +extension NativePvmGpuBatch: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeNativePvmGpuBatch: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> NativePvmGpuBatch { + return + try NativePvmGpuBatch( + bytes: FfiConverterData.read(from: &buf) + ) + } + + public static func write(_ value: NativePvmGpuBatch, into buf: inout [UInt8]) { + FfiConverterData.write(value.bytes, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeNativePvmGpuBatch_lift(_ buf: RustBuffer) throws -> NativePvmGpuBatch { + return try FfiConverterTypeNativePvmGpuBatch.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeNativePvmGpuBatch_lower(_ value: NativePvmGpuBatch) -> RustBuffer { + return FfiConverterTypeNativePvmGpuBatch.lower(value) +} + + +public struct NativePvmMotionTiltSample: Equatable, Hashable { + public var sequence: UInt32 + public var timestampUs: UInt64 + public var tiltX: Float + public var tiltY: Float + public var azimuth: Float? + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(sequence: UInt32, timestampUs: UInt64, tiltX: Float, tiltY: Float, azimuth: Float?) { + self.sequence = sequence + self.timestampUs = timestampUs + self.tiltX = tiltX + self.tiltY = tiltY + self.azimuth = azimuth + } + + + + +} + +#if compiler(>=6) +extension NativePvmMotionTiltSample: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeNativePvmMotionTiltSample: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> NativePvmMotionTiltSample { + return + try NativePvmMotionTiltSample( + sequence: FfiConverterUInt32.read(from: &buf), + timestampUs: FfiConverterUInt64.read(from: &buf), + tiltX: FfiConverterFloat.read(from: &buf), + tiltY: FfiConverterFloat.read(from: &buf), + azimuth: FfiConverterOptionFloat.read(from: &buf) + ) + } + + public static func write(_ value: NativePvmMotionTiltSample, into buf: inout [UInt8]) { + FfiConverterUInt32.write(value.sequence, into: &buf) + FfiConverterUInt64.write(value.timestampUs, into: &buf) + FfiConverterFloat.write(value.tiltX, into: &buf) + FfiConverterFloat.write(value.tiltY, into: &buf) + FfiConverterOptionFloat.write(value.azimuth, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeNativePvmMotionTiltSample_lift(_ buf: RustBuffer) throws -> NativePvmMotionTiltSample { + return try FfiConverterTypeNativePvmMotionTiltSample.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeNativePvmMotionTiltSample_lower(_ value: NativePvmMotionTiltSample) -> RustBuffer { + return FfiConverterTypeNativePvmMotionTiltSample.lower(value) +} + + +public struct NativePvmTri2dFrame: Equatable, Hashable { + public var width: UInt32 + public var height: UInt32 + public var drawCount: UInt32 + public var vertexCount: UInt32 + public var indexCount: UInt32 + public var bytes: Data + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(width: UInt32, height: UInt32, drawCount: UInt32, vertexCount: UInt32, indexCount: UInt32, bytes: Data) { + self.width = width + self.height = height + self.drawCount = drawCount + self.vertexCount = vertexCount + self.indexCount = indexCount + self.bytes = bytes + } + + + + +} + +#if compiler(>=6) +extension NativePvmTri2dFrame: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeNativePvmTri2dFrame: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> NativePvmTri2dFrame { + return + try NativePvmTri2dFrame( + width: FfiConverterUInt32.read(from: &buf), + height: FfiConverterUInt32.read(from: &buf), + drawCount: FfiConverterUInt32.read(from: &buf), + vertexCount: FfiConverterUInt32.read(from: &buf), + indexCount: FfiConverterUInt32.read(from: &buf), + bytes: FfiConverterData.read(from: &buf) + ) + } + + public static func write(_ value: NativePvmTri2dFrame, into buf: inout [UInt8]) { + FfiConverterUInt32.write(value.width, into: &buf) + FfiConverterUInt32.write(value.height, into: &buf) + FfiConverterUInt32.write(value.drawCount, into: &buf) + FfiConverterUInt32.write(value.vertexCount, into: &buf) + FfiConverterUInt32.write(value.indexCount, into: &buf) + FfiConverterData.write(value.bytes, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeNativePvmTri2dFrame_lift(_ buf: RustBuffer) throws -> NativePvmTri2dFrame { + return try FfiConverterTypeNativePvmTri2dFrame.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeNativePvmTri2dFrame_lower(_ value: NativePvmTri2dFrame) -> RustBuffer { + return FfiConverterTypeNativePvmTri2dFrame.lower(value) +} + + +public +enum NativePvmError: Swift.Error, Equatable, Hashable, Foundation.LocalizedError { + + + + case Runtime(detail: String + ) + case DuplicateAsset(path: String + ) + case RuntimePoisoned + + + + + + + public var errorDescription: String? { + String(reflecting: self) + } + +} + +#if compiler(>=6) +extension NativePvmError: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeNativePvmError: FfiConverterRustBuffer { + typealias SwiftType = NativePvmError + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> NativePvmError { + let variant: Int32 = try readInt(&buf) + switch variant { + + + + + case 1: return .Runtime( + detail: try FfiConverterString.read(from: &buf) + ) + case 2: return .DuplicateAsset( + path: try FfiConverterString.read(from: &buf) + ) + case 3: return .RuntimePoisoned + + default: throw UniffiInternalError.unexpectedEnumCase + } + } + + public static func write(_ value: NativePvmError, into buf: inout [UInt8]) { + switch value { + + + + + + case let .Runtime(detail): + writeInt(&buf, Int32(1)) + FfiConverterString.write(detail, into: &buf) + + + case let .DuplicateAsset(path): + writeInt(&buf, Int32(2)) + FfiConverterString.write(path, into: &buf) + + + case .RuntimePoisoned: + writeInt(&buf, Int32(3)) + + } + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeNativePvmError_lift(_ buf: RustBuffer) throws -> NativePvmError { + return try FfiConverterTypeNativePvmError.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeNativePvmError_lower(_ value: NativePvmError) -> RustBuffer { + return FfiConverterTypeNativePvmError.lower(value) +} + + + +public enum NativePvmInputEventType: Equatable, Hashable { + + case keyDown + case keyUp + case buttonDown + case buttonUp + case pointerMove + case pointerDelta + case surfaceMetrics + + + + + +} + +#if compiler(>=6) +extension NativePvmInputEventType: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeNativePvmInputEventType: FfiConverterRustBuffer { + typealias SwiftType = NativePvmInputEventType + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> NativePvmInputEventType { + let variant: Int32 = try readInt(&buf) + switch variant { + + case 1: return .keyDown + + case 2: return .keyUp + + case 3: return .buttonDown + + case 4: return .buttonUp + + case 5: return .pointerMove + + case 6: return .pointerDelta + + case 7: return .surfaceMetrics + + default: throw UniffiInternalError.unexpectedEnumCase + } + } + + public static func write(_ value: NativePvmInputEventType, into buf: inout [UInt8]) { + switch value { + + + case .keyDown: + writeInt(&buf, Int32(1)) + + + case .keyUp: + writeInt(&buf, Int32(2)) + + + case .buttonDown: + writeInt(&buf, Int32(3)) + + + case .buttonUp: + writeInt(&buf, Int32(4)) + + + case .pointerMove: + writeInt(&buf, Int32(5)) + + + case .pointerDelta: + writeInt(&buf, Int32(6)) + + + case .surfaceMetrics: + writeInt(&buf, Int32(7)) + + } + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeNativePvmInputEventType_lift(_ buf: RustBuffer) throws -> NativePvmInputEventType { + return try FfiConverterTypeNativePvmInputEventType.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeNativePvmInputEventType_lower(_ value: NativePvmInputEventType) -> RustBuffer { + return FfiConverterTypeNativePvmInputEventType.lower(value) +} + + + + +public enum NativePvmPresentationProfile: Equatable, Hashable { + + case framebuffer + case tri2d + case webGpuRaster + + + + + +} + +#if compiler(>=6) +extension NativePvmPresentationProfile: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeNativePvmPresentationProfile: FfiConverterRustBuffer { + typealias SwiftType = NativePvmPresentationProfile + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> NativePvmPresentationProfile { + let variant: Int32 = try readInt(&buf) + switch variant { + + case 1: return .framebuffer + + case 2: return .tri2d + + case 3: return .webGpuRaster + + default: throw UniffiInternalError.unexpectedEnumCase + } + } + + public static func write(_ value: NativePvmPresentationProfile, into buf: inout [UInt8]) { + switch value { + + + case .framebuffer: + writeInt(&buf, Int32(1)) + + + case .tri2d: + writeInt(&buf, Int32(2)) + + + case .webGpuRaster: + writeInt(&buf, Int32(3)) + + } + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeNativePvmPresentationProfile_lift(_ buf: RustBuffer) throws -> NativePvmPresentationProfile { + return try FfiConverterTypeNativePvmPresentationProfile.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeNativePvmPresentationProfile_lower(_ value: NativePvmPresentationProfile) -> RustBuffer { + return FfiConverterTypeNativePvmPresentationProfile.lower(value) +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterOptionFloat: FfiConverterRustBuffer { + typealias SwiftType = Float? + + public static func write(_ value: SwiftType, into buf: inout [UInt8]) { + guard let value = value else { + writeInt(&buf, Int8(0)) + return + } + writeInt(&buf, Int8(1)) + FfiConverterFloat.write(value, into: &buf) + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType { + switch try readInt(&buf) as Int8 { + case 0: return nil + case 1: return try FfiConverterFloat.read(from: &buf) + default: throw UniffiInternalError.unexpectedOptionalTag + } + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterOptionString: FfiConverterRustBuffer { + typealias SwiftType = String? + + public static func write(_ value: SwiftType, into buf: inout [UInt8]) { + guard let value = value else { + writeInt(&buf, Int8(0)) + return + } + writeInt(&buf, Int8(1)) + FfiConverterString.write(value, into: &buf) + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType { + switch try readInt(&buf) as Int8 { + case 0: return nil + case 1: return try FfiConverterString.read(from: &buf) + default: throw UniffiInternalError.unexpectedOptionalTag + } + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterOptionData: FfiConverterRustBuffer { + typealias SwiftType = Data? + + public static func write(_ value: SwiftType, into buf: inout [UInt8]) { + guard let value = value else { + writeInt(&buf, Int8(0)) + return + } + writeInt(&buf, Int8(1)) + FfiConverterData.write(value, into: &buf) + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType { + switch try readInt(&buf) as Int8 { + case 0: return nil + case 1: return try FfiConverterData.read(from: &buf) + default: throw UniffiInternalError.unexpectedOptionalTag + } + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterOptionTypeNativePvmAudioChunk: FfiConverterRustBuffer { + typealias SwiftType = NativePvmAudioChunk? + + public static func write(_ value: SwiftType, into buf: inout [UInt8]) { + guard let value = value else { + writeInt(&buf, Int8(0)) + return + } + writeInt(&buf, Int8(1)) + FfiConverterTypeNativePvmAudioChunk.write(value, into: &buf) + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType { + switch try readInt(&buf) as Int8 { + case 0: return nil + case 1: return try FfiConverterTypeNativePvmAudioChunk.read(from: &buf) + default: throw UniffiInternalError.unexpectedOptionalTag + } + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterOptionTypeNativePvmFrame: FfiConverterRustBuffer { + typealias SwiftType = NativePvmFrame? + + public static func write(_ value: SwiftType, into buf: inout [UInt8]) { + guard let value = value else { + writeInt(&buf, Int8(0)) + return + } + writeInt(&buf, Int8(1)) + FfiConverterTypeNativePvmFrame.write(value, into: &buf) + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType { + switch try readInt(&buf) as Int8 { + case 0: return nil + case 1: return try FfiConverterTypeNativePvmFrame.read(from: &buf) + default: throw UniffiInternalError.unexpectedOptionalTag + } + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterOptionTypeNativePvmGpuBatch: FfiConverterRustBuffer { + typealias SwiftType = NativePvmGpuBatch? + + public static func write(_ value: SwiftType, into buf: inout [UInt8]) { + guard let value = value else { + writeInt(&buf, Int8(0)) + return + } + writeInt(&buf, Int8(1)) + FfiConverterTypeNativePvmGpuBatch.write(value, into: &buf) + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType { + switch try readInt(&buf) as Int8 { + case 0: return nil + case 1: return try FfiConverterTypeNativePvmGpuBatch.read(from: &buf) + default: throw UniffiInternalError.unexpectedOptionalTag + } + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterOptionTypeNativePvmTri2dFrame: FfiConverterRustBuffer { + typealias SwiftType = NativePvmTri2dFrame? + + public static func write(_ value: SwiftType, into buf: inout [UInt8]) { + guard let value = value else { + writeInt(&buf, Int8(0)) + return + } + writeInt(&buf, Int8(1)) + FfiConverterTypeNativePvmTri2dFrame.write(value, into: &buf) + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType { + switch try readInt(&buf) as Int8 { + case 0: return nil + case 1: return try FfiConverterTypeNativePvmTri2dFrame.read(from: &buf) + default: throw UniffiInternalError.unexpectedOptionalTag + } + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterSequenceInt16: FfiConverterRustBuffer { + typealias SwiftType = [Int16] + + public static func write(_ value: [Int16], into buf: inout [UInt8]) { + let len = Int32(value.count) + writeInt(&buf, len) + for item in value { + FfiConverterInt16.write(item, into: &buf) + } + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [Int16] { + let len: Int32 = try readInt(&buf) + var seq = [Int16]() + seq.reserveCapacity(Int(len)) + for _ in 0 ..< len { + seq.append(try FfiConverterInt16.read(from: &buf)) + } + return seq + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterSequenceTypeNativePvmAsset: FfiConverterRustBuffer { + typealias SwiftType = [NativePvmAsset] + + public static func write(_ value: [NativePvmAsset], into buf: inout [UInt8]) { + let len = Int32(value.count) + writeInt(&buf, len) + for item in value { + FfiConverterTypeNativePvmAsset.write(item, into: &buf) + } + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [NativePvmAsset] { + let len: Int32 = try readInt(&buf) + var seq = [NativePvmAsset]() + seq.reserveCapacity(Int(len)) + for _ in 0 ..< len { + seq.append(try FfiConverterTypeNativePvmAsset.read(from: &buf)) + } + return seq + } +} + +private enum InitializationResult { + case ok + case contractVersionMismatch + case apiChecksumMismatch +} +// Use a global variable to perform the versioning checks. Swift ensures that +// the code inside is only computed once. +private let initializationResult: InitializationResult = { + // Get the bindings contract version from our ComponentInterface + let bindings_contract_version = 30 + // Get the scaffolding contract version by calling the into the dylib + let scaffolding_contract_version = ffi_pvm_runtime_uniffi_contract_version() + if bindings_contract_version != scaffolding_contract_version { + return InitializationResult.contractVersionMismatch + } + if (uniffi_pvm_runtime_checksum_method_nativepvmruntime_backend() != 56657) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_pvm_runtime_checksum_method_nativepvmruntime_clear_motion_tilt() != 37897) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_pvm_runtime_checksum_method_nativepvmruntime_gpu_ready() != 61888) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_pvm_runtime_checksum_method_nativepvmruntime_init() != 58620) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_pvm_runtime_checksum_method_nativepvmruntime_is_exited() != 14672) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_pvm_runtime_checksum_method_nativepvmruntime_last_gas_used() != 63988) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_pvm_runtime_checksum_method_nativepvmruntime_send_gpu_event() != 11805) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_pvm_runtime_checksum_method_nativepvmruntime_send_input() != 59274) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_pvm_runtime_checksum_method_nativepvmruntime_set_gpu_capabilities() != 28903) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_pvm_runtime_checksum_method_nativepvmruntime_set_motion_tilt() != 50848) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_pvm_runtime_checksum_method_nativepvmruntime_take_audio() != 21780) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_pvm_runtime_checksum_method_nativepvmruntime_take_frame() != 8124) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_pvm_runtime_checksum_method_nativepvmruntime_take_gpu_batch() != 14686) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_pvm_runtime_checksum_method_nativepvmruntime_take_log() != 61835) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_pvm_runtime_checksum_method_nativepvmruntime_take_save() != 52485) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_pvm_runtime_checksum_method_nativepvmruntime_take_tri2d() != 20193) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_pvm_runtime_checksum_method_nativepvmruntime_update() != 28698) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_pvm_runtime_checksum_constructor_nativepvmruntime_new() != 25625) { + return InitializationResult.apiChecksumMismatch + } + + return InitializationResult.ok +}() + +// Make the ensure init function public so that other modules which have external type references to +// our types can call it. +public func uniffiEnsurePvmRuntimeInitialized() { + switch initializationResult { + case .ok: + break + case .contractVersionMismatch: + fatalError("UniFFI contract version mismatch: try cleaning and rebuilding your project") + case .apiChecksumMismatch: + fatalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + } +} + +// swiftlint:enable all \ No newline at end of file diff --git a/ios/truapi-host/Sources/pvm_runtimeFFI/include/module.modulemap b/ios/truapi-host/Sources/pvm_runtimeFFI/include/module.modulemap new file mode 100644 index 000000000..6c0b83bd7 --- /dev/null +++ b/ios/truapi-host/Sources/pvm_runtimeFFI/include/module.modulemap @@ -0,0 +1,7 @@ +module pvm_runtimeFFI { + header "pvm_runtimeFFI.h" + export * + use "Darwin" + use "_Builtin_stdbool" + use "_Builtin_stdint" +} \ No newline at end of file diff --git a/ios/truapi-host/Sources/pvm_runtimeFFI/include/pvm_runtimeFFI.h b/ios/truapi-host/Sources/pvm_runtimeFFI/include/pvm_runtimeFFI.h new file mode 100644 index 000000000..baabd1133 --- /dev/null +++ b/ios/truapi-host/Sources/pvm_runtimeFFI/include/pvm_runtimeFFI.h @@ -0,0 +1,720 @@ +// This file was autogenerated by some hot garbage in the `uniffi` crate. +// Trust me, you don't want to mess with it! + +#pragma once + +#include +#include +#include + +// The following structs are used to implement the lowest level +// of the FFI, and thus useful to multiple uniffied crates. +// We ensure they are declared exactly once, with a header guard, UNIFFI_SHARED_H. +#ifdef UNIFFI_SHARED_H + // We also try to prevent mixing versions of shared uniffi header structs. + // If you add anything to the #else block, you must increment the version suffix in UNIFFI_SHARED_HEADER_V4 + #ifndef UNIFFI_SHARED_HEADER_V4 + #error Combining helper code from multiple versions of uniffi is not supported + #endif // ndef UNIFFI_SHARED_HEADER_V4 +#else +#define UNIFFI_SHARED_H +#define UNIFFI_SHARED_HEADER_V4 +// ⚠️ Attention: If you change this #else block (ending in `#endif // def UNIFFI_SHARED_H`) you *must* ⚠️ +// ⚠️ increment the version suffix in all instances of UNIFFI_SHARED_HEADER_V4 in this file. ⚠️ + +typedef struct RustBuffer +{ + uint64_t capacity; + uint64_t len; + uint8_t *_Nullable data; +} RustBuffer; + +typedef struct ForeignBytes +{ + int32_t len; + const uint8_t *_Nullable data; +} ForeignBytes; + +// Error definitions +typedef struct RustCallStatus { + int8_t code; + RustBuffer errorBuf; +} RustCallStatus; + +// ⚠️ Attention: If you change this #else block (ending in `#endif // def UNIFFI_SHARED_H`) you *must* ⚠️ +// ⚠️ increment the version suffix in all instances of UNIFFI_SHARED_HEADER_V4 in this file. ⚠️ +#endif // def UNIFFI_SHARED_H +#ifndef UNIFFI_FFIDEF_RUST_FUTURE_CONTINUATION_CALLBACK +#define UNIFFI_FFIDEF_RUST_FUTURE_CONTINUATION_CALLBACK +typedef void (*UniffiRustFutureContinuationCallback)(uint64_t, int8_t + ); + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_DROPPED_CALLBACK +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_DROPPED_CALLBACK +typedef void (*UniffiForeignFutureDroppedCallback)(uint64_t + ); + +#endif +#ifndef UNIFFI_FFIDEF_CALLBACK_INTERFACE_FREE +#define UNIFFI_FFIDEF_CALLBACK_INTERFACE_FREE +typedef void (*UniffiCallbackInterfaceFree)(uint64_t + ); + +#endif +#ifndef UNIFFI_FFIDEF_CALLBACK_INTERFACE_CLONE +#define UNIFFI_FFIDEF_CALLBACK_INTERFACE_CLONE +typedef uint64_t (*UniffiCallbackInterfaceClone)(uint64_t + ); + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_DROPPED_CALLBACK_STRUCT +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_DROPPED_CALLBACK_STRUCT +typedef struct UniffiForeignFutureDroppedCallbackStruct { + uint64_t handle; + UniffiForeignFutureDroppedCallback _Nonnull free; +} UniffiForeignFutureDroppedCallbackStruct; + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_U8 +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_U8 +typedef struct UniffiForeignFutureResultU8 { + uint8_t returnValue; + RustCallStatus callStatus; +} UniffiForeignFutureResultU8; + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_U8 +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_U8 +typedef void (*UniffiForeignFutureCompleteU8)(uint64_t, UniffiForeignFutureResultU8 + ); + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_I8 +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_I8 +typedef struct UniffiForeignFutureResultI8 { + int8_t returnValue; + RustCallStatus callStatus; +} UniffiForeignFutureResultI8; + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_I8 +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_I8 +typedef void (*UniffiForeignFutureCompleteI8)(uint64_t, UniffiForeignFutureResultI8 + ); + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_U16 +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_U16 +typedef struct UniffiForeignFutureResultU16 { + uint16_t returnValue; + RustCallStatus callStatus; +} UniffiForeignFutureResultU16; + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_U16 +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_U16 +typedef void (*UniffiForeignFutureCompleteU16)(uint64_t, UniffiForeignFutureResultU16 + ); + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_I16 +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_I16 +typedef struct UniffiForeignFutureResultI16 { + int16_t returnValue; + RustCallStatus callStatus; +} UniffiForeignFutureResultI16; + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_I16 +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_I16 +typedef void (*UniffiForeignFutureCompleteI16)(uint64_t, UniffiForeignFutureResultI16 + ); + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_U32 +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_U32 +typedef struct UniffiForeignFutureResultU32 { + uint32_t returnValue; + RustCallStatus callStatus; +} UniffiForeignFutureResultU32; + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_U32 +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_U32 +typedef void (*UniffiForeignFutureCompleteU32)(uint64_t, UniffiForeignFutureResultU32 + ); + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_I32 +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_I32 +typedef struct UniffiForeignFutureResultI32 { + int32_t returnValue; + RustCallStatus callStatus; +} UniffiForeignFutureResultI32; + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_I32 +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_I32 +typedef void (*UniffiForeignFutureCompleteI32)(uint64_t, UniffiForeignFutureResultI32 + ); + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_U64 +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_U64 +typedef struct UniffiForeignFutureResultU64 { + uint64_t returnValue; + RustCallStatus callStatus; +} UniffiForeignFutureResultU64; + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_U64 +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_U64 +typedef void (*UniffiForeignFutureCompleteU64)(uint64_t, UniffiForeignFutureResultU64 + ); + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_I64 +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_I64 +typedef struct UniffiForeignFutureResultI64 { + int64_t returnValue; + RustCallStatus callStatus; +} UniffiForeignFutureResultI64; + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_I64 +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_I64 +typedef void (*UniffiForeignFutureCompleteI64)(uint64_t, UniffiForeignFutureResultI64 + ); + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_F32 +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_F32 +typedef struct UniffiForeignFutureResultF32 { + float returnValue; + RustCallStatus callStatus; +} UniffiForeignFutureResultF32; + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_F32 +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_F32 +typedef void (*UniffiForeignFutureCompleteF32)(uint64_t, UniffiForeignFutureResultF32 + ); + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_F64 +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_F64 +typedef struct UniffiForeignFutureResultF64 { + double returnValue; + RustCallStatus callStatus; +} UniffiForeignFutureResultF64; + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_F64 +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_F64 +typedef void (*UniffiForeignFutureCompleteF64)(uint64_t, UniffiForeignFutureResultF64 + ); + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_RUST_BUFFER +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_RUST_BUFFER +typedef struct UniffiForeignFutureResultRustBuffer { + RustBuffer returnValue; + RustCallStatus callStatus; +} UniffiForeignFutureResultRustBuffer; + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_RUST_BUFFER +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_RUST_BUFFER +typedef void (*UniffiForeignFutureCompleteRustBuffer)(uint64_t, UniffiForeignFutureResultRustBuffer + ); + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_VOID +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_VOID +typedef struct UniffiForeignFutureResultVoid { + RustCallStatus callStatus; +} UniffiForeignFutureResultVoid; + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_VOID +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_VOID +typedef void (*UniffiForeignFutureCompleteVoid)(uint64_t, UniffiForeignFutureResultVoid + ); + +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_FN_CLONE_NATIVEPVMRUNTIME +#define UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_FN_CLONE_NATIVEPVMRUNTIME +uint64_t uniffi_pvm_runtime_fn_clone_nativepvmruntime(uint64_t handle, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_FN_FREE_NATIVEPVMRUNTIME +#define UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_FN_FREE_NATIVEPVMRUNTIME +void uniffi_pvm_runtime_fn_free_nativepvmruntime(uint64_t handle, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_FN_CONSTRUCTOR_NATIVEPVMRUNTIME_NEW +#define UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_FN_CONSTRUCTOR_NATIVEPVMRUNTIME_NEW +uint64_t uniffi_pvm_runtime_fn_constructor_nativepvmruntime_new(RustBuffer program, RustBuffer assets, RustBuffer presentation, int8_t audio_enabled, uint64_t max_gas_per_update, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_FN_METHOD_NATIVEPVMRUNTIME_BACKEND +#define UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_FN_METHOD_NATIVEPVMRUNTIME_BACKEND +RustBuffer uniffi_pvm_runtime_fn_method_nativepvmruntime_backend(uint64_t ptr, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_FN_METHOD_NATIVEPVMRUNTIME_CLEAR_MOTION_TILT +#define UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_FN_METHOD_NATIVEPVMRUNTIME_CLEAR_MOTION_TILT +void uniffi_pvm_runtime_fn_method_nativepvmruntime_clear_motion_tilt(uint64_t ptr, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_FN_METHOD_NATIVEPVMRUNTIME_GPU_READY +#define UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_FN_METHOD_NATIVEPVMRUNTIME_GPU_READY +int8_t uniffi_pvm_runtime_fn_method_nativepvmruntime_gpu_ready(uint64_t ptr, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_FN_METHOD_NATIVEPVMRUNTIME_INIT +#define UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_FN_METHOD_NATIVEPVMRUNTIME_INIT +void uniffi_pvm_runtime_fn_method_nativepvmruntime_init(uint64_t ptr, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_FN_METHOD_NATIVEPVMRUNTIME_IS_EXITED +#define UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_FN_METHOD_NATIVEPVMRUNTIME_IS_EXITED +int8_t uniffi_pvm_runtime_fn_method_nativepvmruntime_is_exited(uint64_t ptr, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_FN_METHOD_NATIVEPVMRUNTIME_LAST_GAS_USED +#define UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_FN_METHOD_NATIVEPVMRUNTIME_LAST_GAS_USED +uint64_t uniffi_pvm_runtime_fn_method_nativepvmruntime_last_gas_used(uint64_t ptr, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_FN_METHOD_NATIVEPVMRUNTIME_SEND_GPU_EVENT +#define UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_FN_METHOD_NATIVEPVMRUNTIME_SEND_GPU_EVENT +void uniffi_pvm_runtime_fn_method_nativepvmruntime_send_gpu_event(uint64_t ptr, RustBuffer bytes, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_FN_METHOD_NATIVEPVMRUNTIME_SEND_INPUT +#define UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_FN_METHOD_NATIVEPVMRUNTIME_SEND_INPUT +void uniffi_pvm_runtime_fn_method_nativepvmruntime_send_input(uint64_t ptr, RustBuffer event_type, uint8_t code, uint16_t x, uint16_t y, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_FN_METHOD_NATIVEPVMRUNTIME_SET_GPU_CAPABILITIES +#define UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_FN_METHOD_NATIVEPVMRUNTIME_SET_GPU_CAPABILITIES +void uniffi_pvm_runtime_fn_method_nativepvmruntime_set_gpu_capabilities(uint64_t ptr, RustBuffer bytes, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_FN_METHOD_NATIVEPVMRUNTIME_SET_MOTION_TILT +#define UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_FN_METHOD_NATIVEPVMRUNTIME_SET_MOTION_TILT +void uniffi_pvm_runtime_fn_method_nativepvmruntime_set_motion_tilt(uint64_t ptr, RustBuffer sample, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_FN_METHOD_NATIVEPVMRUNTIME_TAKE_AUDIO +#define UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_FN_METHOD_NATIVEPVMRUNTIME_TAKE_AUDIO +RustBuffer uniffi_pvm_runtime_fn_method_nativepvmruntime_take_audio(uint64_t ptr, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_FN_METHOD_NATIVEPVMRUNTIME_TAKE_FRAME +#define UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_FN_METHOD_NATIVEPVMRUNTIME_TAKE_FRAME +RustBuffer uniffi_pvm_runtime_fn_method_nativepvmruntime_take_frame(uint64_t ptr, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_FN_METHOD_NATIVEPVMRUNTIME_TAKE_GPU_BATCH +#define UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_FN_METHOD_NATIVEPVMRUNTIME_TAKE_GPU_BATCH +RustBuffer uniffi_pvm_runtime_fn_method_nativepvmruntime_take_gpu_batch(uint64_t ptr, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_FN_METHOD_NATIVEPVMRUNTIME_TAKE_LOG +#define UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_FN_METHOD_NATIVEPVMRUNTIME_TAKE_LOG +RustBuffer uniffi_pvm_runtime_fn_method_nativepvmruntime_take_log(uint64_t ptr, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_FN_METHOD_NATIVEPVMRUNTIME_TAKE_SAVE +#define UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_FN_METHOD_NATIVEPVMRUNTIME_TAKE_SAVE +RustBuffer uniffi_pvm_runtime_fn_method_nativepvmruntime_take_save(uint64_t ptr, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_FN_METHOD_NATIVEPVMRUNTIME_TAKE_TRI2D +#define UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_FN_METHOD_NATIVEPVMRUNTIME_TAKE_TRI2D +RustBuffer uniffi_pvm_runtime_fn_method_nativepvmruntime_take_tri2d(uint64_t ptr, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_FN_METHOD_NATIVEPVMRUNTIME_UPDATE +#define UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_FN_METHOD_NATIVEPVMRUNTIME_UPDATE +void uniffi_pvm_runtime_fn_method_nativepvmruntime_update(uint64_t ptr, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUSTBUFFER_ALLOC +#define UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUSTBUFFER_ALLOC +RustBuffer ffi_pvm_runtime_rustbuffer_alloc(uint64_t size, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUSTBUFFER_FROM_BYTES +#define UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUSTBUFFER_FROM_BYTES +RustBuffer ffi_pvm_runtime_rustbuffer_from_bytes(ForeignBytes bytes, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUSTBUFFER_FREE +#define UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUSTBUFFER_FREE +void ffi_pvm_runtime_rustbuffer_free(RustBuffer buf, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUSTBUFFER_RESERVE +#define UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUSTBUFFER_RESERVE +RustBuffer ffi_pvm_runtime_rustbuffer_reserve(RustBuffer buf, uint64_t additional, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_POLL_U8 +#define UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_POLL_U8 +void ffi_pvm_runtime_rust_future_poll_u8(uint64_t handle, UniffiRustFutureContinuationCallback _Nonnull callback, uint64_t callback_data +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_CANCEL_U8 +#define UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_CANCEL_U8 +void ffi_pvm_runtime_rust_future_cancel_u8(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_FREE_U8 +#define UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_FREE_U8 +void ffi_pvm_runtime_rust_future_free_u8(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_COMPLETE_U8 +#define UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_COMPLETE_U8 +uint8_t ffi_pvm_runtime_rust_future_complete_u8(uint64_t handle, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_POLL_I8 +#define UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_POLL_I8 +void ffi_pvm_runtime_rust_future_poll_i8(uint64_t handle, UniffiRustFutureContinuationCallback _Nonnull callback, uint64_t callback_data +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_CANCEL_I8 +#define UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_CANCEL_I8 +void ffi_pvm_runtime_rust_future_cancel_i8(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_FREE_I8 +#define UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_FREE_I8 +void ffi_pvm_runtime_rust_future_free_i8(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_COMPLETE_I8 +#define UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_COMPLETE_I8 +int8_t ffi_pvm_runtime_rust_future_complete_i8(uint64_t handle, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_POLL_U16 +#define UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_POLL_U16 +void ffi_pvm_runtime_rust_future_poll_u16(uint64_t handle, UniffiRustFutureContinuationCallback _Nonnull callback, uint64_t callback_data +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_CANCEL_U16 +#define UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_CANCEL_U16 +void ffi_pvm_runtime_rust_future_cancel_u16(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_FREE_U16 +#define UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_FREE_U16 +void ffi_pvm_runtime_rust_future_free_u16(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_COMPLETE_U16 +#define UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_COMPLETE_U16 +uint16_t ffi_pvm_runtime_rust_future_complete_u16(uint64_t handle, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_POLL_I16 +#define UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_POLL_I16 +void ffi_pvm_runtime_rust_future_poll_i16(uint64_t handle, UniffiRustFutureContinuationCallback _Nonnull callback, uint64_t callback_data +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_CANCEL_I16 +#define UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_CANCEL_I16 +void ffi_pvm_runtime_rust_future_cancel_i16(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_FREE_I16 +#define UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_FREE_I16 +void ffi_pvm_runtime_rust_future_free_i16(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_COMPLETE_I16 +#define UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_COMPLETE_I16 +int16_t ffi_pvm_runtime_rust_future_complete_i16(uint64_t handle, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_POLL_U32 +#define UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_POLL_U32 +void ffi_pvm_runtime_rust_future_poll_u32(uint64_t handle, UniffiRustFutureContinuationCallback _Nonnull callback, uint64_t callback_data +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_CANCEL_U32 +#define UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_CANCEL_U32 +void ffi_pvm_runtime_rust_future_cancel_u32(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_FREE_U32 +#define UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_FREE_U32 +void ffi_pvm_runtime_rust_future_free_u32(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_COMPLETE_U32 +#define UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_COMPLETE_U32 +uint32_t ffi_pvm_runtime_rust_future_complete_u32(uint64_t handle, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_POLL_I32 +#define UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_POLL_I32 +void ffi_pvm_runtime_rust_future_poll_i32(uint64_t handle, UniffiRustFutureContinuationCallback _Nonnull callback, uint64_t callback_data +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_CANCEL_I32 +#define UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_CANCEL_I32 +void ffi_pvm_runtime_rust_future_cancel_i32(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_FREE_I32 +#define UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_FREE_I32 +void ffi_pvm_runtime_rust_future_free_i32(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_COMPLETE_I32 +#define UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_COMPLETE_I32 +int32_t ffi_pvm_runtime_rust_future_complete_i32(uint64_t handle, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_POLL_U64 +#define UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_POLL_U64 +void ffi_pvm_runtime_rust_future_poll_u64(uint64_t handle, UniffiRustFutureContinuationCallback _Nonnull callback, uint64_t callback_data +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_CANCEL_U64 +#define UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_CANCEL_U64 +void ffi_pvm_runtime_rust_future_cancel_u64(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_FREE_U64 +#define UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_FREE_U64 +void ffi_pvm_runtime_rust_future_free_u64(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_COMPLETE_U64 +#define UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_COMPLETE_U64 +uint64_t ffi_pvm_runtime_rust_future_complete_u64(uint64_t handle, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_POLL_I64 +#define UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_POLL_I64 +void ffi_pvm_runtime_rust_future_poll_i64(uint64_t handle, UniffiRustFutureContinuationCallback _Nonnull callback, uint64_t callback_data +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_CANCEL_I64 +#define UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_CANCEL_I64 +void ffi_pvm_runtime_rust_future_cancel_i64(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_FREE_I64 +#define UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_FREE_I64 +void ffi_pvm_runtime_rust_future_free_i64(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_COMPLETE_I64 +#define UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_COMPLETE_I64 +int64_t ffi_pvm_runtime_rust_future_complete_i64(uint64_t handle, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_POLL_F32 +#define UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_POLL_F32 +void ffi_pvm_runtime_rust_future_poll_f32(uint64_t handle, UniffiRustFutureContinuationCallback _Nonnull callback, uint64_t callback_data +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_CANCEL_F32 +#define UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_CANCEL_F32 +void ffi_pvm_runtime_rust_future_cancel_f32(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_FREE_F32 +#define UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_FREE_F32 +void ffi_pvm_runtime_rust_future_free_f32(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_COMPLETE_F32 +#define UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_COMPLETE_F32 +float ffi_pvm_runtime_rust_future_complete_f32(uint64_t handle, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_POLL_F64 +#define UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_POLL_F64 +void ffi_pvm_runtime_rust_future_poll_f64(uint64_t handle, UniffiRustFutureContinuationCallback _Nonnull callback, uint64_t callback_data +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_CANCEL_F64 +#define UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_CANCEL_F64 +void ffi_pvm_runtime_rust_future_cancel_f64(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_FREE_F64 +#define UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_FREE_F64 +void ffi_pvm_runtime_rust_future_free_f64(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_COMPLETE_F64 +#define UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_COMPLETE_F64 +double ffi_pvm_runtime_rust_future_complete_f64(uint64_t handle, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_POLL_RUST_BUFFER +#define UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_POLL_RUST_BUFFER +void ffi_pvm_runtime_rust_future_poll_rust_buffer(uint64_t handle, UniffiRustFutureContinuationCallback _Nonnull callback, uint64_t callback_data +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_CANCEL_RUST_BUFFER +#define UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_CANCEL_RUST_BUFFER +void ffi_pvm_runtime_rust_future_cancel_rust_buffer(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_FREE_RUST_BUFFER +#define UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_FREE_RUST_BUFFER +void ffi_pvm_runtime_rust_future_free_rust_buffer(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_COMPLETE_RUST_BUFFER +#define UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_COMPLETE_RUST_BUFFER +RustBuffer ffi_pvm_runtime_rust_future_complete_rust_buffer(uint64_t handle, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_POLL_VOID +#define UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_POLL_VOID +void ffi_pvm_runtime_rust_future_poll_void(uint64_t handle, UniffiRustFutureContinuationCallback _Nonnull callback, uint64_t callback_data +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_CANCEL_VOID +#define UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_CANCEL_VOID +void ffi_pvm_runtime_rust_future_cancel_void(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_FREE_VOID +#define UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_FREE_VOID +void ffi_pvm_runtime_rust_future_free_void(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_COMPLETE_VOID +#define UNIFFI_FFIDEF_FFI_PVM_RUNTIME_RUST_FUTURE_COMPLETE_VOID +void ffi_pvm_runtime_rust_future_complete_void(uint64_t handle, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_CHECKSUM_METHOD_NATIVEPVMRUNTIME_BACKEND +#define UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_CHECKSUM_METHOD_NATIVEPVMRUNTIME_BACKEND +uint16_t uniffi_pvm_runtime_checksum_method_nativepvmruntime_backend(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_CHECKSUM_METHOD_NATIVEPVMRUNTIME_CLEAR_MOTION_TILT +#define UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_CHECKSUM_METHOD_NATIVEPVMRUNTIME_CLEAR_MOTION_TILT +uint16_t uniffi_pvm_runtime_checksum_method_nativepvmruntime_clear_motion_tilt(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_CHECKSUM_METHOD_NATIVEPVMRUNTIME_GPU_READY +#define UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_CHECKSUM_METHOD_NATIVEPVMRUNTIME_GPU_READY +uint16_t uniffi_pvm_runtime_checksum_method_nativepvmruntime_gpu_ready(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_CHECKSUM_METHOD_NATIVEPVMRUNTIME_INIT +#define UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_CHECKSUM_METHOD_NATIVEPVMRUNTIME_INIT +uint16_t uniffi_pvm_runtime_checksum_method_nativepvmruntime_init(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_CHECKSUM_METHOD_NATIVEPVMRUNTIME_IS_EXITED +#define UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_CHECKSUM_METHOD_NATIVEPVMRUNTIME_IS_EXITED +uint16_t uniffi_pvm_runtime_checksum_method_nativepvmruntime_is_exited(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_CHECKSUM_METHOD_NATIVEPVMRUNTIME_LAST_GAS_USED +#define UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_CHECKSUM_METHOD_NATIVEPVMRUNTIME_LAST_GAS_USED +uint16_t uniffi_pvm_runtime_checksum_method_nativepvmruntime_last_gas_used(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_CHECKSUM_METHOD_NATIVEPVMRUNTIME_SEND_GPU_EVENT +#define UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_CHECKSUM_METHOD_NATIVEPVMRUNTIME_SEND_GPU_EVENT +uint16_t uniffi_pvm_runtime_checksum_method_nativepvmruntime_send_gpu_event(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_CHECKSUM_METHOD_NATIVEPVMRUNTIME_SEND_INPUT +#define UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_CHECKSUM_METHOD_NATIVEPVMRUNTIME_SEND_INPUT +uint16_t uniffi_pvm_runtime_checksum_method_nativepvmruntime_send_input(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_CHECKSUM_METHOD_NATIVEPVMRUNTIME_SET_GPU_CAPABILITIES +#define UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_CHECKSUM_METHOD_NATIVEPVMRUNTIME_SET_GPU_CAPABILITIES +uint16_t uniffi_pvm_runtime_checksum_method_nativepvmruntime_set_gpu_capabilities(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_CHECKSUM_METHOD_NATIVEPVMRUNTIME_SET_MOTION_TILT +#define UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_CHECKSUM_METHOD_NATIVEPVMRUNTIME_SET_MOTION_TILT +uint16_t uniffi_pvm_runtime_checksum_method_nativepvmruntime_set_motion_tilt(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_CHECKSUM_METHOD_NATIVEPVMRUNTIME_TAKE_AUDIO +#define UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_CHECKSUM_METHOD_NATIVEPVMRUNTIME_TAKE_AUDIO +uint16_t uniffi_pvm_runtime_checksum_method_nativepvmruntime_take_audio(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_CHECKSUM_METHOD_NATIVEPVMRUNTIME_TAKE_FRAME +#define UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_CHECKSUM_METHOD_NATIVEPVMRUNTIME_TAKE_FRAME +uint16_t uniffi_pvm_runtime_checksum_method_nativepvmruntime_take_frame(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_CHECKSUM_METHOD_NATIVEPVMRUNTIME_TAKE_GPU_BATCH +#define UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_CHECKSUM_METHOD_NATIVEPVMRUNTIME_TAKE_GPU_BATCH +uint16_t uniffi_pvm_runtime_checksum_method_nativepvmruntime_take_gpu_batch(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_CHECKSUM_METHOD_NATIVEPVMRUNTIME_TAKE_LOG +#define UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_CHECKSUM_METHOD_NATIVEPVMRUNTIME_TAKE_LOG +uint16_t uniffi_pvm_runtime_checksum_method_nativepvmruntime_take_log(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_CHECKSUM_METHOD_NATIVEPVMRUNTIME_TAKE_SAVE +#define UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_CHECKSUM_METHOD_NATIVEPVMRUNTIME_TAKE_SAVE +uint16_t uniffi_pvm_runtime_checksum_method_nativepvmruntime_take_save(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_CHECKSUM_METHOD_NATIVEPVMRUNTIME_TAKE_TRI2D +#define UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_CHECKSUM_METHOD_NATIVEPVMRUNTIME_TAKE_TRI2D +uint16_t uniffi_pvm_runtime_checksum_method_nativepvmruntime_take_tri2d(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_CHECKSUM_METHOD_NATIVEPVMRUNTIME_UPDATE +#define UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_CHECKSUM_METHOD_NATIVEPVMRUNTIME_UPDATE +uint16_t uniffi_pvm_runtime_checksum_method_nativepvmruntime_update(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_CHECKSUM_CONSTRUCTOR_NATIVEPVMRUNTIME_NEW +#define UNIFFI_FFIDEF_UNIFFI_PVM_RUNTIME_CHECKSUM_CONSTRUCTOR_NATIVEPVMRUNTIME_NEW +uint16_t uniffi_pvm_runtime_checksum_constructor_nativepvmruntime_new(void + +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_PVM_RUNTIME_UNIFFI_CONTRACT_VERSION +#define UNIFFI_FFIDEF_FFI_PVM_RUNTIME_UNIFFI_CONTRACT_VERSION +uint32_t ffi_pvm_runtime_uniffi_contract_version(void + +); +#endif + diff --git a/ios/truapi-host/scripts/sync-bindings.sh b/ios/truapi-host/scripts/sync-bindings.sh index 2305ca71f..76b5ec152 100755 --- a/ios/truapi-host/scripts/sync-bindings.sh +++ b/ios/truapi-host/scripts/sync-bindings.sh @@ -14,7 +14,7 @@ PACKAGE_ROOT="$(cd "$(dirname "$0")/.." && pwd)" TRUAPI_ROOT="$(cd "$PACKAGE_ROOT/../.." && pwd)" UNIFFI_OUT="$TRUAPI_ROOT/target/uniffi-swift-out" -NAMESPACES="truapi truapi_platform truapi_server" +NAMESPACES="truapi truapi_platform truapi_server pvm_runtime" CHECK_ONLY=0 case "${1-}" in diff --git a/rust/crates/truapi-host-cli/src/frame_server.rs b/rust/crates/truapi-host-cli/src/frame_server.rs index 564f9113e..25fce795d 100644 --- a/rust/crates/truapi-host-cli/src/frame_server.rs +++ b/rust/crates/truapi-host-cli/src/frame_server.rs @@ -108,6 +108,9 @@ pub trait ProductRuntimeFactory: Send + Sync + 'static { } } +// async-trait's generated boxed Future is already must-use; newer Clippy +// otherwise reports the macro's duplicate annotation on this private trait. +#[allow(clippy::double_must_use)] #[async_trait::async_trait] trait ConnectionRuntime: Send + Sync + 'static { async fn receive_frame(&self, frame: Vec) -> Result<(), ProductRuntimeError>; diff --git a/rust/crates/truapi-pvm-host/Cargo.toml b/rust/crates/truapi-pvm-host/Cargo.toml new file mode 100644 index 000000000..fe403051a --- /dev/null +++ b/rust/crates/truapi-pvm-host/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "truapi-pvm-host" +version = "0.1.0" +edition.workspace = true +description = "Reviewed host-rust-core bridge to the standalone PolkaVM application runtime" +license = "MIT" +repository = "https://github.com/paritytech/host-rust-core" +publish = false + +[features] +default = [] +ffi = ["pvm-runtime/ffi"] +browser-assets = ["dep:pvm-runtime-assets"] + +[dependencies] +pvm-runtime = { git = "https://github.com/paritytech/pvm-host-runtime.git", rev = "86d4d78e8bdd4a6c8b024d5895607e6a7b19c180" } +pvm-runtime-assets = { git = "https://github.com/paritytech/pvm-host-runtime.git", rev = "86d4d78e8bdd4a6c8b024d5895607e6a7b19c180", optional = true } + +[lints] +workspace = true + +[[bin]] +name = "pvm-assets-export" +path = "src/bin/pvm-assets-export.rs" +required-features = ["browser-assets"] diff --git a/rust/crates/truapi-pvm-host/src/bin/pvm-assets-export.rs b/rust/crates/truapi-pvm-host/src/bin/pvm-assets-export.rs new file mode 100644 index 000000000..f2d3d8d6e --- /dev/null +++ b/rust/crates/truapi-pvm-host/src/bin/pvm-assets-export.rs @@ -0,0 +1,28 @@ +//! Exports the browser asset set pinned by `truapi-pvm-host`. + +use std::path::PathBuf; + +use truapi_pvm_host::browser_assets; + +fn main() -> Result<(), Box> { + let mut arguments = std::env::args_os().skip(1); + let flag = arguments.next(); + let output = arguments.next(); + if flag.as_deref() != Some(std::ffi::OsStr::new("--output")) + || output.is_none() + || arguments.next().is_some() + { + return Err("usage: pvm-assets-export --output ".into()); + } + + let output = PathBuf::from(output.expect("validated output argument")); + std::fs::create_dir_all(&output)?; + for asset in browser_assets() { + let destination = output.join(asset.path); + if let Some(parent) = destination.parent() { + std::fs::create_dir_all(parent)?; + } + std::fs::write(destination, asset.bytes)?; + } + Ok(()) +} diff --git a/rust/crates/truapi-pvm-host/src/lib.rs b/rust/crates/truapi-pvm-host/src/lib.rs new file mode 100644 index 000000000..701d3a085 --- /dev/null +++ b/rust/crates/truapi-pvm-host/src/lib.rs @@ -0,0 +1,40 @@ +//! Stable host-rust-core bridge to the standalone PolkaVM application runtime. +//! +//! Host applications depend on this crate rather than pinning the standalone +//! runtime repository directly. The bridge revision identifies one reviewed +//! native runtime, GPU wire contract, and browser asset set. + +pub use pvm_runtime::*; + +#[cfg(feature = "browser-assets")] +pub use pvm_runtime_assets::{BrowserAsset, RUNTIME_VERSION, browser_assets}; + +/// Immutable standalone runtime source consumed by this bridge release. +pub const RUNTIME_SOURCE_REVISION: &str = "86d4d78e8bdd4a6c8b024d5895607e6a7b19c180"; + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn source_revision_is_immutable() { + assert_eq!(RUNTIME_SOURCE_REVISION.len(), 40); + assert!( + RUNTIME_SOURCE_REVISION + .bytes() + .all(|byte| byte.is_ascii_hexdigit() && !byte.is_ascii_uppercase()) + ); + } + + #[cfg(feature = "browser-assets")] + #[test] + fn browser_assets_are_complete_and_source_identified() { + assert_eq!(RUNTIME_VERSION, "0.1.6"); + assert_eq!(browser_assets().len(), 7); + assert!( + browser_assets() + .iter() + .any(|asset| asset.path == "pvm-browser-runtime.wasm") + ); + } +} diff --git a/rust/crates/truapi-server/Cargo.toml b/rust/crates/truapi-server/Cargo.toml index e941f6c27..44dc365c0 100644 --- a/rust/crates/truapi-server/Cargo.toml +++ b/rust/crates/truapi-server/Cargo.toml @@ -68,6 +68,7 @@ verifiable = { git = "https://github.com/paritytech/verifiable.git", rev = "19b0 [target.'cfg(not(target_arch = "wasm32"))'.dependencies] truapi = { path = "../truapi", features = ["uniffi"] } +truapi-pvm-host = { path = "../truapi-pvm-host", features = ["ffi"] } truapi-platform = { path = "../truapi-platform", features = ["uniffi"] } futures = { version = "0.3", features = ["thread-pool"] } rand = { version = "0.8", optional = true } diff --git a/rust/crates/truapi-server/src/lib.rs b/rust/crates/truapi-server/src/lib.rs index 8b9ef7f53..f6b9344cd 100644 --- a/rust/crates/truapi-server/src/lib.rs +++ b/rust/crates/truapi-server/src/lib.rs @@ -49,6 +49,10 @@ pub mod native_renderer; #[cfg(target_arch = "wasm32")] pub mod wasm; +/// Host-neutral PolkaVM application runtime exposed through the reviewed bridge. +#[cfg(not(target_arch = "wasm32"))] +pub use truapi_pvm_host as pvm; + pub use host_core::{ FrameSink, HostAdmin, PairingHostRuntime, ProductRuntime, ProductRuntimeControl, ProductRuntimeError, SigningHostRuntime, @@ -94,3 +98,6 @@ truapi::uniffi_reexport_scaffolding!(); #[cfg(not(target_arch = "wasm32"))] truapi_platform::uniffi_reexport_scaffolding!(); + +#[cfg(not(target_arch = "wasm32"))] +truapi_pvm_host::uniffi_reexport_scaffolding!();