| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 resource; | 5 library resource; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'dart:collection'; | 8 import 'dart:collection'; |
| 9 import 'dart:io' as io; | 9 import 'dart:io' as io; |
| 10 | 10 |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 239 _provider._pathToResource.forEach((resourcePath, resource) { | 239 _provider._pathToResource.forEach((resourcePath, resource) { |
| 240 if (posix.dirname(resourcePath) == path) { | 240 if (posix.dirname(resourcePath) == path) { |
| 241 children.add(resource); | 241 children.add(resource); |
| 242 } | 242 } |
| 243 }); | 243 }); |
| 244 return children; | 244 return children; |
| 245 } | 245 } |
| 246 | 246 |
| 247 @override | 247 @override |
| 248 Stream<WatchEvent> get changes { | 248 Stream<WatchEvent> get changes { |
| 249 if (_provider._pathToWatcher.containsKey(path)) { | 249 StreamController<WatchEvent> streamController = new StreamController<WatchEv
ent>(); |
| 250 // Two clients watching the same path is not yet supported. | 250 if (!_provider._pathToWatchers.containsKey(path)) { |
| 251 // TODO(paulberry): add support for this if needed. | 251 _provider._pathToWatchers[path] = <StreamController<WatchEvent>>[]; |
| 252 throw new StateError('Path "$path" is already being watched for changes'); | |
| 253 } | 252 } |
| 254 StreamController<WatchEvent> streamController = new StreamController<WatchEv
ent>(); | 253 _provider._pathToWatchers[path].add(streamController); |
| 255 _provider._pathToWatcher[path] = streamController; | |
| 256 streamController.done.then((_) { | 254 streamController.done.then((_) { |
| 257 _provider._pathToWatcher.remove(path); | 255 _provider._pathToWatchers[path].remove(streamController); |
| 256 if (_provider._pathToWatchers[path].isEmpty) { |
| 257 _provider._pathToWatchers.remove(path); |
| 258 } |
| 258 }); | 259 }); |
| 259 return streamController.stream; | 260 return streamController.stream; |
| 260 } | 261 } |
| 261 } | 262 } |
| 262 | 263 |
| 263 | 264 |
| 264 /** | 265 /** |
| 265 * An in-memory implementation of [ResourceProvider]. | 266 * An in-memory implementation of [ResourceProvider]. |
| 266 * Use `/` as a path separator. | 267 * Use `/` as a path separator. |
| 267 */ | 268 */ |
| 268 class MemoryResourceProvider implements ResourceProvider { | 269 class MemoryResourceProvider implements ResourceProvider { |
| 269 final Map<String, _MemoryResource> _pathToResource = | 270 final Map<String, _MemoryResource> _pathToResource = |
| 270 new HashMap<String, _MemoryResource>(); | 271 new HashMap<String, _MemoryResource>(); |
| 271 final Map<String, String> _pathToContent = new HashMap<String, String>(); | 272 final Map<String, String> _pathToContent = new HashMap<String, String>(); |
| 272 final Map<String, int> _pathToTimestamp = new HashMap<String, int>(); | 273 final Map<String, int> _pathToTimestamp = new HashMap<String, int>(); |
| 273 final Map<String, StreamController<WatchEvent>> _pathToWatcher = | 274 final Map<String, List<StreamController<WatchEvent>>> _pathToWatchers = |
| 274 new HashMap<String, StreamController<WatchEvent>>(); | 275 new HashMap<String, List<StreamController<WatchEvent>>>(); |
| 275 int nextStamp = 0; | 276 int nextStamp = 0; |
| 276 | 277 |
| 277 @override | 278 @override |
| 278 Resource getResource(String path) { | 279 Resource getResource(String path) { |
| 279 path = posix.normalize(path); | 280 path = posix.normalize(path); |
| 280 Resource resource = _pathToResource[path]; | 281 Resource resource = _pathToResource[path]; |
| 281 if (resource == null) { | 282 if (resource == null) { |
| 282 resource = new _MemoryFile(this, path); | 283 resource = new _MemoryFile(this, path); |
| 283 } | 284 } |
| 284 return resource; | 285 return resource; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 318 newFolder(posix.dirname(path)); | 319 newFolder(posix.dirname(path)); |
| 319 _MemoryFile file = new _MemoryFile(this, path); | 320 _MemoryFile file = new _MemoryFile(this, path); |
| 320 _pathToResource[path] = file; | 321 _pathToResource[path] = file; |
| 321 _pathToContent[path] = content; | 322 _pathToContent[path] = content; |
| 322 _pathToTimestamp[path] = nextStamp++; | 323 _pathToTimestamp[path] = nextStamp++; |
| 323 _notifyWatchers(path, ChangeType.ADD); | 324 _notifyWatchers(path, ChangeType.ADD); |
| 324 return file; | 325 return file; |
| 325 } | 326 } |
| 326 | 327 |
| 327 void _notifyWatchers(String path, ChangeType changeType) { | 328 void _notifyWatchers(String path, ChangeType changeType) { |
| 328 _pathToWatcher.forEach((String watcherPath, StreamController<WatchEvent> str
eamController) { | 329 _pathToWatchers.forEach((String watcherPath, List<StreamController<WatchEven
t>> streamControllers) { |
| 329 if (posix.isWithin(watcherPath, path)) { | 330 if (posix.isWithin(watcherPath, path)) { |
| 330 streamController.add(new WatchEvent(changeType, path)); | 331 for (StreamController<WatchEvent> streamController in streamControllers)
{ |
| 332 streamController.add(new WatchEvent(changeType, path)); |
| 333 } |
| 331 } | 334 } |
| 332 }); | 335 }); |
| 333 } | 336 } |
| 334 | 337 |
| 335 void modifyFile(String path, String content) { | 338 void modifyFile(String path, String content) { |
| 336 _checkFileAtPath(path); | 339 _checkFileAtPath(path); |
| 337 _pathToContent[path] = content; | 340 _pathToContent[path] = content; |
| 338 _pathToTimestamp[path] = nextStamp++; | 341 _pathToTimestamp[path] = nextStamp++; |
| 339 _notifyWatchers(path, ChangeType.MODIFY); | 342 _notifyWatchers(path, ChangeType.MODIFY); |
| 340 } | 343 } |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 449 return new _PhysicalFolder(directory); | 452 return new _PhysicalFolder(directory); |
| 450 } else { | 453 } else { |
| 451 io.File file = new io.File(path); | 454 io.File file = new io.File(path); |
| 452 return new _PhysicalFile(file); | 455 return new _PhysicalFile(file); |
| 453 } | 456 } |
| 454 } | 457 } |
| 455 | 458 |
| 456 @override | 459 @override |
| 457 Context get pathContext => io.Platform.isWindows ? windows : posix; | 460 Context get pathContext => io.Platform.isWindows ? windows : posix; |
| 458 } | 461 } |
| OLD | NEW |