| 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.directory_watcher; | 5 library watcher.directory_watcher; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'dart:io'; | 8 import 'dart:io'; |
| 9 | 9 |
| 10 import 'package:crypto/crypto.dart'; | 10 import 'package:crypto/crypto.dart'; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 35 /// If the watcher is not currently monitoring the directory (because there | 35 /// If the watcher is not currently monitoring the directory (because there |
| 36 /// are no subscribers to [events]), this returns a future that isn't | 36 /// are no subscribers to [events]), this returns a future that isn't |
| 37 /// complete yet. It will complete when a subscriber starts listening and | 37 /// complete yet. It will complete when a subscriber starts listening and |
| 38 /// the watcher finishes any initialization work it needs to do. | 38 /// the watcher finishes any initialization work it needs to do. |
| 39 /// | 39 /// |
| 40 /// If the watcher is already monitoring, this returns an already complete | 40 /// If the watcher is already monitoring, this returns an already complete |
| 41 /// future. | 41 /// future. |
| 42 Future get ready => _ready.future; | 42 Future get ready => _ready.future; |
| 43 Completer _ready = new Completer(); | 43 Completer _ready = new Completer(); |
| 44 | 44 |
| 45 /// The amount of time the watcher pauses between successive polls of the |
| 46 /// directory contents. |
| 47 final Duration pollingDelay; |
| 48 |
| 45 /// The previous status of the files in the directory. | 49 /// The previous status of the files in the directory. |
| 46 /// | 50 /// |
| 47 /// Used to tell which files have been modified. | 51 /// Used to tell which files have been modified. |
| 48 final _statuses = new Map<String, _FileStatus>(); | 52 final _statuses = new Map<String, _FileStatus>(); |
| 49 | 53 |
| 50 /// Creates a new [DirectoryWatcher] monitoring [directory]. | 54 /// Creates a new [DirectoryWatcher] monitoring [directory]. |
| 51 DirectoryWatcher(this.directory) { | 55 /// |
| 56 /// If [pollingDelay] is passed, it specifies the amount of time the watcher |
| 57 /// will pause between successive polls of the directory contents. Making |
| 58 /// this shorter will give more immediate feedback at the expense of doing |
| 59 /// more IO and higher CPU usage. Defaults to one second. |
| 60 DirectoryWatcher(this.directory, {Duration pollingDelay}) |
| 61 : pollingDelay = pollingDelay != null ? pollingDelay : |
| 62 new Duration(seconds: 1) { |
| 52 _events = new StreamController<WatchEvent>.broadcast(onListen: () { | 63 _events = new StreamController<WatchEvent>.broadcast(onListen: () { |
| 53 _state = _state.listen(this); | 64 _state = _state.listen(this); |
| 54 }, onCancel: () { | 65 }, onCancel: () { |
| 55 _state = _state.cancel(this); | 66 _state = _state.cancel(this); |
| 56 }); | 67 }); |
| 57 } | 68 } |
| 58 | 69 |
| 59 /// Starts the asynchronous polling process. | 70 /// Starts the asynchronous polling process. |
| 60 /// | 71 /// |
| 61 /// Scans the contents of the directory and compares the results to the | 72 /// Scans the contents of the directory and compares the results to the |
| (...skipping 24 matching lines...) Expand all Loading... |
| 86 _statuses.remove(removed); | 97 _statuses.remove(removed); |
| 87 } | 98 } |
| 88 | 99 |
| 89 var previousState = _state; | 100 var previousState = _state; |
| 90 _state = _state.finish(this); | 101 _state = _state.finish(this); |
| 91 | 102 |
| 92 // If we were already sending notifications, add a bit of delay before | 103 // If we were already sending notifications, add a bit of delay before |
| 93 // restarting just so that we don't whale on the file system. | 104 // restarting just so that we don't whale on the file system. |
| 94 // TODO(rnystrom): Tune this and/or make it tunable? | 105 // TODO(rnystrom): Tune this and/or make it tunable? |
| 95 if (_state.shouldNotify) { | 106 if (_state.shouldNotify) { |
| 96 return new Future.delayed(new Duration(seconds: 1)); | 107 return new Future.delayed(pollingDelay); |
| 97 } | 108 } |
| 98 }).then((_) { | 109 }).then((_) { |
| 99 // Make sure we haven't transitioned to a non-watching state during the | 110 // Make sure we haven't transitioned to a non-watching state during the |
| 100 // delay. | 111 // delay. |
| 101 if (_state.shouldWatch) _watch(); | 112 if (_state.shouldWatch) _watch(); |
| 102 }); | 113 }); |
| 103 } | 114 } |
| 104 | 115 |
| 105 /// Compares the current state of the file at [path] to the state it was in | 116 /// Compares the current state of the file at [path] to the state it was in |
| 106 /// the last time it was scanned. | 117 /// the last time it was scanned. |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 217 | 228 |
| 218 class _FileStatus { | 229 class _FileStatus { |
| 219 /// The last time the file was modified. | 230 /// The last time the file was modified. |
| 220 DateTime modified; | 231 DateTime modified; |
| 221 | 232 |
| 222 /// The SHA-1 hash of the contents of the file. | 233 /// The SHA-1 hash of the contents of the file. |
| 223 List<int> hash; | 234 List<int> hash; |
| 224 | 235 |
| 225 _FileStatus(this.modified, this.hash); | 236 _FileStatus(this.modified, this.hash); |
| 226 } | 237 } |
| OLD | NEW |