| OLD | NEW | 
| (Empty) |  | 
 |   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 | 
 |   3 // BSD-style license that can be found in the LICENSE file. | 
 |   4  | 
 |   5 library watcher.directory_watcher.resubscribable; | 
 |   6  | 
 |   7 import 'dart:async'; | 
 |   8 import 'dart:io'; | 
 |   9  | 
 |  10 import '../directory_watcher.dart'; | 
 |  11 import '../utils.dart'; | 
 |  12 import '../watch_event.dart'; | 
 |  13  | 
 |  14 typedef ManuallyClosedDirectoryWatcher WatcherFactory(); | 
 |  15  | 
 |  16 /// A wrapper for [ManuallyClosedDirectoryWatcher] that encapsulates support for | 
 |  17 /// closing the watcher when it has no subscribers and re-opening it when it's | 
 |  18 /// re-subscribed. | 
 |  19 /// | 
 |  20 /// It's simpler to implement watchers without worrying about this behavior. | 
 |  21 /// This class wraps a watcher class which can be written with the simplifying | 
 |  22 /// assumption that it can continue emitting events until an explicit `close` | 
 |  23 /// method is called, at which point it will cease emitting events entirely. The | 
 |  24 /// [ManuallyClosedDirectoryWatcher] interface is used for these watchers. | 
 |  25 /// | 
 |  26 /// This would be more cleanly implemented as a function that takes a class and | 
 |  27 /// emits a new class, but Dart doesn't support that sort of thing. Instead it | 
 |  28 /// takes a factory function that produces instances of the inner class. | 
 |  29 abstract class ResubscribableDirectoryWatcher implements DirectoryWatcher { | 
 |  30   /// The factory function that produces instances of the inner class. | 
 |  31   final WatcherFactory _factory; | 
 |  32  | 
 |  33   final String directory; | 
 |  34  | 
 |  35   Stream<WatchEvent> get events => _eventsController.stream; | 
 |  36   StreamController<WatchEvent> _eventsController; | 
 |  37  | 
 |  38   bool get isReady => _readyCompleter.isCompleted; | 
 |  39  | 
 |  40   Future get ready => _readyCompleter.future; | 
 |  41   var _readyCompleter = new Completer(); | 
 |  42  | 
 |  43   /// Creates a new [ResubscribableDirectoryWatcher] wrapping the watchers | 
 |  44   /// emitted by [_factory]. | 
 |  45   ResubscribableDirectoryWatcher(this.directory, this._factory) { | 
 |  46     var watcher; | 
 |  47     var subscription; | 
 |  48  | 
 |  49     _eventsController = new StreamController<WatchEvent>.broadcast( | 
 |  50         onListen: () { | 
 |  51       watcher = _factory(); | 
 |  52       subscription = watcher.events.listen(_eventsController.add, | 
 |  53           onError: _eventsController.addError, | 
 |  54           onDone: _eventsController.close); | 
 |  55  | 
 |  56       // It's important that we complete the value of [_readyCompleter] at the | 
 |  57       // time [onListen] is called, as opposed to the value when [watcher.ready] | 
 |  58       // fires. A new completer may be created by that time. | 
 |  59       watcher.ready.then(_readyCompleter.complete); | 
 |  60     }, onCancel: () { | 
 |  61       // Cancel the subscription before closing the watcher so that the | 
 |  62       // watcher's `onDone` event doesn't close [events]. | 
 |  63       subscription.cancel(); | 
 |  64       watcher.close(); | 
 |  65       _readyCompleter = new Completer(); | 
 |  66     }, sync: true); | 
 |  67   } | 
 |  68 } | 
 |  69  | 
 |  70 /// An interface for watchers with an explicit, manual [close] method. | 
 |  71 /// | 
 |  72 /// See [ResubscribableDirectoryWatcher]. | 
 |  73 abstract class ManuallyClosedDirectoryWatcher implements DirectoryWatcher { | 
 |  74   /// Closes the watcher. | 
 |  75   /// | 
 |  76   /// Subclasses should close their [events] stream and release any internal | 
 |  77   /// resources. | 
 |  78   void close(); | 
 |  79 } | 
| OLD | NEW |