BloomTickerProviderDriveExtension extension

Extension providing reactive frame-tick driver capabilities directly on Flutter TickerProvider instances.

Bridges Flutter's continuous display VSYNC engine into Bloom's 2-Phase LPDAG reactive graph, converting raw frame ticks into lifecycle-managed, self-disposing Bloom streams.

System Architectural Flow

[ TickerProvider (State / Element) ]
                │
                │ .drive(onTick)
                ▼
[ managed<_TickerDriver<T>> ] ──► Lazy Allocation on Downstream Subscription
                │
                ▼
[ Hardware VSYNC Tick ] ──► onTick(elapsed) ──► BloomController<T>.set()
                │
                ▼
[ Distinct Filter ] ──► Suppresses Invalidation if Unchanged
                │
                ▼
[ Downstream Teardown ] ──► managed triggers tryDispose on Deactivation

Key Invariants & Architectural Benefits

  1. Lazy Allocation & Zero Leaks: Tickers are instantiated only when downstream subscribers actively observe the node, and are automatically halted and disposed when unobserved.
  2. Hardware VSYNC Alignment: Computations are synchronized directly with the hardware display refresh cadence (60Hz / 120Hz), eliminating asynchronous timer drift and frame jitter.
  3. Tick Dropping via distinct: Gating identical consecutive results prevents unnecessary re-evaluations and widget rebuilds, conserving CPU and battery life.
  4. Resilient Remount Deferral: Integrates with Graceful policies (e.g. Graceful.microtask()) to preserve ticker continuity across quick widget reparenting or route transitions.

Invocation Pathways

TickerProvider.drive<T>(onTick, ...) ──► Bloom<T>

For inline UI widget composition that does not require an explicit TickerProvider, use composed.drive(...) instead.

Examples

class RotationIndicatorState extends State<RotationIndicator>
    with SingleTickerProviderStateMixin {
  late final angleBloom = drive(
    (elapsed) => (elapsed.inMicroseconds % 1000000) / 1000000.0 * 2 * math.pi,
  );

  @override
  Widget build(BuildContext context) {
    return composed((context, via) => Transform.rotate(
      angle: via(angleBloom),
      child: const Icon(Icons.refresh),
    ));
  }
}
on

Methods

drive<T>(T onTick(Duration elapsed), {bool distinct = false, bool equals(T previous, T next)?, Graceful? graceful}) → Bloom<T>

Available on TickerProvider, provided by the BloomTickerProviderDriveExtension extension

Drives a reactive Bloom<T> from this TickerProvider by evaluating onTick on every animation frame tick.