110 lines
3.9 KiB
Markdown
110 lines
3.9 KiB
Markdown
# App и Perf модули
|
||
|
||
## `src/app.rs` — GlintApp
|
||
|
||
Точка входа Iced-приложения. Держит состояние и реализует `update`/`view`.
|
||
|
||
### `GlintApp`
|
||
|
||
```rust
|
||
pub struct GlintApp {
|
||
pub doc: Document<'static>,
|
||
pub vdom_roots: Vec<Element<'static>>,
|
||
pub rhei: RheiContext,
|
||
}
|
||
```
|
||
|
||
- `doc` — оригинальный Document (стили, переменные, tracker)
|
||
- `vdom_roots` — результат последнего evaluate_vdom (_incr)
|
||
- `rhei` — Rhai-движок с кэшированными AST
|
||
|
||
### `update(&mut self, message: Message) -> iced::Task<Message>`
|
||
|
||
Обработка сообщений от Iced:
|
||
|
||
| Message | Действие |
|
||
|---------|----------|
|
||
| `WindowScrolled(y)` | Установить `__scroll_y`, вызвать `on_variable_changed` |
|
||
| `ScrollableScrolled(id, y)` | Установить `__scroll_{id}`, вызвать `on_variable_changed` |
|
||
| `EventTriggered(script)` | `execute_action()`, затем diff переменных для поиска изменившихся |
|
||
| `InputChanged(var, val)` | Установить переменную, вызвать `on_variable_changed` |
|
||
| `ToggleChanged(var, val)` | Установить `Bool`, вызвать `on_variable_changed` |
|
||
| `SliderChanged(var, val)` | Установить `Float`, вызвать `on_variable_changed` |
|
||
|
||
После обработки сообщения:
|
||
1. `tracker.take_dirty_set()` — получить dirty элементы
|
||
2. `evaluate_vdom_incr()` — пересчитать VDOM
|
||
3. Сохранить в `self.vdom_roots`
|
||
|
||
**Perf:** VDOM фаза замеряется `PerfScope::new("vdom")`.
|
||
|
||
### `view(&self) -> iced::Element`
|
||
|
||
Построить Iced-виджеты из `self.vdom_roots`:
|
||
|
||
1. Собрать scroll_positions из `__scroll_*` переменных
|
||
2. Для каждого root: `render_element()` → push в column
|
||
3. Наложить global fixed/absolute/sticky слои
|
||
4. Вернуть `container(layout).into()`
|
||
|
||
**Perf:** Render фаза замеряется `PerfScope::new("render")`.
|
||
В конце `perf::print_frame()` — вывод в stderr.
|
||
|
||
---
|
||
|
||
## `src/perf.rs` — Performance Monitoring
|
||
|
||
Система замера времени по фазам (VDOM, Style, Render). Включение: флаг `--perf`.
|
||
|
||
### `PerfReport`
|
||
|
||
```rust
|
||
pub struct PerfReport {
|
||
pub vdom_eval: f64, // ms
|
||
pub style: f64, // ms
|
||
pub render: f64, // ms
|
||
pub total: f64, // ms
|
||
}
|
||
```
|
||
|
||
Хранится в `thread_local!` `RefCell<PerfReport>`.
|
||
|
||
### `PerfScope`
|
||
|
||
Drop-guard: замеряет время от создания до разрушения.
|
||
|
||
```rust
|
||
pub struct PerfScope {
|
||
name: &'static str,
|
||
start: Instant,
|
||
}
|
||
```
|
||
|
||
При `drop()`: добавляет elapsed ms к соответствующему полю `PerfReport`.
|
||
Имена: `"vdom"`, `"style"`, `"render"`.
|
||
|
||
### Функции
|
||
|
||
| Функция | Описание |
|
||
|---------|----------|
|
||
| `set_enabled(bool)` | Включить/выключить замеры |
|
||
| `is_enabled() -> bool` | Проверить состояние |
|
||
| `report_and_reset() -> Option<String>` | Собрать отчёт, проверить >16ms threshold |
|
||
| `reset()` | Обнулить PerfReport |
|
||
| `print_frame()` | Вызвать report_and_reset + сброс, напечатать в stderr |
|
||
|
||
### Пример вывода
|
||
|
||
```
|
||
[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
|
||
```
|
||
|
||
### Точки инструментирования
|
||
|
||
| Файл | Фаза | Место |
|
||
|------|------|-------|
|
||
| `app.rs:update` | vdom | Вокруг `evaluate_vdom_incr()` |
|
||
| `app.rs:view` | render | Вся функция `view()` |
|
||
| `style.rs:compute_cached` | style | Внутри `StyleSheet::compute_cached()` |
|