Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(559)

Side by Side Diff: pkg/barback/lib/src/phase.dart

Issue 200983002: Re-run a transform when a secondary input starts existing. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: code review Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « pkg/barback/lib/src/group_runner.dart ('k') | pkg/barback/lib/src/transform_node.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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.phase; 5 library barback.phase;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 8
9 import 'asset_cascade.dart'; 9 import 'asset_cascade.dart';
10 import 'asset_id.dart'; 10 import 'asset_id.dart';
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
92 /// emit assets. 92 /// emit assets.
93 Stream<AssetNode> get onAsset => _onAssetController.stream; 93 Stream<AssetNode> get onAsset => _onAssetController.stream;
94 final _onAssetController = 94 final _onAssetController =
95 new StreamController<AssetNode>.broadcast(sync: true); 95 new StreamController<AssetNode>.broadcast(sync: true);
96 96
97 /// Whether [this] is dirty and still has more processing to do. 97 /// Whether [this] is dirty and still has more processing to do.
98 /// 98 ///
99 /// A phase is considered dirty if any of the previous phases in the same 99 /// A phase is considered dirty if any of the previous phases in the same
100 /// cascade are dirty, since those phases could emit an asset that this phase 100 /// cascade are dirty, since those phases could emit an asset that this phase
101 /// will then need to process. 101 /// will then need to process.
102 bool get isDirty => (_previous != null && _previous.isDirty) || 102 bool get isDirty => (previous != null && previous.isDirty) ||
103 _inputs.values.any((input) => input.isDirty) || 103 _inputs.values.any((input) => input.isDirty) ||
104 _groups.values.any((group) => group.isDirty); 104 _groups.values.any((group) => group.isDirty);
105 105
106 /// A stream that emits an event whenever any transforms in this phase logs 106 /// A stream that emits an event whenever any transforms in this phase logs
107 /// an entry. 107 /// an entry.
108 Stream<LogEntry> get onLog => _onLogPool.stream; 108 Stream<LogEntry> get onLog => _onLogPool.stream;
109 final _onLogPool = new StreamPool<LogEntry>.broadcast(); 109 final _onLogPool = new StreamPool<LogEntry>.broadcast();
110 110
111 /// The previous phase in the cascade, or null if this is the first phase. 111 /// The previous phase in the cascade, or null if this is the first phase.
112 final Phase _previous; 112 final Phase previous;
113 113
114 /// The subscription to [_previous]'s [onDone] stream. 114 /// The subscription to [previous]'s [onDone] stream.
115 StreamSubscription _previousOnDoneSubscription; 115 StreamSubscription _previousOnDoneSubscription;
116 116
117 /// The subscription to [_previous]'s [onAsset] stream. 117 /// The subscription to [previous]'s [onAsset] stream.
118 StreamSubscription<AssetNode> _previousOnAssetSubscription; 118 StreamSubscription<AssetNode> _previousOnAssetSubscription;
119 119
120 /// A map of asset ids to completers for [getInput] requests. 120 /// A map of asset ids to completers for [getInput] requests.
121 /// 121 ///
122 /// If an asset node is requested before it's available, we put a completer in 122 /// If an asset node is requested before it's available, we put a completer in
123 /// this map to wait for the asset to be generated. If it's not generated, the 123 /// this map to wait for the asset to be generated. If it's not generated, the
124 /// completer should complete to `null`. 124 /// completer should complete to `null`.
125 final _pendingOutputRequests = new Map<AssetId, Completer<AssetNode>>(); 125 final _pendingOutputRequests = new Map<AssetId, Completer<AssetNode>>();
126 126
127 /// Returns all currently-available output assets for this phase. 127 /// Returns all currently-available output assets for this phase.
128 Set<AssetNode> get availableOutputs { 128 Set<AssetNode> get availableOutputs {
129 return _outputs.values 129 return _outputs.values
130 .map((output) => output.output) 130 .map((output) => output.output)
131 .where((node) => node.state.isAvailable) 131 .where((node) => node.state.isAvailable)
132 .toSet(); 132 .toSet();
133 } 133 }
134 134
135 // TODO(nweiz): Rather than passing the cascade and the phase everywhere, 135 // TODO(nweiz): Rather than passing the cascade and the phase everywhere,
136 // create an interface that just exposes [getInput]. Emit errors via 136 // create an interface that just exposes [getInput]. Emit errors via
137 // [AssetNode]s. 137 // [AssetNode]s.
138 Phase(AssetCascade cascade, String location) 138 Phase(AssetCascade cascade, String location)
139 : this._(cascade, location, 0); 139 : this._(cascade, location, 0);
140 140
141 Phase._(this.cascade, this._location, this._index, [this._previous]) { 141 Phase._(this.cascade, this._location, this._index, [this.previous]) {
142 if (_previous != null) { 142 if (previous != null) {
143 _previousOnAssetSubscription = _previous.onAsset.listen(addInput); 143 _previousOnAssetSubscription = previous.onAsset.listen(addInput);
144 _previousOnDoneSubscription = _previous.onDone.listen((_) { 144 _previousOnDoneSubscription = previous.onDone.listen((_) {
145 if (!isDirty) _onDoneController.add(null); 145 if (!isDirty) _onDoneController.add(null);
146 }); 146 });
147 } 147 }
148 148
149 onDone.listen((_) { 149 onDone.listen((_) {
150 // All the previous phases have finished building. If anyone's still 150 // All the previous phases have finished building. If anyone's still
151 // waiting for outputs, cut off the wait; we won't be generating them, 151 // waiting for outputs, cut off the wait; we won't be generating them,
152 // at least until a source asset changes. 152 // at least until a source asset changes.
153 for (var completer in _pendingOutputRequests.values) { 153 for (var completer in _pendingOutputRequests.values) {
154 completer.complete(null); 154 completer.complete(null);
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
197 if (!isDirty) _onDoneController.add(null); 197 if (!isDirty) _onDoneController.add(null);
198 }); 198 });
199 199
200 input.updateTransformers(_transformers); 200 input.updateTransformers(_transformers);
201 201
202 for (var group in _groups.values) { 202 for (var group in _groups.values) {
203 group.addInput(node); 203 group.addInput(node);
204 } 204 }
205 } 205 }
206 206
207 // TODO(nweiz): If the input is available when this is called, it's 207 // TODO(nweiz): If the output is available when this is called, it's
208 // theoretically possible for it to become unavailable between the call and 208 // theoretically possible for it to become unavailable between the call and
209 // the return. If it does so, it won't trigger the rebuilding process. To 209 // the return. If it does so, it won't trigger the rebuilding process. To
210 // avoid this, we should have this and the methods it calls take explicit 210 // avoid this, we should have this and the methods it calls take explicit
211 // callbacks, as in [AssetNode.whenAvailable]. 211 // callbacks, as in [AssetNode.whenAvailable].
212 /// Gets the asset node for an input [id].
213 ///
214 /// If [id] is for a generated or transformed asset, this will wait until it
215 /// has been created and return it. This means that the returned asset will
216 /// always be [AssetState.AVAILABLE].
217 ///
218 /// If the input cannot be found, returns null.
219 Future<AssetNode> getInput(AssetId id) {
220 return syncFuture(() {
221 if (id.package != cascade.package) return cascade.graph.getAssetNode(id);
222 if (_previous != null) return _previous.getOutput(id);
223 if (!_inputs.containsKey(id)) return null;
224
225 var input = _inputs[id].input;
226 return input.whenAvailable((_) => input).catchError((error) {
227 if (error is! AssetNotFoundException || error.id != id) throw error;
228 // Retry in case the input was replaced.
229 return getInput(id);
230 });
231 });
232 }
233
234 /// Gets the asset node for an output [id]. 212 /// Gets the asset node for an output [id].
235 /// 213 ///
236 /// If [id] is for a generated or transformed asset, this will wait until it 214 /// If [id] is for a generated or transformed asset, this will wait until it
237 /// has been created and return it. This means that the returned asset will 215 /// has been created and return it. This means that the returned asset will
238 /// always be [AssetState.AVAILABLE]. 216 /// always be [AssetState.AVAILABLE].
239 /// 217 ///
240 /// If the output cannot be found, returns null. 218 /// If the output cannot be found, returns null.
241 Future<AssetNode> getOutput(AssetId id) { 219 Future<AssetNode> getOutput(AssetId id) {
242 return syncFuture(() { 220 return syncFuture(() {
243 if (id.package != cascade.package) return cascade.graph.getAssetNode(id); 221 if (id.package != cascade.package) return cascade.graph.getAssetNode(id);
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
400 assert(asset.state.isDirty); 378 assert(asset.state.isDirty);
401 asset.force(); 379 asset.force();
402 asset.whenStateChanges().then((state) { 380 asset.whenStateChanges().then((state) {
403 if (state.isRemoved) return getOutput(asset.id); 381 if (state.isRemoved) return getOutput(asset.id);
404 return asset; 382 return asset;
405 }).then(request.complete).catchError(request.completeError); 383 }).then(request.complete).catchError(request.completeError);
406 } 384 }
407 385
408 String toString() => "phase $_location.$_index"; 386 String toString() => "phase $_location.$_index";
409 } 387 }
OLDNEW
« no previous file with comments | « pkg/barback/lib/src/group_runner.dart ('k') | pkg/barback/lib/src/transform_node.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698