docs: reorganize into en/ru and add English translation

This commit is contained in:
Glint Dev
2026-07-24 22:04:29 +03:00
parent 938f05f59d
commit 35f92435a3
20 changed files with 4651 additions and 0 deletions

View File

@@ -0,0 +1,92 @@
# Модуль реактивности: `src/interpreter/reactive.rs`
Система отслеживания зависимостей между переменными и элементами VDOM.
Позволяет пересчитывать только изменившиеся элементы (Phase 3).
---
## `ElementId(u32)`
Уникальный идентификатор элемента в VDOM-дереве. Раздаётся `ReactiveTracker::alloc_id()`
во время загрузки шаблона.
```rust
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct ElementId(pub u32);
```
**Используется как:**
- Ключ в `dirty_set: HashSet<ElementId>`
- Ключ в `dependencies: HashMap<ElementId, HashSet<String>>`
- Поле в `Element::element_id` (связь VDOM → tracker)
- Источник для `iced::widget::Id` (Phase 9.2: `format!("ti:{}", id.0)`)
- Источник для scrollable_id (`el.element_id.0 as u64`)
---
## `ReactiveTracker`
Граф зависимостей: переменная → список элементов, которые её используют.
```rust
pub struct ReactiveTracker {
subscribers: HashMap<String, HashSet<ElementId>>,
dependencies: HashMap<ElementId, HashSet<String>>,
dirty_set: HashSet<ElementId>,
next_id: u32,
}
```
**Поля:**
- `subscribers` — для каждой переменной: какие ElementId от неё зависят
- `dependencies` — для каждого элемента: от каких переменных он зависит (обратная связь)
- `dirty_set` — элементы, которые нужно пересчитать в следующем фрейме
- `next_id` — счётчик для `alloc_id()`
### Методы
| Метод | Описание |
|-------|----------|
| `new()` | Пустой tracker |
| `alloc_id() -> ElementId` | Выделить новый ID, увеличить счётчик |
| `add_dependency(element, var_name)` | Зарегистрировать зависимость |
| `scan_value(element, value)` | Сканировать строку на `$var` и добавить зависимости |
| `on_variable_changed(name)` | Пометить все зависимые элементы как dirty |
| `take_dirty_set() -> HashSet<ElementId>` | Забрать dirty_set и очистить |
| `is_dirty(id) -> bool` | Проверить, помечен ли элемент |
| `reset()` | Очистить все данные |
### scan_value()
Парсит строку в поиске `$var_name` паттернов:
```rust
"Hello $name, you are $age years old"
// → add_dependency(element, "name")
// → add_dependency(element, "age")
```
Используется во время загрузки шаблона для каждой properties строки,
содержащей `$`. В результате каждый элемент знает, от каких переменных зависит.
### Цикл обновления
```
Событие → update() → on_variable_changed("var")
→ dirty_set = {element_A, element_B, ...}
→ take_dirty_set() → evaluate_vdom_incr(roots, &dirty_set)
→ для элементов в dirty_set: пересчитать
→ для остальных: вернуть как есть
```
---
## Тесты
| Тест | Что проверяет |
|------|--------------|
| `test_basic_dependency_tracking` | Два элемента, две переменные, правильность dirty_set |
| `test_scan_value` | Парсинг `$var` из строки |
| `test_scan_no_vars` | Строка без `$` не создаёт зависимостей |
| `test_take_dirty_set` | `take_dirty_set()` очищает внутренний set |
| `test_reset` | `reset()` очищает всё |