observe method

Bloom<double> observe({
  1. bool distinct = true,
  2. bool equals(
    1. double previous,
    2. double next
    )?,
  3. Graceful? graceful,
})

Observes this controller's animated value as a reactive Bloom<double>.

Caution: VSYNC Coupling (Passive Observer)

observe is a passive observer of this controller's timeline and does NOT generate physical VSYNC ticks on its own.

For this Bloom node to emit updates, the controller must have an active VSYNC host actively animating it in the widget tree (e.g., via composed.animate(...)).

System Architectural Flow

[composed.animate (Active VSYNC Socket)] ──> [DurableAnimationController (Timeline)]
                                                             │
                                                             ▼
[controller.observe() (Passive Bloom<double>)] <──────────────┘
  • distinct: When true (default), suppresses pulses if animated value does not change.
  • equals: Custom equality function.
  • graceful: Optional teardown deferral policy.

Requires:

  • If equals is provided, distinct must be true.

Ensures:

  • Emits updated double values whenever the controller's animation updates.

Warning (Anti-Pattern Prevention):

  • Calling controller.observe() without mounting the controller in an active VSYNC socket (such as composed.animate) will produce a dormant Bloom that never ticks.

BAD:

// [Anti-Pattern] Expecting observe() to tick without a mounted VSYNC host
final ctrl = DurableAnimationController(duration: const Duration(seconds: 1))..forward();
final animatedBloom = ctrl.observe(); // Never receives ticks because no vsync is mounted!

GOOD:

// [Recommended] Mount controller via composed.animate, observe timeline reactively elsewhere
final ctrl = DurableAnimationController(duration: const Duration(seconds: 1));
final animatedBloom = ctrl.observe();

Widget build(BuildContext context) {
  return Column(
    children: [
      composed.animate(ctrl, (context, via, c) => FadeTransition(opacity: c.view, child: const Text('Host'))),
      composed((context, via) => Text('Progress: ${via(animatedBloom).toStringAsFixed(2)}')),
    ],
  );
}

Implementation

Bloom<double> observe({
  bool distinct = true,
  bool Function(double previous, double next)? equals,
  Graceful? graceful,
}) =>
    _view.toBloom(
      distinct: distinct,
      equals: equals,
      graceful: graceful,
    );