# App and Perf modules ## `src/app.rs` — GlintApp Iced application entry point. Holds state and implements `update`/`view`. ### `GlintApp` ```rust pub struct GlintApp { pub doc: Document<'static>, pub vdom_roots: Vec>, pub rhei: RheiContext, } ``` - `doc` — original Document (styles, variables, tracker) - `vdom_roots` — result of the last evaluate_vdom (_incr) - `rhei` — Rhai engine with cached ASTs ### `update(&mut self, message: Message) -> iced::Task` Processing messages from Iced: | Message | Action | |---------|--------| | `WindowScrolled(y)` | Set `__scroll_y`, call `on_variable_changed` | | `ScrollableScrolled(id, y)` | Set `__scroll_{id}`, call `on_variable_changed` | | `EventTriggered(script)` | `execute_action()`, then diff variables to find changed ones | | `InputChanged(var, val)` | Set variable, call `on_variable_changed` | | `ToggleChanged(var, val)` | Set `Bool`, call `on_variable_changed` | | `SliderChanged(var, val)` | Set `Float`, call `on_variable_changed` | After processing the message: 1. `tracker.take_dirty_set()` — get dirty elements 2. `evaluate_vdom_incr()` — recalculate VDOM 3. Save to `self.vdom_roots` **Perf:** VDOM phase is measured with `PerfScope::new("vdom")`. ### `view(&self) -> iced::Element` Build Iced widgets from `self.vdom_roots`: 1. Collect scroll_positions from `__scroll_*` variables 2. For each root: `render_element()` → push into column 3. Overlay global fixed/absolute/sticky layers 4. Return `container(layout).into()` **Perf:** Render phase is measured with `PerfScope::new("render")`. At the end `perf::print_frame()` — output to stderr. --- ## `src/perf.rs` — Performance Monitoring Phase timing system (VDOM, Style, Render). Enabled with `--perf` flag. ### `PerfReport` ```rust pub struct PerfReport { pub vdom_eval: f64, // ms pub style: f64, // ms pub render: f64, // ms pub total: f64, // ms } ``` Stored in `thread_local!` `RefCell`. ### `PerfScope` Drop-guard: measures time from creation to destruction. ```rust pub struct PerfScope { name: &'static str, start: Instant, } ``` On `drop()`: adds elapsed ms to the corresponding `PerfReport` field. Names: `"vdom"`, `"style"`, `"render"`. ### Functions | Function | Description | |----------|-------------| | `set_enabled(bool)` | Enable/disable measurements | | `is_enabled() -> bool` | Check state | | `report_and_reset() -> Option` | Collect report, check >16ms threshold | | `reset()` | Reset PerfReport | | `print_frame()` | Call report_and_reset + reset, print to stderr | ### Example output ``` [perf] VDOM: 6.63ms | Style: 0.26ms | Render: 7.19ms | Total: 14.08ms [perf] VDOM: 13.26ms | Style: 0.52ms | Render: 7.18ms | Total: 20.95ms ⚠️ Frame budget exceeded! 20.95ms > 16ms ``` ### Instrumentation points | File | Phase | Location | |------|-------|----------| | `app.rs:update` | vdom | Around `evaluate_vdom_incr()` | | `app.rs:view` | render | Entire `view()` function | | `style.rs:compute_cached` | style | Inside `StyleSheet::compute_cached()` |