| 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_classifier; | |
| 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 classifying the primary inputs for a transformer according to | |
| 21 /// its `classifyPrimary` method. | |
| 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 TransformerClassifier { | |
| 27 /// The containing [Phase]. | |
| 28 final Phase _phase; | |
| 29 | |
| 30 /// The [Transformer] to use to classify 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 classiciation 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 classifier. | |
| 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 TransformerClassifier(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( | |
| 90 _phase, transformer, input, _location); | |
| 91 _transforms[input.id.path] = transform; | |
| 92 | |
| 93 transform.onStatusChange.listen( | |
| 94 (_) => _streams.changeStatus(status), | |
| 95 onDone: () => _transforms.remove(input.id.path)); | |
| 96 | |
| 97 _streams.onAssetPool.add(transform.onAsset); | |
| 98 _streams.onLogPool.add(transform.onLog); | |
| 99 } | |
| 100 }).whenComplete(() { | |
| 101 _activeIsPrimaries--; | |
| 102 if (!_streams.isClosed) _streams.changeStatus(status); | |
| 103 }); | |
| 104 } | |
| 105 | |
| 106 /// Removes this transformer. | |
| 107 /// | |
| 108 /// This marks all outputs of the transformer as removed. | |
| 109 void remove() { | |
| 110 _streams.close(); | |
| 111 for (var transform in _transforms.values.toList()) { | |
| 112 transform.remove(); | |
| 113 } | |
| 114 for (var forwarder in _passThroughForwarders.toList()) { | |
| 115 forwarder.close(); | |
| 116 } | |
| 117 } | |
| 118 | |
| 119 /// Force all deferred transforms to begin producing concrete assets. | |
| 120 void forceAllTransforms() { | |
| 121 for (var transform in _transforms.values) { | |
| 122 transform.force(); | |
| 123 } | |
| 124 } | |
| 125 | |
| 126 String toString() => "classifier in $_location for $transformer"; | |
| 127 } | |
| OLD | NEW |