OLD | NEW |
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 watcher.utils; | 5 library watcher.utils; |
6 | 6 |
| 7 import 'dart:async'; |
7 import 'dart:io'; | 8 import 'dart:io'; |
| 9 import 'dart:collection'; |
8 | 10 |
9 /// Returns `true` if [error] is a [FileSystemException] for a missing | 11 /// Returns `true` if [error] is a [FileSystemException] for a missing |
10 /// directory. | 12 /// directory. |
11 bool isDirectoryNotFoundException(error) { | 13 bool isDirectoryNotFoundException(error) { |
12 if (error is! FileSystemException) return false; | 14 if (error is! FileSystemException) return false; |
13 | 15 |
14 // See dartbug.com/12461 and tests/standalone/io/directory_error_test.dart. | 16 // See dartbug.com/12461 and tests/standalone/io/directory_error_test.dart. |
15 var notFoundCode = Platform.operatingSystem == "windows" ? 3 : 2; | 17 var notFoundCode = Platform.operatingSystem == "windows" ? 3 : 2; |
16 return error.osError.errorCode == notFoundCode; | 18 return error.osError.errorCode == notFoundCode; |
17 } | 19 } |
| 20 |
| 21 /// Returns a buffered stream that will emit the same values as the stream |
| 22 /// returned by [future] once [future] completes. |
| 23 /// |
| 24 /// If [future] completes to an error, the return value will emit that error and |
| 25 /// then close. |
| 26 Stream futureStream(Future<Stream> future) { |
| 27 var controller = new StreamController(sync: true); |
| 28 future.then((stream) { |
| 29 stream.listen( |
| 30 controller.add, |
| 31 onError: controller.addError, |
| 32 onDone: controller.close); |
| 33 }).catchError((e, stackTrace) { |
| 34 controller.addError(e, stackTrace); |
| 35 controller.close(); |
| 36 }); |
| 37 return controller.stream; |
| 38 } |
| 39 |
| 40 /// Like [new Future], but avoids around issue 11911 by using [new Future.value] |
| 41 /// under the covers. |
| 42 Future newFuture(callback()) => new Future.value().then((_) => callback()); |
| 43 |
| 44 /// A stream transformer that batches all events that are sent at the same time. |
| 45 /// |
| 46 /// When multiple events are synchronously added to a stream controller, the |
| 47 /// [StreamController] implementation uses [scheduleMicrotask] to schedule the |
| 48 /// asynchronous firing of each event. In order to recreate the synchronous |
| 49 /// batches, this collates all the events that are received in "nearby" |
| 50 /// microtasks. |
| 51 class BatchedStreamTransformer<T> implements StreamTransformer<T, List<T>> { |
| 52 Stream<List<T>> bind(Stream<T> input) { |
| 53 var batch = new Queue(); |
| 54 return new StreamTransformer<T, List<T>>.fromHandlers( |
| 55 handleData: (event, sink) { |
| 56 batch.add(event); |
| 57 |
| 58 // [Timer.run] schedules an event that runs after any microtasks that have |
| 59 // been scheduled. |
| 60 Timer.run(() { |
| 61 if (batch.isEmpty) return; |
| 62 sink.add(batch.toList()); |
| 63 batch.clear(); |
| 64 }); |
| 65 }, handleDone: (sink) { |
| 66 if (batch.isNotEmpty) { |
| 67 sink.add(batch.toList()); |
| 68 batch.clear(); |
| 69 } |
| 70 sink.close(); |
| 71 }).bind(input); |
| 72 } |
| 73 } |
OLD | NEW |