State
Scheduling And Validation
Control notification timing, coalesce writes, and validate or reject source values.
- Scheduling
- Batching
- Validator
- TrySourceSet
Scheduling controls when notifications are delivered. Validation controls which values are accepted.
Scheduling
AzStateSchedule controls when subscribers are notified.
ImmediateNotify synchronously during
SourceSeton the main thread.NextUpdateCoalesce changes and notify during the next
Updatepump.EndOfFrameCoalesce changes and notify during the end-of-frame pump.
Immediate
public readonly AzState<int> Health =
new(100, schedule: AzStateSchedule.Immediate);Use for gameplay values that should notify right away.
NextUpdate
public readonly AzState<int> Score =
new(0, schedule: AzStateSchedule.NextUpdate);If you call SourceSet multiple times before the next update pump, subscribers receive one notification with the latest value.
Score.SourceSet(1);
Score.SourceSet(2);
Score.SourceSet(3);
// Subscribers are notified later with 3.Value updates when the state is applied, but scheduled subscribers are notified later.
EndOfFrame
public readonly AzState<Vector3> CameraTarget =
new(Vector3.zero, schedule: AzStateSchedule.EndOfFrame);Use for presentation or camera-related values that should react after normal update work.
Changing Schedule
Score.SetSchedule(AzStateSchedule.Immediate);Changing schedule flushes any pending notification immediately, then future writes use the new schedule.
Batching
AzStateBatch coalesces multiple state changes into one notification per modified state.
using (AzStateBatch.Begin())
{
Health.SourceSet(90);
Health.SourceSet(80);
Health.SourceSet(70);
}
// One Health notification with 70.Batching is useful when:
- loading save data
- applying multiple stat changes
- resetting a model
- updating several UI-bound values together
using (AzStateBatch.Begin())
{
Player.Health.SourceSet(save.Health);
Player.Score.SourceSet(save.Score);
Player.Position.SourceSet(save.Position);
Player.Status.SourceSet("Loaded");
}Batches can be nested. Notifications flush only when the outermost batch ends.
Always use the using pattern. If you call AzStateBatch.Begin() and do not dispose it, batched notifications remain stuck for that thread.
Validation
AzState<T> supports two validation hooks:
ValidatorTransforms the incoming value.
StrictValidatorAccepts or rejects the incoming value.
Validator
Use Validator to normalize values.
Health.Validator = value => Mathf.Clamp(value, 0, 100);
Health.SourceSet(150);
Debug.Log(Health.Value); // 100StrictValidator
Use StrictValidator to reject invalid values.
Health.StrictValidator = value =>
{
if (value < 0)
{
return AzStateValidationResult.Failure("Health cannot be negative.");
}
if (value > 100)
{
return AzStateValidationResult.Failure("Health cannot exceed 100.");
}
return AzStateValidationResult.Success();
};
bool changed = Health.SourceSet(-10);
Debug.Log(changed); // false
Debug.Log(Health.Value); // unchangedValidation order:
- Equality check determines whether the incoming value is changed, unless forced.
Validatortransforms the value.StrictValidatoraccepts or rejects the transformed value.- The state updates and notifies if accepted and changed.
By default, validation is skipped for unchanged values. Pass validateOnlyIfChanged: false to SourceSet if you need validation to run anyway.
Health.SourceSet(Health.Value, validateOnlyIfChanged: false);TrySourceSet
TrySourceSet gives you a validation result.
if (!Health.TrySourceSet(inputValue, out AzStateValidationResult result))
{
errorText.text = result.ErrorMessage;
}On the main thread, TrySourceSet returns exact strict-validation status.
Off-thread, it returns success when the request is accepted for later main-thread validation and application.
Use TrySourceSet for:
- forms
- sliders with error feedback
- user input
- transactions
- editor tooling
