iris is the framework alone; the app is one crate in app-rust/
Iris: "the organization of the rust rewrite is a mess right now... there shouldn't be anything related to the app inside of iris. Iris is supposed to be the UI framework alone." And, on the crate count: "I'm confused why the app only code needs more than one crate though." Nine cargo workspaces become three, and the port's project code -- which sat in five places, four of them inside the framework -- becomes one crate, `ai-app`, in `app-rust/`: client-core -> app-rust/src/client iris/transcript-ui -> app-rust/src/ui iris/transcript-fixture -> app-rust/src/ui/fixture.rs + tests/ + touch/ iris/desktop-app -> app-rust/src/desktop + src/bin_desktop.rs iris/android-app -> app-rust/src/android + android-project/ android-shell -> app-rust/src/shell iris/ keeps core, macro, the iris crate, tabs-ui and rig-input, and now mentions no session, transcript, setup or server anywhere. Only two of the old splits had a reason that survived reading. event-model stays a crate at the repo root because server/ depends on it too, so a crate is what makes the backend and the app agree by construction. The two Android .so names looked like a hard constraint -- a package produces one library artifact -- until P2 turned out to already plan merging those two Android apps into one; both faces now come out of libai_app.so, picked apart by features so `--no-default-features --features shell` keeps wgpu, parley and iris out of the Compose app's APK. docs/RUST.md's "One app crate" has the rest, including what each remaining feature is for. DECISIONS.md and SUBAGENTS.md move into docs/ with everything else. Verified: ./run-tests.sh and `cd iris && cargo test` green, clippy and fmt clean in all five workspaces, `cargo ndk -t x86_64` links libai_app.so, build-apk.sh produces an APK that installs and launches on this checkout's emulator (Gl ... virgl, as expected), and the phone-sized headless screenshot renders the transcript unchanged. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
7b54aaf3c4
commit
a9312e9431
113 files changed
+23221
-2992
No files matched your search
+51
-4
@@ -1,15 +1,16 @@
|
||||
use crate::{Mask, TextData, Textures, WeakWidget, WidgetId, Widgets, util::TrackedArena};
|
||||
use crate::{
|
||||
Mask, MoveOffset, TextData, Textures, WeakWidget, WidgetId, Widgets, util::TrackedArena,
|
||||
};
|
||||
|
||||
mod access;
|
||||
mod active;
|
||||
mod cache;
|
||||
mod painter;
|
||||
mod render_state;
|
||||
mod size;
|
||||
|
||||
pub use access::*;
|
||||
pub use active::*;
|
||||
pub use painter::Painter;
|
||||
pub use render_state::*;
|
||||
pub use size::*;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct UiData {
|
||||
@@ -17,6 +18,52 @@ pub struct UiData {
|
||||
pub textures: Textures,
|
||||
pub text: TextData,
|
||||
pub masks: TrackedArena<Mask, u32>,
|
||||
/// One entry per widget ever drawn, forming the parent-linked chain
|
||||
/// `resolve_move` walks in both shader stages. Allocated once on a
|
||||
/// widget's first draw and reused for every later redraw of the same
|
||||
/// id (never reallocated), so a retained descendant's `parent` index
|
||||
/// never goes stale -- see LAYOUT.md section 2.
|
||||
pub move_offsets: TrackedArena<MoveOffset, u32>,
|
||||
/// Every widget whose [`crate::Widget::tick`] should run before the
|
||||
/// next frame -- today, a `LazySpan` coasting through a fling. Added by
|
||||
/// [`Self::animate`] when the animation starts and removed by
|
||||
/// [`Self::tick_animations`] the frame its `tick` answers `false`, so
|
||||
/// a stopped animation costs nothing and a dropped widget cannot be
|
||||
/// ticked (`get_dyn_mut` answers `None` and it is dropped the same
|
||||
/// way).
|
||||
animating: Vec<WidgetId>,
|
||||
}
|
||||
|
||||
impl UiData {
|
||||
/// Ask for `id`'s [`crate::Widget::tick`] to run every frame until it
|
||||
/// says it is done. Idempotent -- registering an already-animating
|
||||
/// widget is the ordinary case (a second fling before the first
|
||||
/// settled) and must not tick it twice per frame.
|
||||
pub fn animate(&mut self, id: WidgetId) {
|
||||
if !self.animating.contains(&id) {
|
||||
self.animating.push(id);
|
||||
}
|
||||
}
|
||||
|
||||
/// Tick every registered widget to `now`, drop the ones that finished,
|
||||
/// and say whether any is still going -- which is a backend's cue to
|
||||
/// ask for another frame. Called once per frame *before* the draw, so
|
||||
/// what the frame draws is this instant's position rather than the
|
||||
/// previous one's.
|
||||
pub fn tick_animations(&mut self, now: std::time::Instant) -> bool {
|
||||
// Taken out and put back rather than iterated in place: `tick`
|
||||
// needs `&mut` on the widget arena this list lives beside, and a
|
||||
// widget is free to register another one while ticking.
|
||||
let mut registered = std::mem::take(&mut self.animating);
|
||||
registered.retain(|&id| match self.widgets.get_dyn_mut(id) {
|
||||
Some(widget) => widget.tick(now),
|
||||
None => false,
|
||||
});
|
||||
for id in registered {
|
||||
self.animate(id);
|
||||
}
|
||||
!self.animating.is_empty()
|
||||
}
|
||||
}
|
||||
|
||||
pub trait UiRsc {
|
||||
|
||||
Reference in new issue
Block a user