| OLD | NEW |
| (Empty) |
| 1 // Copyright 2013 Google Inc. All Rights Reserved. | |
| 2 // | |
| 3 // Licensed under the Apache License, Version 2.0 (the "License"); | |
| 4 // you may not use this file except in compliance with the License. | |
| 5 // You may obtain a copy of the License at | |
| 6 // | |
| 7 // http://www.apache.org/licenses/LICENSE-2.0 | |
| 8 // | |
| 9 // Unless required by applicable law or agreed to in writing, software | |
| 10 // distributed under the License is distributed on an "AS IS" BASIS, | |
| 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 12 // See the License for the specific language governing permissions and | |
| 13 // limitations under the License. | |
| 14 | |
| 15 part of quiver.async; | |
| 16 | |
| 17 /** | |
| 18 * Splits a [Stream] of events into multiple Streams based on a set of | |
| 19 * predicates. | |
| 20 * | |
| 21 * Using StreamRouter differs from [Stream.where] because events are only sent | |
| 22 * to one Stream. If more than one predicate matches the event, the event is | |
| 23 * sent to the stream created by the earlier call to [route]. Events not matched | |
| 24 * by a call to [route] are sent to the [defaultStream]. | |
| 25 * | |
| 26 * Example: | |
| 27 * import 'dart:html'; | |
| 28 * import 'package:quiver/async.dart'; | |
| 29 * | |
| 30 * var router = new StreamRouter(window.onClick); | |
| 31 * var onRightClick = router.route((e) => e.button == 2); | |
| 32 * var onAltClick = router.route((e) => e.altKey); | |
| 33 * var onOtherClick router.defaultStream; | |
| 34 */ | |
| 35 class StreamRouter<T> { | |
| 36 final Stream<T> _incoming; | |
| 37 StreamSubscription _subscription; | |
| 38 | |
| 39 final List<_Route> _routes = <_Route>[]; | |
| 40 final StreamController<T> _defaultController = | |
| 41 new StreamController<T>.broadcast(); | |
| 42 | |
| 43 /** | |
| 44 * Create a new StreamRouter that listens to the [incoming] stream. | |
| 45 */ | |
| 46 StreamRouter(Stream<T> incoming) : _incoming = incoming { | |
| 47 _subscription = _incoming.listen(_handle, onDone: close); | |
| 48 } | |
| 49 | |
| 50 /** | |
| 51 * Events that match [predicate] are sent to the stream created by this | |
| 52 * method, and not sent to any other router streams. | |
| 53 */ | |
| 54 Stream<T> route(bool predicate(T event)) { | |
| 55 var controller = new StreamController<T>.broadcast(); | |
| 56 _routes.add(new _Route(predicate, controller)); | |
| 57 return controller.stream; | |
| 58 } | |
| 59 | |
| 60 Stream<T> get defaultStream => _defaultController.stream; | |
| 61 | |
| 62 Future close() { | |
| 63 return Future.wait(_routes.map((r) => r.controller.close())).then((_) { | |
| 64 _subscription.cancel(); | |
| 65 }); | |
| 66 } | |
| 67 | |
| 68 void _handle(T event) { | |
| 69 var route = | |
| 70 _routes.firstWhere((r) => r.predicate(event), orElse: () => null); | |
| 71 var controller = (route != null) ? route.controller : _defaultController; | |
| 72 controller.add(event); | |
| 73 } | |
| 74 } | |
| 75 | |
| 76 typedef bool _Predicate(event); | |
| 77 | |
| 78 class _Route { | |
| 79 final _Predicate predicate; | |
| 80 final StreamController controller; | |
| 81 | |
| 82 _Route(this.predicate, this.controller); | |
| 83 } | |
| OLD | NEW |