Основы / Архитектура

Декларативное описание поверх retained-дерева Unity.

LumaFlow не создаёт второй рендерер и не заменяет layout engine. Он превращает неизменяемые Widget в обычные UI Toolkit элементы и обновляет совместимые экземпляры на месте.

У каждого уровня одна понятная задача.

Widget

То, что создаёт разработчик: неизменяемая конфигурация текста, layout, callback и детей.

Element

Смонтированный экземпляр LumaFlow: хранит жизненный цикл, зависимости и выполняет reconciliation.

VisualElement

Нативный объект UI Toolkit: Unity рассчитывает его layout, обрабатывает ввод и рисует.

Приложение описывает Widget. LumaFlow управляет Element. Unity отображает VisualElement.

Изменение State не пересоздаёт весь экран.

Когда значение меняется, LumaFlow планирует перестроение только у прочитавшей его ветви. Build возвращает новое описание. Затем framework сравнивает его с уже смонтированным Element.

Совместимы

Существующий элемент обновляется

Element и VisualElement сохраняют идентичность; изменяются только свойства и дети.

Несовместимы

Ветка заменяется

Старый Element освобождается, а для нового типа создаётся другой VisualElement.

Именно поэтому Widget неизменяем.

Widget описывает текущее желаемое состояние. Долгоживущая идентичность принадлежит Element и VisualElement, а не объекту Widget.

Позиции достаточно, пока дети не меняются местами.

Обычные дети сопоставляются по позиции. Если элементы со своим состоянием вставляются, удаляются или сортируются, добавьте стабильный WidgetKey.

ProjectRows.cs
new Column(
  projects.Select(project =>
    new ProjectRow(project)
      .WithKey(new WidgetKey(project.Id))));
Key локален для списка соседей.

Это не глобальный идентификатор приложения. В одном наборе детей ключи должны быть уникальны и не должны зависеть от текущего индекса.

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, пока он смонтирован.

Interop.cs
new Native(() =>
  new Label("Нативный UI Toolkit контент"));
Дальше: списки и Key →