From be73672c8dc0686f2f38b33aab1f15a5622eeb52 Mon Sep 17 00:00:00 2001 From: lorenzomicheli Date: Mon, 12 Oct 2026 13:44:59 +0000 Subject: [PATCH] Docs: draft issue asking gpui-mobile where hot reload should live Not posted. longbridge/gpui-mobile has Discussions off, so it's an issue draft: what cargo-gpui is (Subsecond, credit to Dioxus), the measured times, the split (tool and crates standalone; GpuiLibraryLoader proposed for gpui-mobile), and the question of where they'd like it. Co-Authored-By: Claude Opus 5.5 --- CONTRIBUTING_IDEAS.md | 3 +- MOBILE_PATCHES.md | 3 +- docs/upstream/README.md | 1 + docs/upstream/hot-reload-discussion.md | 89 ++++++++++++++++++++++++++ 4 files changed, 94 insertions(+), 2 deletions(-) create mode 100644 docs/upstream/hot-reload-discussion.md diff --git a/CONTRIBUTING_IDEAS.md b/CONTRIBUTING_IDEAS.md index b26ea08..b4f8d05 100644 --- a/CONTRIBUTING_IDEAS.md +++ b/CONTRIBUTING_IDEAS.md @@ -98,7 +98,8 @@ October 2026; "fork" means the fix is on one of the branches listed in screen in 3.3–3.6 s through an ssh adb tunnel, state kept) and reloads the library without reinstalling (8.3 s). gpui-mobile only needs a loader for the pushed library (`GpuiLibraryLoader`, fork branch - `dev-hot-loader`). Next: ask upstream where they want it. A desktop-hosted + `dev-hot-loader`). Next: ask upstream where they want it + ([issue draft](docs/upstream/hot-reload-discussion.md)). A desktop-hosted phone-size preview is not started. 5. **Binary size.** Measured in [docs/binary-size.md](docs/binary-size.md); every PR's job summary shows the APK and `.so` sizes. diff --git a/MOBILE_PATCHES.md b/MOBILE_PATCHES.md index 5ce00c4..e72cf89 100644 --- a/MOBILE_PATCHES.md +++ b/MOBILE_PATCHES.md @@ -119,7 +119,8 @@ has pushed one, else the packaged library. Release builds always load the packaged one. It replaces the `loadLibrary()` the lab's `LabActivity` carried; `build.sh` copies it with the other helpers. Host-driven Activities only (`NativeActivity` loads the packaged library itself). Not proposed -upstream yet. +upstream yet: an [issue draft](docs/upstream/hot-reload-discussion.md) asks +the maintainers first. ### Clear the Java exceptions the accessibility bridge leaves pending — branch `android-a11y-clear-exceptions`, now part of `android-accessibility` diff --git a/docs/upstream/README.md b/docs/upstream/README.md index f3f395d..2cedf90 100644 --- a/docs/upstream/README.md +++ b/docs/upstream/README.md @@ -39,6 +39,7 @@ captures in [../demos](../demos) and say where a capture is missing. | 17 | kit | `input-purpose` (fork branch only) | ⛔ | #4, plus the same GPUI change; conflicts with `main` (to rebase then) | yes | — | | 18 | mobile | `android-activity-requests`, `android-picker-files` (fork only) | ⛔ | the JNI rework (issue #31): built on its `jni.rs` | partly ([picker screenshots](../demos/platform-apis)) | — | | 19 | mobile | `android-string-arrays` (fork only) | ⛔ | #6, plus the JNI rework (#31): `contacts/android.rs` was rewritten there | no | — | +| 20 | mobile | [`dev-hot-loader`](https://github.com/Bombatomica64/gpui-mobile/tree/dev-hot-loader) (`GpuiLibraryLoader`) | ⏳ ask first: an issue asking where hot reload should live; the PR only if they want it | — | phone strip from the A1 spike | [issue draft](hot-reload-discussion.md) | Notes on the triage: diff --git a/docs/upstream/hot-reload-discussion.md b/docs/upstream/hot-reload-discussion.md new file mode 100644 index 0000000..842a379 --- /dev/null +++ b/docs/upstream/hot-reload-discussion.md @@ -0,0 +1,89 @@ +# Draft: hot reload for gpui-mobile apps (not posted) + +> **Status: draft for review, not posted.** longbridge/gpui-mobile has GitHub +> Discussions turned off, so this would be an **issue**. Title: +> "Hot reload for Rust on Android: interested, and where should it live?" + +--- + +Hi! While building a test app on gpui-mobile we made Rust hot reload work on +Android, and we'd like to know whether you find it useful and where you'd +like it to live. + +## What it is + +[cargo-gpui](https://github.com/Bombatomica64/cargo-gpui) is a small dev tool +plus an app-side crate: + +- **Hot patching.** On save, `cargo gpui dev` recompiles only the app crate, + links a small patch library against the running app and pushes it. The app + swaps in the new code between frames, and the screen, typed text and view + state stay. It's built on [Subsecond](https://docs.rs/subsecond) from + [Dioxus](https://github.com/DioxusLabs/dioxus); the patch builder adapts + parts of the Dioxus CLI (`dx serve --hotpatch`), with credit and its MIT + notice in the repo. +- **Reload without reinstalling**, for the changes a patch can't make (struct + layout, dependencies): the tool rebuilds the library, pushes a zstd delta + (~1.4 MB) and restarts the app on the same screen. No Gradle, no APK + install. + +Views opt in with an attribute on their `Render` impl: + +```rust +#[gpui_hot::hot] +impl Render for Counter { + fn render(&mut self, window: &mut Window, cx: &mut Context) -> impl IntoElement { + div().child(format!("{}", self.count)) + } +} +``` + +It's debug-only: release builds compile the hooks to nothing. + +## Numbers + +Measured on a OnePlus phone (Android 16) reached over an ssh adb tunnel, +with a 32-screen test app: + +| Step | Time | +|---|---| +| Save → change on screen (patch) | 3.3–3.6 s | +| Reload with a 1.4 MB delta, same screen | 8.3 s | + +Over USB the push part (~1.5 s of each patch) should shrink; we haven't +measured that yet. + +![Patches applied on the phone](https://raw.githubusercontent.com/Bombatomica64/Gpui-android/main/docs/demos/subsecond-buttons-patches.png) + +*From our first prototype: a title, a colour and a layout changed live while +the click counter kept its value (3).* + +## How it's split + +- **Outside gpui-mobile** (the repo above, MIT OR Apache-2.0): the + `cargo gpui` CLI, the `gpui-hot` crate and its attribute macro. They depend + on GPUI and Subsecond, not on gpui-mobile. +- **Inside gpui-mobile**, one small piece: a Java helper, + `GpuiLibraryLoader`, that a host-driven Activity calls instead of + `System.loadLibrary`. In a debuggable build it loads + `files/dev/lib.so` when a dev tool has pushed one; release builds + always load the packaged library. It's opt-in, about 50 lines, and adds no + Rust code or dependency. It's on our fork as branch + [`dev-hot-loader`](https://github.com/Bombatomica64/gpui-mobile/blob/dev-hot-loader/example/android/gradle/app/src/main/java/dev/gpui/mobile/GpuiLibraryLoader.java), + based on your `main`. + +## Questions + +1. Is this useful to you? +2. Where would you like it? + - keep it as a separate project that apps opt into; + - move the tool under longbridge; + - or bring it into gpui-mobile itself. +3. Would you take `GpuiLibraryLoader` as a small PR? We can open it + whenever you like. + +Known limits: Android arm64 debug builds only; host-driven Activities only +for reloads (`NativeActivity` loads the packaged library itself); statics in +the app crate restart from their initial values after a patch. + +Thanks for gpui-mobile!