Unverified Commit 9e658bc3 authored by Alexandre Ardhuin's avatar Alexandre Ardhuin Committed by GitHub

migrate scheduler to nullsafety (#61570)

parent fdf87edd
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
/// The Flutter Scheduler library. /// The Flutter Scheduler library.
/// ///
/// To use, import `package:flutter/scheduler.dart`. /// To use, import `package:flutter/scheduler.dart`.
......
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'dart:async'; import 'dart:async';
import 'dart:collection'; import 'dart:collection';
import 'dart:developer' show Flow, Timeline; import 'dart:developer' show Flow, Timeline;
...@@ -57,7 +55,7 @@ typedef TaskCallback<T> = T Function(); ...@@ -57,7 +55,7 @@ typedef TaskCallback<T> = T Function();
/// See also: /// See also:
/// ///
/// * [defaultSchedulingStrategy], the default [SchedulingStrategy] for [SchedulerBinding.schedulingStrategy]. /// * [defaultSchedulingStrategy], the default [SchedulingStrategy] for [SchedulerBinding.schedulingStrategy].
typedef SchedulingStrategy = bool Function({ int priority, SchedulerBinding scheduler }); typedef SchedulingStrategy = bool Function({ required int priority, required SchedulerBinding scheduler });
class _TaskEntry<T> { class _TaskEntry<T> {
_TaskEntry(this.task, this.priority, this.debugLabel, this.flow) { _TaskEntry(this.task, this.priority, this.debugLabel, this.flow) {
...@@ -65,15 +63,14 @@ class _TaskEntry<T> { ...@@ -65,15 +63,14 @@ class _TaskEntry<T> {
debugStack = StackTrace.current; debugStack = StackTrace.current;
return true; return true;
}()); }());
completer = Completer<T>();
} }
final TaskCallback<T> task; final TaskCallback<T> task;
final int priority; final int priority;
final String debugLabel; final String? debugLabel;
final Flow flow; final Flow? flow;
StackTrace debugStack; late StackTrace debugStack;
Completer<T> completer; final Completer<T> completer = Completer<T>();
void run() { void run() {
if (!kReleaseMode) { if (!kReleaseMode) {
...@@ -82,7 +79,7 @@ class _TaskEntry<T> { ...@@ -82,7 +79,7 @@ class _TaskEntry<T> {
() { () {
completer.complete(task()); completer.complete(task());
}, },
flow: flow != null ? Flow.step(flow.id) : null, flow: flow != null ? Flow.step(flow!.id) : null,
); );
} else { } else {
completer.complete(task()); completer.complete(task());
...@@ -123,8 +120,8 @@ class _FrameCallbackEntry { ...@@ -123,8 +120,8 @@ class _FrameCallbackEntry {
final FrameCallback callback; final FrameCallback callback;
static StackTrace debugCurrentCallbackStack; static StackTrace? debugCurrentCallbackStack;
StackTrace debugStack; StackTrace? debugStack;
} }
/// The various phases that a [SchedulerBinding] goes through during /// The various phases that a [SchedulerBinding] goes through during
...@@ -292,7 +289,7 @@ mixin SchedulerBinding on BindingBase { ...@@ -292,7 +289,7 @@ mixin SchedulerBinding on BindingBase {
callback(timings); callback(timings);
} }
} catch (exception, stack) { } catch (exception, stack) {
InformationCollector collector; InformationCollector? collector;
assert(() { assert(() {
collector = () sync* { collector = () sync* {
yield DiagnosticsProperty<TimingsCallback>( yield DiagnosticsProperty<TimingsCallback>(
...@@ -314,8 +311,8 @@ mixin SchedulerBinding on BindingBase { ...@@ -314,8 +311,8 @@ mixin SchedulerBinding on BindingBase {
} }
/// The current [SchedulerBinding], if one has been created. /// The current [SchedulerBinding], if one has been created.
static SchedulerBinding get instance => _instance; static SchedulerBinding? get instance => _instance;
static SchedulerBinding _instance; static SchedulerBinding? _instance;
@override @override
void initServiceExtensions() { void initServiceExtensions() {
...@@ -340,8 +337,8 @@ mixin SchedulerBinding on BindingBase { ...@@ -340,8 +337,8 @@ mixin SchedulerBinding on BindingBase {
/// ///
/// The preferred way to watch for changes to this value is using /// The preferred way to watch for changes to this value is using
/// [WidgetsBindingObserver.didChangeAppLifecycleState]. /// [WidgetsBindingObserver.didChangeAppLifecycleState].
AppLifecycleState get lifecycleState => _lifecycleState; AppLifecycleState? get lifecycleState => _lifecycleState;
AppLifecycleState _lifecycleState; AppLifecycleState? _lifecycleState;
/// Called when the application lifecycle state changes. /// Called when the application lifecycle state changes.
/// ///
...@@ -398,8 +395,8 @@ mixin SchedulerBinding on BindingBase { ...@@ -398,8 +395,8 @@ mixin SchedulerBinding on BindingBase {
Future<T> scheduleTask<T>( Future<T> scheduleTask<T>(
TaskCallback<T> task, TaskCallback<T> task,
Priority priority, { Priority priority, {
String debugLabel, String? debugLabel,
Flow flow, Flow? flow,
}) { }) {
final bool isFirstTask = _taskQueue.isEmpty; final bool isFirstTask = _taskQueue.isEmpty;
final _TaskEntry<T> entry = _TaskEntry<T>( final _TaskEntry<T> entry = _TaskEntry<T>(
...@@ -462,7 +459,7 @@ mixin SchedulerBinding on BindingBase { ...@@ -462,7 +459,7 @@ mixin SchedulerBinding on BindingBase {
_taskQueue.removeFirst(); _taskQueue.removeFirst();
entry.run(); entry.run();
} catch (exception, exceptionStack) { } catch (exception, exceptionStack) {
StackTrace callbackStack; StackTrace? callbackStack;
assert(() { assert(() {
callbackStack = entry.debugStack; callbackStack = entry.debugStack;
return true; return true;
...@@ -585,7 +582,7 @@ mixin SchedulerBinding on BindingBase { ...@@ -585,7 +582,7 @@ mixin SchedulerBinding on BindingBase {
); );
} }
for (final int id in callbacks.keys) { for (final int id in callbacks.keys) {
final _FrameCallbackEntry entry = callbacks[id]; final _FrameCallbackEntry entry = callbacks[id]!;
yield DiagnosticsStackTrace('── callback $id ──', entry.debugStack, showSeparator: false); yield DiagnosticsStackTrace('── callback $id ──', entry.debugStack, showSeparator: false);
} }
}, },
...@@ -622,7 +619,7 @@ mixin SchedulerBinding on BindingBase { ...@@ -622,7 +619,7 @@ mixin SchedulerBinding on BindingBase {
debugPrint( debugPrint(
FlutterError.defaultStackFilter( FlutterError.defaultStackFilter(
FlutterError.demangleStackTrace( FlutterError.demangleStackTrace(
_FrameCallbackEntry.debugCurrentCallbackStack, _FrameCallbackEntry.debugCurrentCallbackStack!,
).toString().trimRight().split('\n') ).toString().trimRight().split('\n')
).join('\n') ).join('\n')
); );
...@@ -677,7 +674,7 @@ mixin SchedulerBinding on BindingBase { ...@@ -677,7 +674,7 @@ mixin SchedulerBinding on BindingBase {
_postFrameCallbacks.add(callback); _postFrameCallbacks.add(callback);
} }
Completer<void> _nextFrameCompleter; Completer<void>? _nextFrameCompleter;
/// Returns a Future that completes after the frame completes. /// Returns a Future that completes after the frame completes.
/// ///
...@@ -694,11 +691,11 @@ mixin SchedulerBinding on BindingBase { ...@@ -694,11 +691,11 @@ mixin SchedulerBinding on BindingBase {
scheduleFrame(); scheduleFrame();
_nextFrameCompleter = Completer<void>(); _nextFrameCompleter = Completer<void>();
addPostFrameCallback((Duration timeStamp) { addPostFrameCallback((Duration timeStamp) {
_nextFrameCompleter.complete(); _nextFrameCompleter!.complete();
_nextFrameCompleter = null; _nextFrameCompleter = null;
}); });
} }
return _nextFrameCompleter.future; return _nextFrameCompleter!.future;
} }
/// Whether this scheduler has requested that [handleBeginFrame] be called soon. /// Whether this scheduler has requested that [handleBeginFrame] be called soon.
...@@ -885,7 +882,7 @@ mixin SchedulerBinding on BindingBase { ...@@ -885,7 +882,7 @@ mixin SchedulerBinding on BindingBase {
}); });
} }
Duration _firstRawTimeStampInEpoch; Duration? _firstRawTimeStampInEpoch;
Duration _epochStart = Duration.zero; Duration _epochStart = Duration.zero;
Duration _lastRawTimeStamp = Duration.zero; Duration _lastRawTimeStamp = Duration.zero;
...@@ -920,7 +917,7 @@ mixin SchedulerBinding on BindingBase { ...@@ -920,7 +917,7 @@ mixin SchedulerBinding on BindingBase {
/// These mechanisms together combine to ensure that the durations we give /// These mechanisms together combine to ensure that the durations we give
/// during frame callbacks are monotonically increasing. /// during frame callbacks are monotonically increasing.
Duration _adjustForEpoch(Duration rawTimeStamp) { Duration _adjustForEpoch(Duration rawTimeStamp) {
final Duration rawDurationSinceEpoch = _firstRawTimeStampInEpoch == null ? Duration.zero : rawTimeStamp - _firstRawTimeStampInEpoch; final Duration rawDurationSinceEpoch = _firstRawTimeStampInEpoch == null ? Duration.zero : rawTimeStamp - _firstRawTimeStampInEpoch!;
return Duration(microseconds: (rawDurationSinceEpoch.inMicroseconds / timeDilation).round() + _epochStart.inMicroseconds); return Duration(microseconds: (rawDurationSinceEpoch.inMicroseconds / timeDilation).round() + _epochStart.inMicroseconds);
} }
...@@ -931,9 +928,9 @@ mixin SchedulerBinding on BindingBase { ...@@ -931,9 +928,9 @@ mixin SchedulerBinding on BindingBase {
/// produced. /// produced.
Duration get currentFrameTimeStamp { Duration get currentFrameTimeStamp {
assert(_currentFrameTimeStamp != null); assert(_currentFrameTimeStamp != null);
return _currentFrameTimeStamp; return _currentFrameTimeStamp!;
} }
Duration _currentFrameTimeStamp; Duration? _currentFrameTimeStamp;
/// The raw time stamp as provided by the engine to [Window.onBeginFrame] /// The raw time stamp as provided by the engine to [Window.onBeginFrame]
/// for the frame currently being processed. /// for the frame currently being processed.
...@@ -952,7 +949,7 @@ mixin SchedulerBinding on BindingBase { ...@@ -952,7 +949,7 @@ mixin SchedulerBinding on BindingBase {
} }
int _debugFrameNumber = 0; int _debugFrameNumber = 0;
String _debugBanner; String? _debugBanner;
bool _ignoreNextEngineDrawFrame = false; bool _ignoreNextEngineDrawFrame = false;
void _handleBeginFrame(Duration rawTimeStamp) { void _handleBeginFrame(Duration rawTimeStamp) {
...@@ -995,7 +992,7 @@ mixin SchedulerBinding on BindingBase { ...@@ -995,7 +992,7 @@ mixin SchedulerBinding on BindingBase {
/// [debugPrintEndFrameBanner] to true. This allows you to distinguish log /// [debugPrintEndFrameBanner] to true. This allows you to distinguish log
/// statements printed during a frame from those printed between frames (e.g. /// statements printed during a frame from those printed between frames (e.g.
/// in response to events or timers). /// in response to events or timers).
void handleBeginFrame(Duration rawTimeStamp) { void handleBeginFrame(Duration? rawTimeStamp) {
Timeline.startSync('Frame', arguments: timelineArgumentsIndicatingLandmarkEvent); Timeline.startSync('Frame', arguments: timelineArgumentsIndicatingLandmarkEvent);
_firstRawTimeStampInEpoch ??= rawTimeStamp; _firstRawTimeStampInEpoch ??= rawTimeStamp;
_currentFrameTimeStamp = _adjustForEpoch(rawTimeStamp ?? _lastRawTimeStamp); _currentFrameTimeStamp = _adjustForEpoch(rawTimeStamp ?? _lastRawTimeStamp);
...@@ -1008,7 +1005,7 @@ mixin SchedulerBinding on BindingBase { ...@@ -1008,7 +1005,7 @@ mixin SchedulerBinding on BindingBase {
if (debugPrintBeginFrameBanner || debugPrintEndFrameBanner) { if (debugPrintBeginFrameBanner || debugPrintEndFrameBanner) {
final StringBuffer frameTimeStampDescription = StringBuffer(); final StringBuffer frameTimeStampDescription = StringBuffer();
if (rawTimeStamp != null) { if (rawTimeStamp != null) {
_debugDescribeTimeStamp(_currentFrameTimeStamp, frameTimeStampDescription); _debugDescribeTimeStamp(_currentFrameTimeStamp!, frameTimeStampDescription);
} else { } else {
frameTimeStampDescription.write('(warm-up frame)'); frameTimeStampDescription.write('(warm-up frame)');
} }
...@@ -1029,7 +1026,7 @@ mixin SchedulerBinding on BindingBase { ...@@ -1029,7 +1026,7 @@ mixin SchedulerBinding on BindingBase {
_transientCallbacks = <int, _FrameCallbackEntry>{}; _transientCallbacks = <int, _FrameCallbackEntry>{};
callbacks.forEach((int id, _FrameCallbackEntry callbackEntry) { callbacks.forEach((int id, _FrameCallbackEntry callbackEntry) {
if (!_removedIds.contains(id)) if (!_removedIds.contains(id))
_invokeFrameCallback(callbackEntry.callback, _currentFrameTimeStamp, callbackEntry.debugStack); _invokeFrameCallback(callbackEntry.callback, _currentFrameTimeStamp!, callbackEntry.debugStack);
}); });
_removedIds.clear(); _removedIds.clear();
} finally { } finally {
...@@ -1053,7 +1050,7 @@ mixin SchedulerBinding on BindingBase { ...@@ -1053,7 +1050,7 @@ mixin SchedulerBinding on BindingBase {
// PERSISTENT FRAME CALLBACKS // PERSISTENT FRAME CALLBACKS
_schedulerPhase = SchedulerPhase.persistentCallbacks; _schedulerPhase = SchedulerPhase.persistentCallbacks;
for (final FrameCallback callback in _persistentCallbacks) for (final FrameCallback callback in _persistentCallbacks)
_invokeFrameCallback(callback, _currentFrameTimeStamp); _invokeFrameCallback(callback, _currentFrameTimeStamp!);
// POST-FRAME CALLBACKS // POST-FRAME CALLBACKS
_schedulerPhase = SchedulerPhase.postFrameCallbacks; _schedulerPhase = SchedulerPhase.postFrameCallbacks;
...@@ -1061,13 +1058,13 @@ mixin SchedulerBinding on BindingBase { ...@@ -1061,13 +1058,13 @@ mixin SchedulerBinding on BindingBase {
List<FrameCallback>.from(_postFrameCallbacks); List<FrameCallback>.from(_postFrameCallbacks);
_postFrameCallbacks.clear(); _postFrameCallbacks.clear();
for (final FrameCallback callback in localPostFrameCallbacks) for (final FrameCallback callback in localPostFrameCallbacks)
_invokeFrameCallback(callback, _currentFrameTimeStamp); _invokeFrameCallback(callback, _currentFrameTimeStamp!);
} finally { } finally {
_schedulerPhase = SchedulerPhase.idle; _schedulerPhase = SchedulerPhase.idle;
Timeline.finishSync(); // end the Frame Timeline.finishSync(); // end the Frame
assert(() { assert(() {
if (debugPrintEndFrameBanner) if (debugPrintEndFrameBanner)
debugPrint('▀' * _debugBanner.length); debugPrint('▀' * _debugBanner!.length);
_debugBanner = null; _debugBanner = null;
return true; return true;
}()); }());
...@@ -1106,7 +1103,7 @@ mixin SchedulerBinding on BindingBase { ...@@ -1106,7 +1103,7 @@ mixin SchedulerBinding on BindingBase {
// Wraps the callback in a try/catch and forwards any error to // Wraps the callback in a try/catch and forwards any error to
// [debugSchedulerExceptionHandler], if set. If not set, then simply prints // [debugSchedulerExceptionHandler], if set. If not set, then simply prints
// the error. // the error.
void _invokeFrameCallback(FrameCallback callback, Duration timeStamp, [ StackTrace callbackStack ]) { void _invokeFrameCallback(FrameCallback callback, Duration timeStamp, [ StackTrace? callbackStack ]) {
assert(callback != null); assert(callback != null);
assert(_FrameCallbackEntry.debugCurrentCallbackStack == null); assert(_FrameCallbackEntry.debugCurrentCallbackStack == null);
assert(() { assert(() {
...@@ -1143,7 +1140,7 @@ mixin SchedulerBinding on BindingBase { ...@@ -1143,7 +1140,7 @@ mixin SchedulerBinding on BindingBase {
/// If there are any frame callbacks registered, only runs tasks with /// If there are any frame callbacks registered, only runs tasks with
/// a [Priority] of [Priority.animation] or higher. Otherwise, runs /// a [Priority] of [Priority.animation] or higher. Otherwise, runs
/// all tasks. /// all tasks.
bool defaultSchedulingStrategy({ int priority, SchedulerBinding scheduler }) { bool defaultSchedulingStrategy({ required int priority, required SchedulerBinding scheduler }) {
if (scheduler.transientCallbackCount > 0) if (scheduler.transientCallbackCount > 0)
return priority >= Priority.animation.value; return priority >= Priority.animation.value;
return true; return true;
......
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
// Any changes to this file should be reflected in the debugAssertAllSchedulerVarsUnset() // Any changes to this file should be reflected in the debugAssertAllSchedulerVarsUnset()
......
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
/// A task priority, as passed to [SchedulerBinding.scheduleTask]. /// A task priority, as passed to [SchedulerBinding.scheduleTask].
......
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'dart:async'; import 'dart:async';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
...@@ -71,7 +69,7 @@ class Ticker { ...@@ -71,7 +69,7 @@ class Ticker {
}()); }());
} }
TickerFuture _future; TickerFuture? _future;
/// Whether this ticker has been silenced. /// Whether this ticker has been silenced.
/// ///
...@@ -115,9 +113,9 @@ class Ticker { ...@@ -115,9 +113,9 @@ class Ticker {
return false; return false;
if (muted) if (muted)
return false; return false;
if (SchedulerBinding.instance.framesEnabled) if (SchedulerBinding.instance!.framesEnabled)
return true; return true;
if (SchedulerBinding.instance.schedulerPhase != SchedulerPhase.idle) if (SchedulerBinding.instance!.schedulerPhase != SchedulerPhase.idle)
return true; // for example, we might be in a warm-up frame or forced frame return true; // for example, we might be in a warm-up frame or forced frame
return false; return false;
} }
...@@ -130,7 +128,7 @@ class Ticker { ...@@ -130,7 +128,7 @@ class Ticker {
/// [isTicking]. /// [isTicking].
bool get isActive => _future != null; bool get isActive => _future != null;
Duration _startTime; Duration? _startTime;
/// Starts the clock for this [Ticker]. If the ticker is not [muted], then this /// Starts the clock for this [Ticker]. If the ticker is not [muted], then this
/// also starts calling the ticker's callback once per animation frame. /// also starts calling the ticker's callback once per animation frame.
...@@ -163,10 +161,10 @@ class Ticker { ...@@ -163,10 +161,10 @@ class Ticker {
if (shouldScheduleTick) { if (shouldScheduleTick) {
scheduleTick(); scheduleTick();
} }
if (SchedulerBinding.instance.schedulerPhase.index > SchedulerPhase.idle.index && if (SchedulerBinding.instance!.schedulerPhase.index > SchedulerPhase.idle.index &&
SchedulerBinding.instance.schedulerPhase.index < SchedulerPhase.postFrameCallbacks.index) SchedulerBinding.instance!.schedulerPhase.index < SchedulerPhase.postFrameCallbacks.index)
_startTime = SchedulerBinding.instance.currentFrameTimeStamp; _startTime = SchedulerBinding.instance!.currentFrameTimeStamp;
return _future; return _future!;
} }
/// Adds a debug representation of a [Ticker] optimized for including in error /// Adds a debug representation of a [Ticker] optimized for including in error
...@@ -197,7 +195,7 @@ class Ticker { ...@@ -197,7 +195,7 @@ class Ticker {
// We take the _future into a local variable so that isTicking is false // We take the _future into a local variable so that isTicking is false
// when we actually complete the future (isTicking uses _future to // when we actually complete the future (isTicking uses _future to
// determine its state). // determine its state).
final TickerFuture localFuture = _future; final TickerFuture localFuture = _future!;
_future = null; _future = null;
_startTime = null; _startTime = null;
assert(!isActive); assert(!isActive);
...@@ -213,7 +211,7 @@ class Ticker { ...@@ -213,7 +211,7 @@ class Ticker {
final TickerCallback _onTick; final TickerCallback _onTick;
int _animationId; int? _animationId;
/// Whether this [Ticker] has already scheduled a frame callback. /// Whether this [Ticker] has already scheduled a frame callback.
@protected @protected
...@@ -237,7 +235,7 @@ class Ticker { ...@@ -237,7 +235,7 @@ class Ticker {
_animationId = null; _animationId = null;
_startTime ??= timeStamp; _startTime ??= timeStamp;
_onTick(timeStamp - _startTime); _onTick(timeStamp - _startTime!);
// The onTick callback may have scheduled another tick already, for // The onTick callback may have scheduled another tick already, for
// example by calling stop then start again. // example by calling stop then start again.
...@@ -252,7 +250,7 @@ class Ticker { ...@@ -252,7 +250,7 @@ class Ticker {
void scheduleTick({ bool rescheduling = false }) { void scheduleTick({ bool rescheduling = false }) {
assert(!scheduled); assert(!scheduled);
assert(shouldScheduleTick); assert(shouldScheduleTick);
_animationId = SchedulerBinding.instance.scheduleFrameCallback(_tick, rescheduling: rescheduling); _animationId = SchedulerBinding.instance!.scheduleFrameCallback(_tick, rescheduling: rescheduling);
} }
/// Cancels the frame callback that was requested by [scheduleTick], if any. /// Cancels the frame callback that was requested by [scheduleTick], if any.
...@@ -264,7 +262,7 @@ class Ticker { ...@@ -264,7 +262,7 @@ class Ticker {
@protected @protected
void unscheduleTick() { void unscheduleTick() {
if (scheduled) { if (scheduled) {
SchedulerBinding.instance.cancelFrameCallbackWithId(_animationId); SchedulerBinding.instance!.cancelFrameCallbackWithId(_animationId!);
_animationId = null; _animationId = null;
} }
assert(!shouldScheduleTick); assert(!shouldScheduleTick);
...@@ -301,7 +299,7 @@ class Ticker { ...@@ -301,7 +299,7 @@ class Ticker {
@mustCallSuper @mustCallSuper
void dispose() { void dispose() {
if (_future != null) { if (_future != null) {
final TickerFuture localFuture = _future; final TickerFuture localFuture = _future!;
_future = null; _future = null;
assert(!isActive); assert(!isActive);
unscheduleTick(); unscheduleTick();
...@@ -319,8 +317,8 @@ class Ticker { ...@@ -319,8 +317,8 @@ class Ticker {
/// An optional label can be provided for debugging purposes. /// An optional label can be provided for debugging purposes.
/// ///
/// This label will appear in the [toString] output in debug builds. /// This label will appear in the [toString] output in debug builds.
final String debugLabel; final String? debugLabel;
StackTrace _debugCreationStack; late StackTrace _debugCreationStack;
@override @override
String toString({ bool debugIncludeStack = false }) { String toString({ bool debugIncludeStack = false }) {
...@@ -374,14 +372,14 @@ class TickerFuture implements Future<void> { ...@@ -374,14 +372,14 @@ class TickerFuture implements Future<void> {
} }
final Completer<void> _primaryCompleter = Completer<void>(); final Completer<void> _primaryCompleter = Completer<void>();
Completer<void> _secondaryCompleter; Completer<void>? _secondaryCompleter;
bool _completed; // null means unresolved, true means complete, false means canceled bool? _completed; // null means unresolved, true means complete, false means canceled
void _complete() { void _complete() {
assert(_completed == null); assert(_completed == null);
_completed = true; _completed = true;
_primaryCompleter.complete(null); _primaryCompleter.complete();
_secondaryCompleter?.complete(null); _secondaryCompleter?.complete();
} }
void _cancel(Ticker ticker) { void _cancel(Ticker ticker) {
...@@ -415,14 +413,14 @@ class TickerFuture implements Future<void> { ...@@ -415,14 +413,14 @@ class TickerFuture implements Future<void> {
if (_secondaryCompleter == null) { if (_secondaryCompleter == null) {
_secondaryCompleter = Completer<void>(); _secondaryCompleter = Completer<void>();
if (_completed != null) { if (_completed != null) {
if (_completed) { if (_completed!) {
_secondaryCompleter.complete(); _secondaryCompleter!.complete();
} else { } else {
_secondaryCompleter.completeError(const TickerCanceled()); _secondaryCompleter!.completeError(const TickerCanceled());
} }
} }
} }
return _secondaryCompleter.future; return _secondaryCompleter!.future;
} }
@override @override
...@@ -431,17 +429,17 @@ class TickerFuture implements Future<void> { ...@@ -431,17 +429,17 @@ class TickerFuture implements Future<void> {
} }
@override @override
Future<void> catchError(Function onError, { bool test(dynamic error) }) { Future<void> catchError(Function onError, { bool Function(Object)? test }) {
return _primaryCompleter.future.catchError(onError, test: test); return _primaryCompleter.future.catchError(onError, test: test);
} }
@override @override
Future<R> then<R>(FutureOr<R> onValue(void value), { Function onError }) { Future<R> then<R>(FutureOr<R> onValue(void value), { Function? onError }) {
return _primaryCompleter.future.then<R>(onValue, onError: onError); return _primaryCompleter.future.then<R>(onValue, onError: onError);
} }
@override @override
Future<void> timeout(Duration timeLimit, { dynamic onTimeout() }) { Future<void> timeout(Duration timeLimit, { FutureOr<void> Function()? onTimeout }) {
return _primaryCompleter.future.timeout(timeLimit, onTimeout: onTimeout); return _primaryCompleter.future.timeout(timeLimit, onTimeout: onTimeout);
} }
...@@ -451,7 +449,7 @@ class TickerFuture implements Future<void> { ...@@ -451,7 +449,7 @@ class TickerFuture implements Future<void> {
} }
@override @override
String toString() => '${describeIdentity(this)}(${ _completed == null ? "active" : _completed ? "complete" : "canceled" })'; String toString() => '${describeIdentity(this)}(${ _completed == null ? "active" : _completed! ? "complete" : "canceled" })';
} }
/// Exception thrown by [Ticker] objects on the [TickerFuture.orCancel] future /// Exception thrown by [Ticker] objects on the [TickerFuture.orCancel] future
...@@ -464,7 +462,7 @@ class TickerCanceled implements Exception { ...@@ -464,7 +462,7 @@ class TickerCanceled implements Exception {
/// ///
/// This may be null in the case that the [Future] created for /// This may be null in the case that the [Future] created for
/// [TickerFuture.orCancel] was created after the ticker was canceled. /// [TickerFuture.orCancel] was created after the ticker was canceled.
final Ticker ticker; final Ticker? ticker;
@override @override
String toString() { String toString() {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment