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 |