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

Side by Side Diff: pkg/barback/lib/src/graph/transform_node.dart

Issue 299833003: Expose aggregate transformers in barback. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: code review Created 6 years, 6 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
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.graph.transform_node; 5 library barback.graph.transform_node;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 8
9 import '../asset/asset.dart'; 9 import '../asset/asset.dart';
10 import '../asset/asset_id.dart'; 10 import '../asset/asset_id.dart';
11 import '../asset/asset_node.dart'; 11 import '../asset/asset_node.dart';
12 import '../asset/asset_node_set.dart'; 12 import '../asset/asset_node_set.dart';
13 import '../errors.dart'; 13 import '../errors.dart';
14 import '../log.dart'; 14 import '../log.dart';
15 import '../transformer/aggregate_transform.dart'; 15 import '../transformer/aggregate_transform.dart';
16 import '../transformer/aggregate_transformer.dart'; 16 import '../transformer/aggregate_transformer.dart';
17 import '../transformer/declaring_aggregate_transform.dart'; 17 import '../transformer/declaring_aggregate_transform.dart';
18 import '../transformer/declaring_aggregate_transformer.dart'; 18 import '../transformer/declaring_aggregate_transformer.dart';
19 import '../transformer/lazy_aggregate_transformer.dart'; 19 import '../transformer/lazy_aggregate_transformer.dart';
20 import '../utils.dart'; 20 import '../utils.dart';
21 import 'node_status.dart'; 21 import 'node_status.dart';
22 import 'node_streams.dart'; 22 import 'node_streams.dart';
23 import 'phase.dart'; 23 import 'phase.dart';
24 import 'transformer_classifier.dart';
24 25
25 /// Describes a transform on a set of assets and its relationship to the build 26 /// Describes a transform on a set of assets and its relationship to the build
26 /// dependency graph. 27 /// dependency graph.
27 /// 28 ///
28 /// Keeps track of whether it's dirty and needs to be run and which assets it 29 /// Keeps track of whether it's dirty and needs to be run and which assets it
29 /// depends on. 30 /// depends on.
30 class TransformNode { 31 class TransformNode {
31 /// The aggregate key for this node. 32 /// The aggregate key for this node.
32 final String key; 33 final String key;
33 34
35 /// The [TransformerClassifier] that [this] belongs to.
36 final TransformerClassifier classifier;
37
34 /// The [Phase] that this transform runs in. 38 /// The [Phase] that this transform runs in.
35 final Phase phase; 39 Phase get phase => classifier.phase;
36 40
37 /// The [AggregateTransformer] to apply to this node's inputs. 41 /// The [AggregateTransformer] to apply to this node's inputs.
38 final AggregateTransformer transformer; 42 final AggregateTransformer transformer;
39 43
40 /// The primary asset nodes this transform runs on. 44 /// The primary asset nodes this transform runs on.
41 final _primaries = new AssetNodeSet(); 45 final _primaries = new AssetNodeSet();
42 46
43 /// A string describing the location of [this] in the transformer graph. 47 /// A string describing the location of [this] in the transformer graph.
44 final String _location; 48 final String _location;
45 49
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 159
156 /// The controller for the currently-running [AggregateTransformer.apply] 160 /// The controller for the currently-running [AggregateTransformer.apply]
157 /// call's [AggregateTransform]. 161 /// call's [AggregateTransform].
158 /// 162 ///
159 /// This will be non-`null` when [AggregateTransform.apply] is running, which 163 /// This will be non-`null` when [AggregateTransform.apply] is running, which
160 /// means that it's always non-`null` when [_state] is [_State.APPLYING] or 164 /// means that it's always non-`null` when [_state] is [_State.APPLYING] or
161 /// [_State.NEEDS_APPLY], sometimes non-`null` when it's 165 /// [_State.NEEDS_APPLY], sometimes non-`null` when it's
162 /// [_State.NEEDS_DECLARE], and always `null` otherwise. 166 /// [_State.NEEDS_DECLARE], and always `null` otherwise.
163 AggregateTransformController _applyController; 167 AggregateTransformController _applyController;
164 168
165 TransformNode(this.phase, this.transformer, this.key, this._location) { 169 TransformNode(this.classifier, this.transformer, this.key, this._location) {
166 _forced = transformer is! DeclaringAggregateTransformer; 170 _forced = transformer is! DeclaringAggregateTransformer;
167 171
168 _phaseAssetSubscription = phase.previous.onAsset.listen((node) { 172 _phaseAssetSubscription = phase.previous.onAsset.listen((node) {
169 if (!_missingInputs.contains(node.id)) return; 173 if (!_missingInputs.contains(node.id)) return;
170 if (_forced) node.force(); 174 if (_forced) node.force();
171 _dirty(); 175 _dirty();
172 }); 176 });
173 177
174 _phaseStatusSubscription = phase.previous.onStatusChange.listen((status) { 178 _phaseStatusSubscription = phase.previous.onStatusChange.listen((status) {
175 if (status == NodeStatus.RUNNING) return; 179 if (status == NodeStatus.RUNNING) return;
176 180
177 _maybeFinishDeclareController(); 181 _maybeFinishDeclareController();
178 _maybeFinishApplyController(); 182 _maybeFinishApplyController();
179 }); 183 });
180 184
185 classifier.onDoneClassifying.listen((_) {
186 _maybeFinishDeclareController();
187 _maybeFinishApplyController();
188 });
189
181 _run(); 190 _run();
182 } 191 }
183 192
184 /// Adds [input] as a primary input for this node. 193 /// Adds [input] as a primary input for this node.
185 void addPrimary(AssetNode input) { 194 void addPrimary(AssetNode input) {
186 _primaries.add(input); 195 _primaries.add(input);
187 if (_forced) input.force(); 196 if (_forced) input.force();
188 197
189 _primarySubscriptions[input.id] = input.onStateChange 198 _primarySubscriptions[input.id] = input.onStateChange
190 .listen((_) => _onPrimaryStateChange(input)); 199 .listen((_) => _onPrimaryStateChange(input));
191 200
192 if (_state == _State.DECLARING && !_declareController.isDone) { 201 if (_state == _State.DECLARING && !_declareController.isDone) {
193 // If we're running `declareOutputs` and its id stream isn't closed yet, 202 // If we're running `declareOutputs` and its id stream isn't closed yet,
194 // pass this in as another id. 203 // pass this in as another id.
195 _declareController.addId(input.id); 204 _declareController.addId(input.id);
196 _maybeFinishDeclareController(); 205 _maybeFinishDeclareController();
197 } else if (_state == _State.APPLYING) { 206 } else if (_state == _State.APPLYING) {
198 // If we're running `apply`, we need to wait until [input] is available 207 // If we're running `apply`, we need to wait until [input] is available
199 // before we pass it into the stream. If it's available now, great; if 208 // before we pass it into the stream. If it's available now, great; if
200 // not, [_onPrimaryStateChange] will handle it. 209 // not, [_onPrimaryStateChange] will handle it.
201 if (!input.state.isAvailable) return; 210 if (!input.state.isAvailable) {
211 // If we started running eagerly without being forced, abort that run if
212 // a new unavailable asset comes in.
213 if (input.isLazy && !_forced) _restartRun();
214 return;
215 }
216
202 _onPrimaryStateChange(input); 217 _onPrimaryStateChange(input);
203 _maybeFinishApplyController(); 218 _maybeFinishApplyController();
204 } else { 219 } else {
205 // Otherwise, a new input means we'll need to re-run `declareOutputs`. 220 // Otherwise, a new input means we'll need to re-run `declareOutputs`.
206 _restartRun(); 221 _restartRun();
207 } 222 }
208 } 223 }
209 224
210 /// Marks this transform as removed. 225 /// Marks this transform as removed.
211 /// 226 ///
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
319 // re-run declare and then apply. 334 // re-run declare and then apply.
320 _restartRun(); 335 _restartRun();
321 } else { 336 } else {
322 // If the new asset comes before the asset stream is done, we can just 337 // If the new asset comes before the asset stream is done, we can just
323 // pass it to the stream. 338 // pass it to the stream.
324 _applyController.addInput(input.asset); 339 _applyController.addInput(input.asset);
325 _maybeFinishApplyController(); 340 _maybeFinishApplyController();
326 } 341 }
327 } else { 342 } else {
328 if (_forced) input.force(); 343 if (_forced) input.force();
329 if (_state == _State.APPLYING && !_applyController.addedId(input.id)) { 344 if (_state == _State.APPLYING && !_applyController.addedId(input.id) &&
345 (_forced || !input.isLazy)) {
330 // If the input hasn't yet been added to the transform's input stream, 346 // If the input hasn't yet been added to the transform's input stream,
331 // there's no need to consider the transformation dirty. 347 // there's no need to consider the transformation dirty. However, if the
348 // input is lazy and we're running eagerly, we need to restart the
349 // transformation.
332 return; 350 return;
333 } 351 }
334 _dirty(); 352 _dirty();
335 } 353 }
336 } 354 }
337 355
338 /// Run the entire transformation, including both `declareOutputs` (if 356 /// Run the entire transformation, including both `declareOutputs` (if
339 /// applicable) and `apply`. 357 /// applicable) and `apply`.
340 void _run() { 358 void _run() {
341 assert(_state != _State.DECLARING); 359 assert(_state != _State.DECLARING);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
382 return; 400 return;
383 } 401 }
384 402
385 _state = _State.DECLARING; 403 _state = _State.DECLARING;
386 var controller = new DeclaringAggregateTransformController(this); 404 var controller = new DeclaringAggregateTransformController(this);
387 _declareController = controller; 405 _declareController = controller;
388 _streams.onLogPool.add(controller.onLog); 406 _streams.onLogPool.add(controller.onLog);
389 for (var primary in _primaries) { 407 for (var primary in _primaries) {
390 controller.addId(primary.id); 408 controller.addId(primary.id);
391 } 409 }
410 _maybeFinishDeclareController();
392 411
393 syncFuture(() { 412 syncFuture(() {
394 return (transformer as DeclaringAggregateTransformer) 413 return (transformer as DeclaringAggregateTransformer)
395 .declareOutputs(controller.transform); 414 .declareOutputs(controller.transform);
396 }).whenComplete(() { 415 }).whenComplete(() {
397 // Cancel the controller here even if `declareOutputs` wasn't interrupted. 416 // Cancel the controller here even if `declareOutputs` wasn't interrupted.
398 // Since the declaration is finished, we want to close out the 417 // Since the declaration is finished, we want to close out the
399 // controller's streams. 418 // controller's streams.
400 controller.cancel(); 419 controller.cancel();
401 _declareController = null; 420 _declareController = null;
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
550 /// 569 ///
551 /// Returns whether or not an error occurred while running the transformer. 570 /// Returns whether or not an error occurred while running the transformer.
552 Future<bool> _runApply() { 571 Future<bool> _runApply() {
553 var controller = new AggregateTransformController(this); 572 var controller = new AggregateTransformController(this);
554 _applyController = controller; 573 _applyController = controller;
555 _streams.onLogPool.add(controller.onLog); 574 _streams.onLogPool.add(controller.onLog);
556 for (var primary in _primaries) { 575 for (var primary in _primaries) {
557 if (!primary.state.isAvailable) continue; 576 if (!primary.state.isAvailable) continue;
558 controller.addInput(primary.asset); 577 controller.addInput(primary.asset);
559 } 578 }
579 _maybeFinishApplyController();
560 580
561 return syncFuture(() { 581 return syncFuture(() {
562 return transformer.apply(controller.transform); 582 return transformer.apply(controller.transform);
563 }).whenComplete(() { 583 }).whenComplete(() {
564 // Cancel the controller here even if `apply` wasn't interrupted. Since 584 // Cancel the controller here even if `apply` wasn't interrupted. Since
565 // the apply is finished, we want to close out the controller's streams. 585 // the apply is finished, we want to close out the controller's streams.
566 controller.cancel(); 586 controller.cancel();
567 _applyController = null; 587 _applyController = null;
568 }).then((_) { 588 }).then((_) {
569 assert(_state != _State.DECLARED); 589 assert(_state != _State.DECLARED);
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
684 void _consumePrimary(AssetId id) { 704 void _consumePrimary(AssetId id) {
685 var controller = _passThroughControllers.remove(id); 705 var controller = _passThroughControllers.remove(id);
686 if (controller == null) return; 706 if (controller == null) return;
687 controller.setRemoved(); 707 controller.setRemoved();
688 } 708 }
689 709
690 /// If `declareOutputs` is running and all previous phases have declared their 710 /// If `declareOutputs` is running and all previous phases have declared their
691 /// outputs, mark [_declareController] as done. 711 /// outputs, mark [_declareController] as done.
692 void _maybeFinishDeclareController() { 712 void _maybeFinishDeclareController() {
693 if (_declareController == null) return; 713 if (_declareController == null) return;
714 if (classifier.isClassifying) return;
694 if (phase.previous.status == NodeStatus.RUNNING) return; 715 if (phase.previous.status == NodeStatus.RUNNING) return;
695 _declareController.done(); 716 _declareController.done();
696 } 717 }
697 718
698 /// If `apply` is running, all previous phases have declared their outputs, 719 /// If `apply` is running, all previous phases have declared their outputs,
699 /// and all primary inputs are available and thus have been passed to the 720 /// and all primary inputs are available and thus have been passed to the
700 /// transformer, mark [_applyController] as done. 721 /// transformer, mark [_applyController] as done.
701 void _maybeFinishApplyController() { 722 void _maybeFinishApplyController() {
702 if (_applyController == null) return; 723 if (_applyController == null) return;
724 if (classifier.isClassifying) return;
703 if (_primaries.any((input) => !input.state.isAvailable)) return; 725 if (_primaries.any((input) => !input.state.isAvailable)) return;
704 if (phase.previous.status == NodeStatus.RUNNING) return; 726 if (phase.previous.status == NodeStatus.RUNNING) return;
705 _applyController.done(); 727 _applyController.done();
706 } 728 }
707 729
708 BarbackException _wrapException(error, StackTrace stackTrace) { 730 BarbackException _wrapException(error, StackTrace stackTrace) {
709 if (error is! AssetNotFoundException) { 731 if (error is! AssetNotFoundException) {
710 return new TransformerException(info, error, stackTrace); 732 return new TransformerException(info, error, stackTrace);
711 } else { 733 } else {
712 return new MissingInputException(info, error.id); 734 return new MissingInputException(info, error.id);
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
774 /// declaring and [APPLYING] otherwise. If a primary input is added or 796 /// declaring and [APPLYING] otherwise. If a primary input is added or
775 /// removed, this will transition to [DECLARING]. 797 /// removed, this will transition to [DECLARING].
776 static const APPLIED = const _State._("applied"); 798 static const APPLIED = const _State._("applied");
777 799
778 final String name; 800 final String name;
779 801
780 const _State._(this.name); 802 const _State._(this.name);
781 803
782 String toString() => name; 804 String toString() => name;
783 } 805 }
OLDNEW
« no previous file with comments | « pkg/barback/lib/src/graph/phase.dart ('k') | pkg/barback/lib/src/graph/transformer_classifier.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698