| 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 barback.asset_cascade; | 5 library barback.asset_cascade; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'dart:collection'; | 8 import 'dart:collection'; |
| 9 | 9 |
| 10 import 'asset.dart'; | 10 import 'asset.dart'; |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 77 /// | 77 /// |
| 78 /// If no build it in progress, is `null`. | 78 /// If no build it in progress, is `null`. |
| 79 Future _processDone; | 79 Future _processDone; |
| 80 | 80 |
| 81 /// Whether any source assets have been updated or removed since processing | 81 /// Whether any source assets have been updated or removed since processing |
| 82 /// last began. | 82 /// last began. |
| 83 var _newChanges = false; | 83 var _newChanges = false; |
| 84 | 84 |
| 85 /// Creates a new [AssetCascade]. | 85 /// Creates a new [AssetCascade]. |
| 86 /// | 86 /// |
| 87 /// It loads source assets within [package] using [provider] and then uses | 87 /// It loads source assets within [package] using [provider]. |
| 88 /// [transformerPhases] to generate output files from them. | 88 AssetCascade(this.graph, this.package) { |
| 89 //TODO(rnystrom): Better way of specifying transformers and their ordering. | 89 _addPhase(new Phase(this, [])); |
| 90 AssetCascade(this.graph, this.package, | |
| 91 Iterable<Iterable<Transformer>> transformerPhases) { | |
| 92 // Flatten the phases to a list so we can traverse backwards to wire up | |
| 93 // each phase to its next. | |
| 94 var phases = transformerPhases.toList(); | |
| 95 if (phases.isEmpty) phases = [[]]; | |
| 96 | |
| 97 Phase nextPhase = null; | |
| 98 for (var transformers in phases.reversed) { | |
| 99 nextPhase = new Phase(this, transformers.toList(), nextPhase); | |
| 100 nextPhase.onDirty.listen((_) { | |
| 101 _newChanges = true; | |
| 102 _waitForProcess(); | |
| 103 }); | |
| 104 _phases.insert(0, nextPhase); | |
| 105 } | |
| 106 } | 90 } |
| 107 | 91 |
| 108 /// Gets the asset identified by [id]. | 92 /// Gets the asset identified by [id]. |
| 109 /// | 93 /// |
| 110 /// If [id] is for a generated or transformed asset, this will wait until it | 94 /// If [id] is for a generated or transformed asset, this will wait until it |
| 111 /// has been created and return it. This means that the returned asset will | 95 /// has been created and return it. This means that the returned asset will |
| 112 /// always be [AssetState.AVAILABLE]. | 96 /// always be [AssetState.AVAILABLE]. |
| 113 /// | 97 /// |
| 114 /// If the asset cannot be found, returns null. | 98 /// If the asset cannot be found, returns null. |
| 115 Future<AssetNode> getAssetNode(AssetId id) { | 99 Future<AssetNode> getAssetNode(AssetId id) { |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 178 removed.forEach((id) { | 162 removed.forEach((id) { |
| 179 // If the source was being loaded, cancel that load. | 163 // If the source was being loaded, cancel that load. |
| 180 if (_loadingSources.containsKey(id)) _loadingSources.remove(id).cancel(); | 164 if (_loadingSources.containsKey(id)) _loadingSources.remove(id).cancel(); |
| 181 | 165 |
| 182 var controller = _sourceControllerMap.remove(id); | 166 var controller = _sourceControllerMap.remove(id); |
| 183 // Don't choke if an id is double-removed for some reason. | 167 // Don't choke if an id is double-removed for some reason. |
| 184 if (controller != null) controller.setRemoved(); | 168 if (controller != null) controller.setRemoved(); |
| 185 }); | 169 }); |
| 186 } | 170 } |
| 187 | 171 |
| 172 /// Sets this cascade's transformer phases to [transformers]. |
| 173 void updateTransformers(Iterable<Iterable<Transformer>> transformers) { |
| 174 transformers = transformers.toList(); |
| 175 |
| 176 for (var i = 0; i < transformers.length; i++) { |
| 177 if (_phases.length > i) { |
| 178 _phases[i].updateTransformers(transformers[i]); |
| 179 continue; |
| 180 } |
| 181 |
| 182 _addPhase(_phases.last.addPhase(transformers[i])); |
| 183 } |
| 184 |
| 185 if (transformers.length < _phases.length) { |
| 186 for (var i = transformers.length; i < _phases.length; i++) { |
| 187 // TODO(nweiz): actually remove phases rather than emptying them of |
| 188 // transformers. |
| 189 _phases[i].updateTransformers([]); |
| 190 } |
| 191 } |
| 192 } |
| 193 |
| 188 void reportError(BarbackException error) { | 194 void reportError(BarbackException error) { |
| 189 _accumulatedErrors.add(error); | 195 _accumulatedErrors.add(error); |
| 190 _errorsController.add(error); | 196 _errorsController.add(error); |
| 191 } | 197 } |
| 192 | 198 |
| 199 /// Add [phase] to the end of [_phases] and watch its [onDirty] stream. |
| 200 void _addPhase(Phase phase) { |
| 201 phase.onDirty.listen((_) { |
| 202 _newChanges = true; |
| 203 _waitForProcess(); |
| 204 }); |
| 205 _phases.add(phase); |
| 206 } |
| 207 |
| 193 /// Starts the build process asynchronously if there is work to be done. | 208 /// Starts the build process asynchronously if there is work to be done. |
| 194 /// | 209 /// |
| 195 /// Returns a future that completes with the background processing is done. | 210 /// Returns a future that completes with the background processing is done. |
| 196 /// If there is no work to do, returns a future that completes immediately. | 211 /// If there is no work to do, returns a future that completes immediately. |
| 197 /// All errors that occur during processing will be caught (and routed to the | 212 /// All errors that occur during processing will be caught (and routed to the |
| 198 /// [results] stream) before they get to the returned future, so it is safe | 213 /// [results] stream) before they get to the returned future, so it is safe |
| 199 /// to discard it. | 214 /// to discard it. |
| 200 Future _waitForProcess() { | 215 Future _waitForProcess() { |
| 201 if (_processDone != null) return _processDone; | 216 if (_processDone != null) return _processDone; |
| 202 | 217 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 241 | 256 |
| 242 // Otherwise, everything is done. | 257 // Otherwise, everything is done. |
| 243 return; | 258 return; |
| 244 } | 259 } |
| 245 | 260 |
| 246 // Process that phase and then loop onto the next. | 261 // Process that phase and then loop onto the next. |
| 247 return future.then((_) => _process()); | 262 return future.then((_) => _process()); |
| 248 }); | 263 }); |
| 249 } | 264 } |
| 250 } | 265 } |
| OLD | NEW |