| 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.linux; | 5 library watcher.directory_watcher.linux; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'dart:io'; | 8 import 'dart:io'; |
| 9 | 9 |
| 10 import '../utils.dart'; | 10 import '../utils.dart'; |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 206 if (oldState != _EntryState.FILE && newState == _EntryState.FILE) { | 206 if (oldState != _EntryState.FILE && newState == _EntryState.FILE) { |
| 207 emitEvent(ChangeType.ADD); | 207 emitEvent(ChangeType.ADD); |
| 208 } else if (oldState == _EntryState.FILE && newState == _EntryState.FILE) { | 208 } else if (oldState == _EntryState.FILE && newState == _EntryState.FILE) { |
| 209 emitEvent(ChangeType.MODIFY); | 209 emitEvent(ChangeType.MODIFY); |
| 210 } else if (oldState == _EntryState.FILE && newState != _EntryState.FILE) { | 210 } else if (oldState == _EntryState.FILE && newState != _EntryState.FILE) { |
| 211 emitEvent(ChangeType.REMOVE); | 211 emitEvent(ChangeType.REMOVE); |
| 212 } | 212 } |
| 213 | 213 |
| 214 if (oldState == _EntryState.DIRECTORY) { | 214 if (oldState == _EntryState.DIRECTORY) { |
| 215 var watcher = _subWatchers.remove(path); | 215 var watcher = _subWatchers.remove(path); |
| 216 if (watcher == null) return; | 216 if (watcher == null) continue; |
| 217 for (var path in watcher._allFiles) { | 217 for (var path in watcher._allFiles) { |
| 218 _eventsController.add(new WatchEvent(ChangeType.REMOVE, path)); | 218 _eventsController.add(new WatchEvent(ChangeType.REMOVE, path)); |
| 219 } | 219 } |
| 220 watcher.close(); | 220 watcher.close(); |
| 221 } | 221 } |
| 222 | 222 |
| 223 if (newState == _EntryState.DIRECTORY) _watchSubdir(path); | 223 if (newState == _EntryState.DIRECTORY) _watchSubdir(path); |
| 224 } | 224 } |
| 225 } | 225 } |
| 226 | 226 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 240 if (event is FileSystemDeleteEvent) return ChangeType.REMOVE; | 240 if (event is FileSystemDeleteEvent) return ChangeType.REMOVE; |
| 241 if (event is FileSystemCreateEvent) return ChangeType.ADD; | 241 if (event is FileSystemCreateEvent) return ChangeType.ADD; |
| 242 | 242 |
| 243 assert(event is FileSystemModifyEvent); | 243 assert(event is FileSystemModifyEvent); |
| 244 return ChangeType.MODIFY; | 244 return ChangeType.MODIFY; |
| 245 } | 245 } |
| 246 | 246 |
| 247 /// Handles the underlying event stream closing, indicating that the directory | 247 /// Handles the underlying event stream closing, indicating that the directory |
| 248 /// being watched was removed. | 248 /// being watched was removed. |
| 249 void _onDone() { | 249 void _onDone() { |
| 250 // Most of the time when a directory is removed, its contents will get |
| 251 // individual REMOVE events before the watch stream is closed -- in that |
| 252 // case, [_entries] will be empty here. However, if the directory's removal |
| 253 // is caused by a MOVE, we need to manually emit events. |
| 254 if (isReady) { |
| 255 _entries.forEach((path, state) { |
| 256 if (state == _EntryState.DIRECTORY) return; |
| 257 _eventsController.add(new WatchEvent(ChangeType.REMOVE, path)); |
| 258 }); |
| 259 } |
| 260 |
| 250 // The parent directory often gets a close event before the subdirectories | 261 // The parent directory often gets a close event before the subdirectories |
| 251 // are done emitting events. We wait for them to finish before we close | 262 // are done emitting events. We wait for them to finish before we close |
| 252 // [events] so that we can be sure to emit a remove event for every file | 263 // [events] so that we can be sure to emit a remove event for every file |
| 253 // that used to exist. | 264 // that used to exist. |
| 254 Future.wait(_subWatchers.values.map((watcher) { | 265 Future.wait(_subWatchers.values.map((watcher) { |
| 255 try { | 266 try { |
| 256 return watcher.events.toList(); | 267 return watcher.events.toList(); |
| 257 } on StateError catch (_) { | 268 } on StateError catch (_) { |
| 258 // It's possible that [watcher.events] is closed but the onDone event | 269 // It's possible that [watcher.events] is closed but the onDone event |
| 259 // hasn't reached us yet. It's fine if so. | 270 // hasn't reached us yet. It's fine if so. |
| (...skipping 26 matching lines...) Expand all Loading... |
| 286 static const DIRECTORY = const _EntryState._("directory"); | 297 static const DIRECTORY = const _EntryState._("directory"); |
| 287 | 298 |
| 288 const _EntryState._(this._name); | 299 const _EntryState._(this._name); |
| 289 | 300 |
| 290 /// Returns [DIRECTORY] if [isDir] is true, and [FILE] otherwise. | 301 /// Returns [DIRECTORY] if [isDir] is true, and [FILE] otherwise. |
| 291 factory _EntryState(bool isDir) => | 302 factory _EntryState(bool isDir) => |
| 292 isDir ? _EntryState.DIRECTORY : _EntryState.FILE; | 303 isDir ? _EntryState.DIRECTORY : _EntryState.FILE; |
| 293 | 304 |
| 294 String toString() => _name; | 305 String toString() => _name; |
| 295 } | 306 } |
| OLD | NEW |