ensureState<T> method
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>;
}