You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hybrid data-binding convention — Unity 6 runtime data binding
(DataBinding/INotifyBindablePropertyChanged/[CreateProperty]) is now allowed, as a View-internal implementation detail behind the existing IView interfaces, for
data-heavy screens. The MVP core is untouched; commands, clicks and navigation stay on ScreenSubscriptions; every binding is BindingMode.ToTarget with a nameof path
(stringly UXML <Bindings> discouraged). Convention, walkthrough, testing story and a
per-screen decision table: Documentation~/HYBRID-DATA-BINDING.md.
BindableViewModel (Runtime/ViewModel/, namespace Cuvara.UIToolkit.ViewModel).
The notifying base a binding source must derive from: Set<T>(ref field, value) guards
with EqualityComparer<T>.Default, raises propertyChanged with the [CallerMemberName] property name only on real change, and returns whether anything
changed. Notifying is mandatory because a non-notifying DataBinding source is
version-polled by the binding system on every UI update — per-frame work the package's
"update on data change, not per frame" contract forbids. Stays plain C#: testable with
NUnit alone, no panel.
EcsHud sample retrofitted as the reference hybrid screen. The imperative Render(caption, fraction) path is gone: the sink writes properties on a [CreateProperty]-annotated VitalsHudViewModel, and VitalsView.Bind assigns Root.dataSource and wires the label and bar once via SetBinding (the
fraction→StyleLength conversion is a converter on the binding, so UI Toolkit types
never leak above the View). The adapter → ViewModel → View layering and the ECS rule
are unchanged — nothing in Runtime/Ecs/ moved. The sample's UXML (renamed VitalsView.uxml so the generated class matches the view) is now enrolled in the
UXML codegen: Generated/VitalsView.uxml.g.cs is the other half of the partial View
and is drift-checked by CI alongside the test fixture.
Tests: Tests/Runtime/ViewModel/BindableViewModelTests.cs (plain C# — raise with
correct name via [CallerMemberName], silence on equal values including null→null,
same-reference and equal-but-distinct strings, return-value semantics, value and
reference types; verified under plain dotnet as well) and BindableViewModelBindingTests.cs ([UnityTest] on a live UIDocument — a Set()
reaches a bound Label and a converter-driven style.width through the real binding
system, with no Render call).
Changed
UXML-CODEGEN.md documents a batchmode limitation found while verifying 0.3.0 on
a real Editor (6000.3.9f1): a -batchmode -quit session that starts with compile
errors exits before the asset import step (exit code still 0), so the auto-regen
postprocessor never runs in it — after an element rename breaks consuming code,
batchmode cannot regenerate its way out. The doc lists the recovery paths (git
checkout of the .g.cs, the menu item in an interactive Editor, or Tools~/UxmlCodegenCli). Docs only; no code change.