У каждого уровня одна понятная задача.
То, что создаёт разработчик: неизменяемая конфигурация текста, layout, callback и детей.
Смонтированный экземпляр LumaFlow: хранит жизненный цикл, зависимости и выполняет reconciliation.
Нативный объект UI Toolkit: Unity рассчитывает его layout, обрабатывает ввод и рисует.
Приложение описывает Widget. LumaFlow управляет Element. Unity отображает VisualElement.
Изменение State не пересоздаёт весь экран.
Когда значение меняется, LumaFlow планирует перестроение только у прочитавшей его ветви. Build возвращает новое описание. Затем framework сравнивает его с уже смонтированным Element.
Существующий элемент обновляется
Element и VisualElement сохраняют идентичность; изменяются только свойства и дети.
Ветка заменяется
Старый Element освобождается, а для нового типа создаётся другой VisualElement.
Widget описывает текущее желаемое состояние. Долгоживущая идентичность принадлежит Element и VisualElement, а не объекту Widget.
Позиции достаточно, пока дети не меняются местами.
Обычные дети сопоставляются по позиции. Если элементы со своим состоянием вставляются, удаляются или сортируются, добавьте стабильный WidgetKey.
new Column(
projects.Select(project =>
new ProjectRow(project)
.WithKey(new WidgetKey(project.Id))));Это не глобальный идентификатор приложения. В одном наборе детей ключи должны быть уникальны и не должны зависеть от текущего индекса.
State принадлежит владельцу, а не одному вызову Build.
Данные приложения храните в явно принадлежащих кому-либо State<T>, контроллерах или domain services. Локальное состояние UI храните в State объекта StatefulWidget.
Создать State у владельца
Поле MonoBehaviour, долгоживущий controller или State, созданный StatefulWidget.
Создать State внутри Build
При следующем вызове Build появится новый экземпляр, а значение и подписки будут потеряны.
MountHandle.Rebuild() повторно вычисляет builder-границы, сохраняя совместимое состояние. Restart(newRoot) используют, когда корню намеренно требуется новое mount-local состояние.
Native — адаптер на границе интеграции.
Native встраивает отдельный UI Toolkit элемент, если нужного wrapper ещё нет в LumaFlow. Используйте factory, когда каждому mount нужен собственный экземпляр. Не перемещайте VisualElement в другой parent, пока он смонтирован.
new Native(() =>
new Label("Нативный UI Toolkit контент"));