docs: reorganize into en/ru and add English translation
This commit is contained in:
92
docs/ru/modules/03-reactive.md
Normal file
92
docs/ru/modules/03-reactive.md
Normal 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()` очищает всё |
|
||||
Reference in New Issue
Block a user