Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | |
| 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. | |
| 4 | |
| 5 library barback.transformer_sorter; | |
| 6 | |
| 7 import 'dart:async'; | |
| 8 | |
| 9 import 'asset_forwarder.dart'; | |
| 10 import 'asset_node.dart'; | |
| 11 import 'errors.dart'; | |
| 12 import 'log.dart'; | |
| 13 import 'node_status.dart'; | |
| 14 import 'node_streams.dart'; | |
| 15 import 'phase.dart'; | |
| 16 import 'transform_node.dart'; | |
| 17 import 'transformer.dart'; | |
| 18 import 'utils.dart'; | |
| 19 | |
| 20 /// A class for sorting the primary inputs for a transformer according to its | |
| 21 /// `sortPrimary` method. | |
|
Bob Nystrom
2014/05/01 19:49:33
This doesn't exist yet, right?
nweiz
2014/05/01 20:47:02
Correct.
| |
| 22 /// | |
| 23 /// This is used for non-aggregate transformers; they're modeled as aggregate | |
| 24 /// transformers that return the primary path if `isPrimary` is true and `null` | |
| 25 /// if `isPrimary` is `null`. | |
| 26 class TransformerSorter { | |
|
Bob Nystrom
2014/05/01 19:49:33
"Sorter" isn't the right word here since it implie
nweiz
2014/05/01 20:47:02
It's sorting in the commonly-used real-world sense
| |
| 27 /// The containing [Phase]. | |
| 28 final Phase _phase; | |
| 29 | |
| 30 /// The [Transformer] to use to sort the inputs. | |
| 31 final Transformer transformer; | |
| 32 | |
| 33 /// A string describing the location of [this] in the transformer graph. | |
| 34 final String _location; | |
| 35 | |
| 36 /// The individual transforms for each sort key. | |
| 37 final _transforms = new Map<Object, TransformNode>(); | |
| 38 | |
| 39 /// Forwarders used to pass through assets that aren't used by [transformer]. | |
| 40 final _passThroughForwarders = new Set<AssetForwarder>(); | |
| 41 | |
| 42 /// The streams exposed by this sorter. | |
| 43 final _streams = new NodeStreams(); | |
| 44 Stream get onStatusChange => _streams.onStatusChange; | |
| 45 Stream<AssetNode> get onAsset => _streams.onAsset; | |
| 46 Stream<LogEntry> get onLog => _streams.onLog; | |
| 47 | |
| 48 /// The number of currently-active calls to [transformer.isPrimary]. | |
| 49 /// | |
| 50 /// This is used to determine whether [this] is dirty. | |
| 51 var _activeIsPrimaries = 0; | |
| 52 | |
| 53 /// How far along [this] is in processing its assets. | |
| 54 NodeStatus get status { | |
| 55 if (_activeIsPrimaries > 0) return NodeStatus.RUNNING; | |
| 56 return NodeStatus.dirtiest( | |
| 57 _transforms.values.map((transform) => transform.status)); | |
| 58 } | |
| 59 | |
| 60 TransformerSorter(this._phase, this.transformer, this._location); | |
| 61 | |
| 62 /// Adds a new asset as an input for this transformer. | |
| 63 void addInput(AssetNode input) { | |
| 64 _activeIsPrimaries++; | |
| 65 syncFuture(() => transformer.isPrimary(input.id)).catchError( | |
| 66 (error, stackTrace) { | |
| 67 if (input.state.isRemoved) return false; | |
| 68 | |
| 69 // Catch all transformer errors and pipe them to the results stream. This | |
| 70 // is so a broken transformer doesn't take down the whole graph. | |
| 71 var info = new TransformInfo(transformer, input.id); | |
| 72 if (error is! AssetNotFoundException) { | |
| 73 error = new TransformerException(info, error, stackTrace); | |
| 74 } else { | |
| 75 error = new MissingInputException(info, error.id); | |
| 76 } | |
| 77 _phase.cascade.reportError(error); | |
| 78 | |
| 79 return false; | |
| 80 }).then((isPrimary) { | |
| 81 if (input.state.isRemoved) return; | |
| 82 if (!isPrimary) { | |
| 83 var forwarder = new AssetForwarder(input); | |
| 84 _passThroughForwarders.add(forwarder); | |
| 85 forwarder.node.whenRemoved( | |
| 86 () => _passThroughForwarders.remove(forwarder)); | |
| 87 _streams.onAssetController.add(forwarder.node); | |
| 88 } else { | |
| 89 var transform = new TransformNode(_phase, transformer, input, _location) ; | |
|
Bob Nystrom
2014/05/01 19:49:33
Long line.
nweiz
2014/05/01 20:47:02
Done.
| |
| 90 _transforms[input.id.path] = transform; | |
| 91 | |
| 92 transform.onStatusChange.listen( | |
| 93 (_) => _streams.changeStatus(status), | |
| 94 onDone: () => _transforms.remove(input.id.path)); | |
| 95 | |
| 96 _streams.onAssetPool.add(transform.onAsset); | |
| 97 _streams.onLogPool.add(transform.onLog); | |
| 98 } | |
| 99 }).whenComplete(() { | |
| 100 _activeIsPrimaries--; | |
| 101 if (!_streams.isClosed) _streams.changeStatus(status); | |
| 102 }); | |
| 103 } | |
| 104 | |
| 105 /// Removes this transformer. | |
| 106 /// | |
| 107 /// This marks all outputs of the transformer as removed. | |
| 108 void remove() { | |
| 109 _streams.close(); | |
| 110 for (var transform in _transforms.values.toList()) { | |
| 111 transform.remove(); | |
| 112 } | |
| 113 for (var forwarder in _passThroughForwarders.toList()) { | |
| 114 forwarder.close(); | |
| 115 } | |
| 116 } | |
| 117 | |
| 118 /// Force all deferred transforms to begin producing concrete assets. | |
| 119 void forceAllTransforms() { | |
| 120 for (var transform in _transforms.values) { | |
| 121 transform.force(); | |
| 122 } | |
| 123 } | |
| 124 | |
| 125 String toString() => "sorter in $_location for $transformer"; | |
| 126 } | |
| OLD | NEW |