Progress Scope
The receiver of an asyncWithProgress block: a CoroutineScope that can report progress and split the bar into slices.
Each ProgressScope owns a window, which is a part of the whole bar. The block's own scope owns the whole bar. A slice owns a part of its parent's window. A report of 0.5f in a slice fills half of that slice, not half of the bar.
The phase is the label of the current step. It is sticky: a report without a phase keeps the last phase.
You cannot implement this interface. Only asyncWithProgress creates it.
Threading
report is safe from any thread, for example from parallel workers.
Call slice and change the phase only from the block's own sequential code.
Watch out
Reports from parallel workers can arrive out of order, so the bar can move back a little. Count finished units in one shared counter and report it with
report(done, total). For a bar that never moves back, filter at the collector.After the operation completes, fails or is cancelled, reports do nothing.
Functions
Starts a coroutine like async, and also publishes its progress as a StateFlow.
Takes the next part of this window for one step and returns a scope for it.