Commit de772647 authored by Ian Hickson's avatar Ian Hickson

Merge pull request #525 from Hixie/yak3-routes-typed

Give type arguments to routes.
parents 1fbec91f 13f3a9be
......@@ -115,8 +115,8 @@ class Dialog extends StatelessComponent {
}
}
class _DialogRoute extends ModalRoute {
_DialogRoute({ Completer completer, this.child }) : super(completer: completer);
class _DialogRoute<T> extends ModalRoute<T> {
_DialogRoute({ Completer<T> completer, this.child }) : super(completer: completer);
final Widget child;
......
......@@ -36,7 +36,7 @@ class _MaterialPageTransition extends TransitionWithChild {
}
}
class MaterialPageRoute extends ModalRoute {
class MaterialPageRoute<T> extends ModalRoute<T> {
MaterialPageRoute({
this.builder,
NamedRouteSettings settings: const NamedRouteSettings()
......
......@@ -5,10 +5,10 @@
import 'framework.dart';
import 'overlay.dart';
abstract class Route {
abstract class Route<T> {
List<OverlayEntry> get overlayEntries;
void didPush(OverlayState overlay, OverlayEntry insertionPoint) { }
void didPop(dynamic result) { }
void didPop(T result) { }
/// The given route has been pushed onto the navigator after this route.
/// Return true if the route before this one should be notified also. The
......@@ -140,6 +140,9 @@ class NavigatorState extends State<Navigator> {
/// Do not use this for ModalRoutes, or indeed anything other than
/// StateRoutes. Doing so would cause very odd results, e.g. ModalRoutes would
/// get confused about who is current.
///
/// The type of the result argument, if provided, must match the type argument
/// of the class of the given route. (In practice, this is usually "dynamic".)
void remove(Route route, [dynamic result]) {
assert(_modal.contains(route));
assert(route.overlayEntries.isEmpty);
......@@ -155,6 +158,10 @@ class NavigatorState extends State<Navigator> {
/// Removes the current route, notifying the observer (if any), and the
/// previous routes (using [Route.didPopNext]).
///
/// The type of the result argument, if provided, must match the type argument
/// of the class of the current route. (In practice, this is usually
/// "dynamic".)
void pop([dynamic result]) {
setState(() {
// We use setState to guarantee that we'll rebuild, since the routes can't
......
......@@ -23,6 +23,7 @@ class StateRoute extends Route {
List<OverlayEntry> get overlayEntries => const <OverlayEntry>[];
void didPop(dynamic result) {
assert(result == null);
if (onPop != null)
onPop();
}
......@@ -31,7 +32,7 @@ class StateRoute extends Route {
bool didPopNext(Route nextRoute) => true;
}
abstract class OverlayRoute extends Route {
abstract class OverlayRoute<T> extends Route<T> {
List<WidgetBuilder> get builders => const <WidgetBuilder>[];
List<OverlayEntry> get overlayEntries => _overlayEntries;
......@@ -46,7 +47,7 @@ abstract class OverlayRoute extends Route {
}
// Subclasses shouldn't call this if they want to delay the finished() call.
void didPop(dynamic result) {
void didPop(T result) {
finished();
}
......@@ -64,11 +65,15 @@ abstract class OverlayRoute extends Route {
}
}
// TODO(abarth): Should we add a type for the result?
abstract class TransitionRoute extends OverlayRoute {
TransitionRoute({ this.completer });
abstract class TransitionRoute<T> extends OverlayRoute<T> {
TransitionRoute({
Completer<T> popCompleter,
Completer<T> transitionCompleter
}) : _popCompleter = popCompleter,
_transitionCompleter = transitionCompleter;
final Completer completer;
final Completer<T> _popCompleter;
final Completer<T> _transitionCompleter;
Duration get transitionDuration;
bool get opaque;
......@@ -82,7 +87,7 @@ abstract class TransitionRoute extends OverlayRoute {
return new Performance(duration: duration, debugLabel: debugLabel);
}
dynamic _result;
T _result;
void _handleStatusChanged(PerformanceStatus status) {
switch (status) {
......@@ -97,7 +102,6 @@ abstract class TransitionRoute extends OverlayRoute {
break;
case PerformanceStatus.dismissed:
super.finished(); // clear the overlays
completer?.complete(_result);
break;
}
}
......@@ -109,9 +113,15 @@ abstract class TransitionRoute extends OverlayRoute {
super.didPush(overlay, insertionPoint);
}
void didPop(dynamic result) {
void didPop(T result) {
_result = result;
_performance.reverse();
_popCompleter?.complete(_result);
}
void finished() {
super.finished();
_transitionCompleter?.complete(_result);
}
String get debugLabel => '$runtimeType';
......@@ -202,11 +212,11 @@ class ModalPosition {
final double left;
}
abstract class ModalRoute extends TransitionRoute {
abstract class ModalRoute<T> extends TransitionRoute<T> {
ModalRoute({
Completer completer,
Completer<T> completer,
this.settings: const NamedRouteSettings()
}) : super(completer: completer);
}) : super(popCompleter: completer);
// The API for general users of this class
......@@ -263,7 +273,7 @@ abstract class ModalRoute extends TransitionRoute {
super.didPush(overlay, insertionPoint);
}
void didPop(dynamic result) {
void didPop(T result) {
assert(_isCurrent);
_isCurrent = false;
super.didPop(result);
......
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