# Обновление виджетов
Очень важно понимать, как работает билдер и параметры виджета:
```cpp
int val = 1234;

void build(gh::Builder& b) {
    b.Display(val).label("My disp");
}
```

Все параметры виджета, указанные в билдере таким образом (в данном случае это значение и название), передаются в приложение только **во время загрузки ПУ**, билдер вызывается и отправляет виджеты со значениями. Это происходит в следующих случаях:
- Открытие ПУ в приложении
- Обновление ПУ в приложении (кнопка обновить в правом углу)
- Обновление ПУ из программы через `hub.sendRefresh()` или `b.refresh()`

> Если значение переменной изменяется где-то в программе - эти изменения будут отправлены в приложение только при следующей загрузке ПУ.

В библиотеке предусмотрено изменение значения и параметров виджета в любой нужный момент, механизм называется обновление виджета.

## Имя виджета
Для отправки обновления виджету должно быть присвоено уникальное имя (функция с подчёркиванием):
```cpp
b.Display_("disp", val).label("My disp");
```

## Обновление значения
Если изменить нужно только значение, то можно воспользоваться функцией `sendUpdate()`
```cpp
hub.sendUpdate("disp", val);
```

Если в билдере в виджет передаётся переменная, которая всегда хранит актуальное значение (как в примере выше) - можно использовать функцию в таком виде:
```cpp
hub.sendUpdate("disp");
```
Библиотека вызовет билдер, прочитает значение и отправит его в приложение.

## Полное обновление
Для обновления других параметров виджета есть следующая конструкция:
```cpp
hub.update("имя").параметр(значение).параметр(значение)...
```
Можно обновить любой параметр, который соответствует этому виджету (см. таблицу). Для обновления значения используется параметр `value`:
```cpp
hub.update("disp").value(val).label("new label");
// или
hub.update("disp").value(random(1000));
```

## Пакетное обновление
Для одновременного обновления сразу нескольких виджетов можно использовать пакетные обновления:
```cpp
gh::Update upd(&hub);
upd.update("имя1").параметр(значение).параметр(значение)...
upd.update("имя2").параметр(значение).параметр(значение)...
upd.update("имя3").параметр(значение).параметр(значение)...
upd.send();
```

## Время и место обновления
Обновления можно отправлять не всегда и не везде, рассмотрим подробнее.

### Из билдера
- Отправлять обновление из билдера можно только в том случае, если билдер вызван для обработки действия. Простыми словами - отправить обновление можно только по событию `click()` или в обработчике `attach()`
- Отправлять обновление через `sendUpdate(имя)` внутри билдера нельзя

Отправим обновление со значением по нажатию на кнопку:
```cpp
void build(gh::Builder& b) {
    b.Display_("disp");
    if (b.Button().click()) hub.update("disp").value(random(1000));
}
```

### Из программы
Из остальных мест программы можно отправлять любые обновления, но не следует делать это слишком часто: можно перегрузить интерфейс связи. В библиотеке предусмотрен очень простой программный таймер, периодические обновления можно отправлять по нему:

```cpp
void build(gh::Builder& b) {
    b.Title_("tit").value("Title");
}

void loop() {
    hub.tick();

    // отправляем обновление каждую секунду
    static gh::Timer tmr(1000);
    if (tmr) hub.update("tit").value(millis());
}
```

## Отправка Action
Некоторые виджеты требуют отправки обновления `action` для совершения некоторых действий. Например всплывающие окна `Confirm` и `Prompt` требуют action для активации:

```cpp
if (b.Confirm_("cfm").text("confirm text").click()) {
    Serial.print("confirm: ");
    Serial.println(b.build.value);
}

String prom;
if (b.Prompt_("prom", &prom).text("prompt text").click()) {
    Serial.print("prompt: ");
    Serial.println(prom);
}

// так
if (b.Button().label("confirm").click()) hub.sendAction("cfm");

// или так
if (b.Button().label("prompt").click()) hub.update("prom").action();
```