State

Two-Way Binding

Bind two state values while keeping accepted value ownership and validation clear.

  • Model and UI
  • Reconciliation
  • Validation
  • Loop avoidance

Two-way binding is useful when UI and model can both propose changes, but one accepted value still needs to win.

Two-Way Binding

BindTwoWay keeps two states synchronized.

IAzPausableToken binding = ModelVolume.BindTwoWay(UiVolume, snapToThisOnBind: true);

If snapToThisOnBind is true, other is immediately set to this state's value.

var model = new AzState<float>(0.25f);
var ui = new AzState<float>(0.80f);

IAzPausableToken binding = model.BindTwoWay(ui, snapToThisOnBind: true);

Debug.Log(ui.Value); // 0.25

Changes flow both ways:

model.SourceSet(0.50f);
Debug.Log(ui.Value); // 0.50

ui.SourceSet(0.75f);
Debug.Log(model.Value); // 0.75

The returned token controls both internal subscriptions.

binding.Pause();
binding.Resume();
binding.Dispose();

When paused, the two states can diverge.

binding.Pause();

model.SourceSet(0.10f);
ui.SourceSet(0.90f);

Debug.Log(model.Value); // 0.10
Debug.Log(ui.Value);    // 0.90

When resumed, future changes synchronize again. Resume does not automatically snap the values; set one side explicitly if you want a reconciliation point.

binding.Resume();
ui.SourceSet(model.Value, force: true);

Validation and Two-Way Binding

If one side transforms or rejects values, the binding converges to the accepted value.

var clamped = new AzState<int>(50)
{
    Validator = value => Mathf.Clamp(value, 0, 100)
};

var raw = new AzState<int>(50);
IAzPausableToken binding = clamped.BindTwoWay(raw);

raw.SourceSet(200);

Debug.Log(clamped.Value); // 100
Debug.Log(raw.Value);     // 100

For predictable initialization, use compatible validators or snapToThisOnBind: true.