# Progress Reporting

`progress.h`/`progress.cpp` separate "does something have progress worth reporting" from "how is that progress actually displayed": `ProgressTracker` is a mixin for classes that make measurable forward progress (an analysis core, the multidimensional sweeper); `ProgressReporter` is an abstract base with one concrete subclass per output format - `AnalysisProgress` (`simulator/progressbar.h`) renders an actual terminal progress bar.

## `ProgressTracker`: reporting without knowing whether anyone's listening

A small mixin holding an optional `ProgressReporter*` (set via `install()`). `initProgress()`/`setProgress()` are no-ops whenever no reporter is installed, so the same analysis or sweep code runs identically whether or not progress output was actually requested - the tracked class never needs an `if (progressEnabled)` branch of its own.

## `ProgressReporter`: what to show and when

Tracks `extent_`/`pos_` (how far along, out of how much) plus an optional displayed `value_` (e.g. the current simulation time), decoupled from *how often* to actually redraw: `report()` only invokes the pure-virtual `reporter()` hook when `force` is set or enough wall-clock time (`dt`, measured via `Accounting::wclk()`) has passed since the last report. This rate-limiting is what keeps a tight simulation loop calling `setProgress()` on every internal step from flooding the terminal with redraws - the actual rendering cost is paid only a few times a second, independent of how often progress changes underneath it.

`setValueFormat()`/`setValueDecoration()` let a caller configure how the optional displayed value should be formatted (fixed/scientific/default, with a precision) and decorated (a prefix/postfix string, e.g. a unit) without the base class needing to know what the value represents - a concrete `reporter()` override reads these settings to render consistently.

## Why an abstract base

`AnalysisProgress` is the only concrete subclass in the tree. The tracked-progress bookkeeping (`extent_`/`pos_`/`value_`, the rate-limiting in `report()`) is shared and belongs in the base class; how progress is actually drawn - or whether it's drawn to a terminal at all - is what `reporter()` exists to make swappable per output format.

## Other operations

- **`disable()`/`enabled()`** - force a `ProgressReporter` off regardless of timing; e.g. `an.cpp` calls `disable()` when the simulator is running in debug mode, so debug output isn't interleaved with progress-bar redraws.
- **`begin()`/`end()`** - bracket a reporting session: `begin()` sets `tBegin`/`tLast` to the current wall-clock time (`Accounting::wclk()`), `end()` just updates `tLast` again, so a final `report(true)` right after `end()` is not throttled by `timeForReport()`.
- **`time()`** - wall-clock time elapsed between `begin()` and the last report (`tLast`), for a concrete `reporter()` to show an elapsed-time figure alongside the bar.
- **`position()`** - read accessor for `pos_`, the last position passed to `initProgress()`/`setProgress()`; a `reporter()` override such as `AnalysisProgress::reporter()` can also just read the protected `pos_`/`extent_` members directly, since it derives from `ProgressReporter`.
