ensureState<T> method

ValueNotifier<T> ensureState<T>(
  1. Element dependent,
  2. StateId id,
  3. StateMode mode,
  4. T create(),
  5. dynamic onDispose(
    1. T
    )?,
)

Ensures a state of type T is available, lazily creating it if necessary, and registers the dependent element.

Implementation

ValueNotifier<T> ensureState<T>(
  Element dependent,
  StateId id,
  StateMode mode,
  T Function() create,
  Function(T)? onDispose,
) {
  if (id.key == null) {
    final currentFrame = WidgetsBinding.instance.platformDispatcher.frameData.frameNumber;
    final counters = _elementKeyCounters.putIfAbsent(dependent, () => {});
    final counter = counters.putIfAbsent(T, () => _BuildCounter());

    if (counter.lastFrameNumber != currentFrame) {
      counter.count = 0;
      counter.lastFrameNumber = currentFrame;
    } else {
      counter.count += 1;
    }

    id = StateId(key: ValueKey(counter.count), type: T);
  }

  // Retrieve the existing state or lazily create a new one.
  final subscription = _subscriptions.putIfAbsent(id, () {
    final notifier = ValueNotifier(create());

    late final StateSubscription<T> sub;

    void listener() {
      for (final element in sub.watchers) {
        if (element.mounted) {
          element.markNeedsBuild();
        }
      }
    }

    notifier.addListener(listener);
    sub = StateSubscription(notifier: notifier, listener: listener, onDispose: onDispose);
    return sub;
  });

  // Register the dependency with Flutter's framework using the stateId as the aspect.
  dependent.dependOnInheritedWidgetOfExactType<StateScope>(aspect: id);

  // Track the element in either watchers or readers based on the requested [mode].
  if (mode == StateMode.watch) {
    subscription.watchers.add(dependent);
  } else {
    subscription.readers.add(dependent);
  }

  return subscription.notifier as ValueNotifier<T>;
}