Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(345)

Side by Side Diff: pkg/barback/lib/src/utils.dart

Issue 5695057915019264: Make barback more package-aware. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Re-upload Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library barback.utils; 5 library barback.utils;
6 6
7 import 'dart:async';
8
7 /// Converts a number in the range [0-255] to a two digit hex string. 9 /// Converts a number in the range [0-255] to a two digit hex string.
8 /// 10 ///
9 /// For example, given `255`, returns `ff`. 11 /// For example, given `255`, returns `ff`.
10 String byteToHex(int byte) { 12 String byteToHex(int byte) {
11 assert(byte >= 0 && byte <= 255); 13 assert(byte >= 0 && byte <= 255);
12 14
13 const DIGITS = "0123456789abcdef"; 15 const DIGITS = "0123456789abcdef";
14 return DIGITS[(byte ~/ 16) % 16] + DIGITS[byte % 16]; 16 return DIGITS[(byte ~/ 16) % 16] + DIGITS[byte % 16];
15 } 17 }
18
19 /// Group the elements in [iter] by the value returned by [fn].
20 ///
21 /// This returns a map whose keys are the return values of [fn] and whose values
22 /// are lists of each element in [iter] for which [fn] returned that key.
23 Map groupBy(Iterable iter, fn(element)) {
24 var map = {};
25 for (var element in iter) {
26 var list = map.putIfAbsent(fn(element), () => []);
27 list.add(element);
28 }
29 return map;
30 }
31
32 /// Flattens nested lists inside an iterable into a single list containing only
33 /// non-list elements.
34 List flatten(Iterable nested) {
35 var result = [];
36 helper(list) {
37 for (var element in list) {
38 if (element is List) {
Bob Nystrom 2013/07/11 23:03:40 is Iterable
nweiz 2013/07/15 22:11:44 That seems a little dangerous. A lot of things can
Bob Nystrom 2013/07/16 17:36:01 Conversely, a lot of things extend iterable that d
nweiz 2013/07/16 19:39:39 That case is more straightforward to detect. If th
39 helper(element);
40 } else {
41 result.add(element);
42 }
43 }
44 }
45 helper(nested);
46 return result;
47 }
48
49 /// Passes each key/value pair in [map] to [fn] and returns a new [Map] whose
50 /// values are the return values of [fn].
51 Map mapMapValues(Map map, fn(key, value)) =>
52 new Map.fromIterable(map.keys, value: (key) => fn(key, map[key]));
53
54 /// Merges [streams] into a single stream that emits events from all sources.
55 Stream mergeStreams(Iterable<Stream> streams) {
56 streams = streams.toList();
57 var doneCount = 0;
58 var controller = new StreamController(sync: true);
Bob Nystrom 2013/07/11 23:03:40 Document why "sync: true"
nweiz 2013/07/15 22:11:44 Done.
59
60 for (var stream in streams) {
61 stream.listen((value) {
62 controller.add(value);
63 }, onError: (error) {
64 controller.addError(error);
65 }, onDone: () {
66 doneCount++;
67 if (doneCount == streams.length) controller.close();
68 });
69 }
70
71 return controller.stream;
72 }
73
74 /// Prepends each line in [text] with [prefix]. If [firstPrefix] is passed, the
75 /// first line is prefixed with that instead.
76 String prefixLines(String text, {String prefix: '| ', String firstPrefix}) {
77 var lines = text.split('\n');
78 if (firstPrefix == null) {
79 return lines.map((line) => '$prefix$line').join('\n');
80 }
81
82 var firstLine = "$firstPrefix${lines.first}";
83 lines = lines.skip(1).map((line) => '$prefix$line').toList();
84 lines.insert(0, firstLine);
85 return lines.join('\n');
86 }
87
88 /// Returns a [Future] that completes after pumping the event queue [times]
89 /// times. By default, this should pump the event queue enough times to allow
90 /// any code to run, as long as it's not waiting on some external event.
91 Future pumpEventQueue([int times=20]) {
92 if (times == 0) return new Future.value();
93 // We use a delayed future to allow runAsync events to finish. The
94 // Future.value or Future() constructors use runAsync themselves and would
95 // therefore not wait for runAsync callbacks that are scheduled after invoking
96 // this method.
97 return new Future.delayed(Duration.ZERO, () => pumpEventQueue(times - 1));
98 }
99
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698