tick method

bool tick(
  1. double dt,
  2. int target,
  3. double charactersPerSecond
)

Advances by dt seconds toward target characters at charactersPerSecond, adapting upward when behind.

Returns false once the reveal has caught up — the caller's cue to stop its ticker and stop rebuilding.

Implementation

bool tick(double dt, int target, double charactersPerSecond) {
  _clock += dt;

  _lastTarget = target;
  // The document can shrink under a live reveal — a construct completing
  // renders fewer characters than its literal text, or a rewrite shortens
  // the source. What was on screen has been seen: the head holds its
  // ground, and only the *vanished* range [target, head) is marked settled
  // — characters below the target still exist, are still mid-fade, and
  // keep fading. Vanished indices keep their own old stamps (nothing
  // restamps below the head), so if the text grows back over them they
  // read as finished rather than replaying, and the `floor - fadeWindow`
  // early-out in [progressFor] covers any slot a newer character
  // overwrites. A deliberate shrink goes through [reset] or [truncateTo]
  // instead.
  if (target < _revealed) {
    _settledBelow = math.max(_settledBelow, target);
  }

  var speed = charactersPerSecond;
  final backlog = target - _revealed;
  if (backlog > 0) {
    final window = _fastForwarding ? fastForwardSeconds : maxLagSeconds;
    speed = math.max(speed, backlog / window);
  }

  final before = _revealed.floor();
  _revealed = math.min(
    _revealed + speed * dt,
    math.max(target.toDouble(), _revealed),
  );
  final after = _revealed.floor();

  if (after > before) {
    final count = after - before;
    // Only the newest `fadeWindow` characters can still be mid-entrance;
    // stamping the ones behind them would be overwritten immediately. This
    // is what keeps a fast-forward of a long reply O(fadeWindow).
    final from = math.max(before, after - fadeWindow);
    for (var index = from; index < after; index++) {
      // Spread arrivals across the frame rather than stacking them on its
      // end, so a burst reveals as a ramp instead of a block.
      _stamps[index & _mask] =
          _clock - dt + dt * (index - before + 1) / count;
    }
  }

  if (_revealed >= target) {
    _fastForwarding = false;
    // The last character has appeared but may still be arriving.
    return tailStillFading;
  }
  return true;
}