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.graph.asset_cascade; | 5 library barback.asset_cascade; |
6 | 6 |
7 import 'dart:async'; | 7 import 'dart:async'; |
8 | 8 |
9 import '../asset/asset.dart'; | 9 import 'asset.dart'; |
10 import '../asset/asset_id.dart'; | 10 import 'asset_id.dart'; |
11 import '../asset/asset_node.dart'; | 11 import 'asset_node.dart'; |
12 import '../asset/asset_set.dart'; | 12 import 'asset_set.dart'; |
13 import '../errors.dart'; | 13 import 'log.dart'; |
14 import '../log.dart'; | 14 import 'cancelable_future.dart'; |
15 import '../transformer/transformer.dart'; | 15 import 'errors.dart'; |
16 import '../utils/cancelable_future.dart'; | |
17 import 'node_status.dart'; | |
18 import 'node_streams.dart'; | |
19 import 'package_graph.dart'; | 16 import 'package_graph.dart'; |
20 import 'phase.dart'; | 17 import 'phase.dart'; |
| 18 import 'stream_pool.dart'; |
| 19 import 'transformer.dart'; |
21 | 20 |
22 /// The asset cascade for an individual package. | 21 /// The asset cascade for an individual package. |
23 /// | 22 /// |
24 /// This keeps track of which [Transformer]s are applied to which assets, and | 23 /// This keeps track of which [Transformer]s are applied to which assets, and |
25 /// re-runs those transformers when their dependencies change. The transformed | 24 /// re-runs those transformers when their dependencies change. The transformed |
26 /// asset nodes are accessible via [getAssetNode]. | 25 /// asset nodes are accessible via [getAssetNode]. |
27 /// | 26 /// |
28 /// A cascade consists of one or more [Phases], each of which has one or more | 27 /// A cascade consists of one or more [Phases], each of which has one or more |
29 /// [Transformer]s that run in parallel, potentially on the same inputs. The | 28 /// [Transformer]s that run in parallel, potentially on the same inputs. The |
30 /// inputs of the first phase are the source assets for this cascade's package. | 29 /// inputs of the first phase are the source assets for this cascade's package. |
(...skipping 18 matching lines...) Expand all Loading... |
49 /// one. | 48 /// one. |
50 final _loadingSources = new Map<AssetId, CancelableFuture<Asset>>(); | 49 final _loadingSources = new Map<AssetId, CancelableFuture<Asset>>(); |
51 | 50 |
52 /// The list of phases in this cascade. | 51 /// The list of phases in this cascade. |
53 /// | 52 /// |
54 /// This will always contain at least one phase, and the first phase will | 53 /// This will always contain at least one phase, and the first phase will |
55 /// never have any transformers. This ensures that every transformer can | 54 /// never have any transformers. This ensures that every transformer can |
56 /// request inputs from a previous phase. | 55 /// request inputs from a previous phase. |
57 final _phases = <Phase>[]; | 56 final _phases = <Phase>[]; |
58 | 57 |
59 /// The subscription to the [Phase.onStatusChange] stream of the last [Phase] | 58 /// The subscription to the [Phase.onDone] stream of the last [Phase] in |
60 /// in [_phases]. | 59 /// [_phases]. |
61 StreamSubscription _phaseStatusSubscription; | 60 StreamSubscription _phaseOnDoneSubscription; |
62 | 61 |
63 /// A stream that emits any errors from the cascade or the transformers. | 62 /// A stream that emits any errors from the cascade or the transformers. |
64 /// | 63 /// |
65 /// This emits errors as they're detected. If an error occurs in one part of | 64 /// This emits errors as they're detected. If an error occurs in one part of |
66 /// the cascade, unrelated parts will continue building. | 65 /// the cascade, unrelated parts will continue building. |
67 Stream<BarbackException> get errors => _errorsController.stream; | 66 Stream<BarbackException> get errors => _errorsController.stream; |
68 final _errorsController = | 67 final _errorsController = |
69 new StreamController<BarbackException>.broadcast(sync: true); | 68 new StreamController<BarbackException>.broadcast(sync: true); |
70 | 69 |
71 /// How far along [this] is in processing its assets. | 70 /// A stream that emits an event whenever any transforms in this cascade logs |
72 NodeStatus get status { | 71 /// an entry. |
| 72 Stream<LogEntry> get onLog => _onLogPool.stream; |
| 73 final _onLogPool = new StreamPool<LogEntry>.broadcast(); |
| 74 |
| 75 /// Whether [this] is dirty and still has more processing to do. |
| 76 bool get isDirty { |
73 // Just check the last phase, since it will check all the previous phases | 77 // Just check the last phase, since it will check all the previous phases |
74 // itself. | 78 // itself. |
75 return _phases.last.status; | 79 return _phases.last.isDirty; |
76 } | 80 } |
77 | 81 |
78 /// The streams exposed by this cascade. | 82 /// A stream that emits an event whenever [this] is no longer dirty. |
79 final _streams = new NodeStreams(); | 83 /// |
80 Stream<LogEntry> get onLog => _streams.onLog; | 84 /// This is synchronous in order to guarantee that it will emit an event as |
81 Stream<NodeStatus> get onStatusChange => _streams.onStatusChange; | 85 /// soon as [isDirty] flips from `true` to `false`. |
| 86 Stream get onDone => _onDoneController.stream; |
| 87 final _onDoneController = new StreamController.broadcast(sync: true); |
82 | 88 |
83 /// Returns all currently-available output assets from this cascade. | 89 /// Returns all currently-available output assets from this cascade. |
84 AssetSet get availableOutputs => | 90 AssetSet get availableOutputs => |
85 new AssetSet.from(_phases.last.availableOutputs.map((node) => node.asset)); | 91 new AssetSet.from(_phases.last.availableOutputs.map((node) => node.asset)); |
86 | 92 |
87 /// Creates a new [AssetCascade]. | 93 /// Creates a new [AssetCascade]. |
88 /// | 94 /// |
89 /// It loads source assets within [package] using [provider]. | 95 /// It loads source assets within [package] using [provider]. |
90 AssetCascade(this.graph, this.package) { | 96 AssetCascade(this.graph, this.package) { |
91 _addPhase(new Phase(this, package)); | 97 _addPhase(new Phase(this, package)); |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
184 var phase = _phases.last.addPhase(); | 190 var phase = _phases.last.addPhase(); |
185 _addPhase(phase); | 191 _addPhase(phase); |
186 phase.updateTransformers(transformers[i]); | 192 phase.updateTransformers(transformers[i]); |
187 } | 193 } |
188 | 194 |
189 for (var i = transformers.length + 1; i < _phases.length; i++) { | 195 for (var i = transformers.length + 1; i < _phases.length; i++) { |
190 _phases[i].remove(); | 196 _phases[i].remove(); |
191 } | 197 } |
192 _phases.removeRange(transformers.length + 1, _phases.length); | 198 _phases.removeRange(transformers.length + 1, _phases.length); |
193 | 199 |
194 _phaseStatusSubscription.cancel(); | 200 _phaseOnDoneSubscription.cancel(); |
195 _phaseStatusSubscription = _phases.last.onStatusChange | 201 _phaseOnDoneSubscription = _phases.last.onDone |
196 .listen(_streams.changeStatus); | 202 .listen(_onDoneController.add); |
197 } | 203 } |
198 | 204 |
199 /// Force all [LazyTransformer]s' transforms in this cascade to begin | 205 /// Force all [LazyTransformer]s' transforms in this cascade to begin |
200 /// producing concrete assets. | 206 /// producing concrete assets. |
201 void forceAllTransforms() { | 207 void forceAllTransforms() { |
202 for (var phase in _phases) { | 208 for (var phase in _phases) { |
203 phase.forceAllTransforms(); | 209 phase.forceAllTransforms(); |
204 } | 210 } |
205 } | 211 } |
206 | 212 |
207 void reportError(BarbackException error) { | 213 void reportError(BarbackException error) { |
208 _errorsController.add(error); | 214 _errorsController.add(error); |
209 } | 215 } |
210 | 216 |
211 /// Add [phase] to the end of [_phases] and watch its streams. | 217 /// Add [phase] to the end of [_phases] and watch its streams. |
212 void _addPhase(Phase phase) { | 218 void _addPhase(Phase phase) { |
213 _streams.onLogPool.add(phase.onLog); | 219 _onLogPool.add(phase.onLog); |
214 if (_phaseStatusSubscription != null) _phaseStatusSubscription.cancel(); | 220 if (_phaseOnDoneSubscription != null) _phaseOnDoneSubscription.cancel(); |
215 _phaseStatusSubscription = | 221 _phaseOnDoneSubscription = phase.onDone.listen(_onDoneController.add); |
216 phase.onStatusChange.listen(_streams.changeStatus); | |
217 | 222 |
218 _phases.add(phase); | 223 _phases.add(phase); |
219 } | 224 } |
220 | 225 |
221 String toString() => "cascade for $package"; | 226 String toString() => "cascade for $package"; |
222 } | 227 } |
OLD | NEW |