pointer_router.dart 3.23 KB
Newer Older
Adam Barth's avatar
Adam Barth committed
1 2 3 4
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

5 6
import 'dart:collection';

7 8
import 'package:flutter/services.dart';

Kris Giesing's avatar
Kris Giesing committed
9
import 'events.dart';
Adam Barth's avatar
Adam Barth committed
10

Ian Hickson's avatar
Ian Hickson committed
11 12
/// A callback that receives a [PointerEvent]
typedef void PointerRoute(PointerEvent event);
Adam Barth's avatar
Adam Barth committed
13

14 15
typedef void PointerExceptionHandler(PointerRouter source, PointerEvent event, PointerRoute route, dynamic exception, StackTrace stack);

Ian Hickson's avatar
Ian Hickson committed
16
/// A routing table for [PointerEvent] events.
17
class PointerRouter {
18
  final Map<int, LinkedHashSet<PointerRoute>> _routeMap = new Map<int, LinkedHashSet<PointerRoute>>();
Adam Barth's avatar
Adam Barth committed
19

Ian Hickson's avatar
Ian Hickson committed
20
  /// Adds a route to the routing table.
Adam Barth's avatar
Adam Barth committed
21
  ///
Ian Hickson's avatar
Ian Hickson committed
22
  /// Whenever this object routes a [PointerEvent] corresponding to
Adam Barth's avatar
Adam Barth committed
23 24
  /// pointer, call route.
  void addRoute(int pointer, PointerRoute route) {
25
    LinkedHashSet<PointerRoute> routes = _routeMap.putIfAbsent(pointer, () => new LinkedHashSet<PointerRoute>());
Adam Barth's avatar
Adam Barth committed
26 27 28 29
    assert(!routes.contains(route));
    routes.add(route);
  }

Ian Hickson's avatar
Ian Hickson committed
30
  /// Removes a route from the routing table.
Adam Barth's avatar
Adam Barth committed
31
  ///
Ian Hickson's avatar
Ian Hickson committed
32
  /// No longer call route when routing a [PointerEvent] corresponding to
Adam Barth's avatar
Adam Barth committed
33 34
  /// pointer. Requires that this route was previously added to the router.
  void removeRoute(int pointer, PointerRoute route) {
Adam Barth's avatar
Adam Barth committed
35
    assert(_routeMap.containsKey(pointer));
36
    LinkedHashSet<PointerRoute> routes = _routeMap[pointer];
Adam Barth's avatar
Adam Barth committed
37 38 39 40 41 42
    assert(routes.contains(route));
    routes.remove(route);
    if (routes.isEmpty)
      _routeMap.remove(pointer);
  }

43 44 45 46 47
  /// This callback is invoked whenever an exception is caught by the pointer
  /// router. The 'source' argument is the [PointerRouter] object that caught
  /// the exception. The 'event' argument is the pointer event that was being
  /// routed. The 'route' argument is the callback that threw the exception. The
  /// 'exception' argument contains the object that was thrown, and the 'stack'
48 49 50
  /// argument contains the stack trace. If no handler is registered, then the
  /// human-readable parts of this information (the exception, event, and stack
  /// trace) will be printed to the console instead.
51 52 53
  PointerExceptionHandler debugPointerExceptionHandler;

  /// Calls the routes registered for this pointer event.
Adam Barth's avatar
Adam Barth committed
54
  ///
55 56
  /// Routes are called in the order in which they were added to the
  /// PointerRouter object.
Ian Hickson's avatar
Ian Hickson committed
57
  void route(PointerEvent event) {
58
    LinkedHashSet<PointerRoute> routes = _routeMap[event.pointer];
Adam Barth's avatar
Adam Barth committed
59
    if (routes == null)
60
      return;
61
    for (PointerRoute route in new List<PointerRoute>.from(routes)) {
62 63
      if (!routes.contains(route))
        continue;
64 65 66
      try {
        route(event);
      } catch (exception, stack) {
67
        if (debugPointerExceptionHandler != null) {
68
          debugPointerExceptionHandler(this, event, route, exception, stack);
69 70 71 72 73 74 75 76 77 78
        } else {
          debugPrint('-- EXCEPTION CAUGHT BY GESTURE LIBRARY ---------------------------------');
          debugPrint('The following exception was raised while routing a pointer event:');
          debugPrint('$exception');
          debugPrint('Event:');
          debugPrint('$event');
          debugPrint('Stack trace:');
          debugPrint('$stack');
          debugPrint('------------------------------------------------------------------------');
        }
79 80
      }
    }
Adam Barth's avatar
Adam Barth committed
81 82
  }
}