Commit e20ef502 authored by Adam Barth's avatar Adam Barth

Merge pull request #1178 from abarth/double_tap_assert

DoubleTap gesture asserts when rejected
parents 17ae19e8 07a9cc75
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// 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.
import 'dart:collection';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'events.dart'; import 'events.dart';
...@@ -13,14 +15,14 @@ typedef void PointerExceptionHandler(PointerRouter source, PointerEvent event, P ...@@ -13,14 +15,14 @@ typedef void PointerExceptionHandler(PointerRouter source, PointerEvent event, P
/// A routing table for [PointerEvent] events. /// A routing table for [PointerEvent] events.
class PointerRouter { class PointerRouter {
final Map<int, List<PointerRoute>> _routeMap = new Map<int, List<PointerRoute>>(); final Map<int, LinkedHashSet<PointerRoute>> _routeMap = new Map<int, LinkedHashSet<PointerRoute>>();
/// Adds a route to the routing table. /// Adds a route to the routing table.
/// ///
/// Whenever this object routes a [PointerEvent] corresponding to /// Whenever this object routes a [PointerEvent] corresponding to
/// pointer, call route. /// pointer, call route.
void addRoute(int pointer, PointerRoute route) { void addRoute(int pointer, PointerRoute route) {
List<PointerRoute> routes = _routeMap.putIfAbsent(pointer, () => new List<PointerRoute>()); LinkedHashSet<PointerRoute> routes = _routeMap.putIfAbsent(pointer, () => new LinkedHashSet<PointerRoute>());
assert(!routes.contains(route)); assert(!routes.contains(route));
routes.add(route); routes.add(route);
} }
...@@ -31,7 +33,7 @@ class PointerRouter { ...@@ -31,7 +33,7 @@ class PointerRouter {
/// pointer. Requires that this route was previously added to the router. /// pointer. Requires that this route was previously added to the router.
void removeRoute(int pointer, PointerRoute route) { void removeRoute(int pointer, PointerRoute route) {
assert(_routeMap.containsKey(pointer)); assert(_routeMap.containsKey(pointer));
List<PointerRoute> routes = _routeMap[pointer]; LinkedHashSet<PointerRoute> routes = _routeMap[pointer];
assert(routes.contains(route)); assert(routes.contains(route));
routes.remove(route); routes.remove(route);
if (routes.isEmpty) if (routes.isEmpty)
...@@ -53,10 +55,12 @@ class PointerRouter { ...@@ -53,10 +55,12 @@ class PointerRouter {
/// Routes are called in the order in which they were added to the /// Routes are called in the order in which they were added to the
/// PointerRouter object. /// PointerRouter object.
void route(PointerEvent event) { void route(PointerEvent event) {
List<PointerRoute> routes = _routeMap[event.pointer]; LinkedHashSet<PointerRoute> routes = _routeMap[event.pointer];
if (routes == null) if (routes == null)
return; return;
for (PointerRoute route in new List<PointerRoute>.from(routes)) { for (PointerRoute route in new List<PointerRoute>.from(routes)) {
if (!routes.contains(route))
continue;
try { try {
route(event); route(event);
} catch (exception, stack) { } catch (exception, stack) {
......
...@@ -27,4 +27,19 @@ void main() { ...@@ -27,4 +27,19 @@ void main() {
router.route(pointer3.up()); router.route(pointer3.up());
expect(callbackRan, isFalse); expect(callbackRan, isFalse);
}); });
test('Supports re-entrant cancellation', () {
bool callbackRan = false;
void callback(PointerEvent event) {
callbackRan = true;
}
PointerRouter router = new PointerRouter();
router.addRoute(2, (PointerEvent event) {
router.removeRoute(2, callback);
});
router.addRoute(2, callback);
TestPointer pointer2 = new TestPointer(2);
router.route(pointer2.down(Point.origin));
expect(callbackRan, isFalse);
});
} }
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