| // Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| import '../watcher.dart'; |
| |
| /// A factory to produce custom watchers for specific file paths. |
| class _CustomWatcherFactory { |
| final String id; |
| final DirectoryWatcher? Function(String path, {Duration? pollingDelay}) |
| createDirectoryWatcher; |
| final FileWatcher? Function(String path, {Duration? pollingDelay}) |
| createFileWatcher; |
| |
| _CustomWatcherFactory( |
| this.id, this.createDirectoryWatcher, this.createFileWatcher); |
| } |
| |
| /// Registers a custom watcher. |
| /// |
| /// Each custom watcher must have a unique [id] and the same watcher may not be |
| /// registered more than once. |
| /// [createDirectoryWatcher] and [createFileWatcher] should return watchers for |
| /// the file paths they are able to handle. If the custom watcher is not able to |
| /// handle the path it should return null. |
| /// The paths handled by each custom watch may not overlap, at most one custom |
| /// matcher may return a non-null watcher for a given path. |
| /// |
| /// When a file or directory watcher is created the path is checked against each |
| /// registered custom watcher, and if exactly one custom watcher is available it |
| /// will be used instead of the default. |
| void registerCustomWatcher( |
| String id, |
| DirectoryWatcher? Function(String path, {Duration? pollingDelay})? |
| createDirectoryWatcher, |
| FileWatcher? Function(String path, {Duration? pollingDelay})? |
| createFileWatcher, |
| ) { |
| if (_customWatcherFactories.containsKey(id)) { |
| throw ArgumentError('A custom watcher with id `$id` ' |
| 'has already been registered'); |
| } |
| _customWatcherFactories[id] = _CustomWatcherFactory( |
| id, |
| createDirectoryWatcher ?? (_, {pollingDelay}) => null, |
| createFileWatcher ?? (_, {pollingDelay}) => null); |
| } |
| |
| /// Tries to create a custom [DirectoryWatcher] and returns it. |
| /// |
| /// Returns `null` if no custom watcher was applicable and throws a [StateError] |
| /// if more than one was. |
| DirectoryWatcher? createCustomDirectoryWatcher(String path, |
| {Duration? pollingDelay}) { |
| DirectoryWatcher? customWatcher; |
| String? customFactoryId; |
| for (var watcherFactory in _customWatcherFactories.values) { |
| if (customWatcher != null) { |
| throw StateError('Two `CustomWatcherFactory`s applicable: ' |
| '`$customFactoryId` and `${watcherFactory.id}` for `$path`'); |
| } |
| customWatcher = |
| watcherFactory.createDirectoryWatcher(path, pollingDelay: pollingDelay); |
| customFactoryId = watcherFactory.id; |
| } |
| return customWatcher; |
| } |
| |
| /// Tries to create a custom [FileWatcher] and returns it. |
| /// |
| /// Returns `null` if no custom watcher was applicable and throws a [StateError] |
| /// if more than one was. |
| FileWatcher? createCustomFileWatcher(String path, {Duration? pollingDelay}) { |
| FileWatcher? customWatcher; |
| String? customFactoryId; |
| for (var watcherFactory in _customWatcherFactories.values) { |
| if (customWatcher != null) { |
| throw StateError('Two `CustomWatcherFactory`s applicable: ' |
| '`$customFactoryId` and `${watcherFactory.id}` for `$path`'); |
| } |
| customWatcher = |
| watcherFactory.createFileWatcher(path, pollingDelay: pollingDelay); |
| customFactoryId = watcherFactory.id; |
| } |
| return customWatcher; |
| } |
| |
| final _customWatcherFactories = <String, _CustomWatcherFactory>{}; |