| 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.transform_node; | 5 library barback.transform_node; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 | 8 |
| 9 import 'package:source_maps/span.dart'; | 9 import 'package:source_maps/span.dart'; |
| 10 | 10 |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 58 | 58 |
| 59 /// Whether [transformer] is lazy and this transform has yet to be forced. | 59 /// Whether [transformer] is lazy and this transform has yet to be forced. |
| 60 bool _isLazy; | 60 bool _isLazy; |
| 61 | 61 |
| 62 /// The subscriptions to each input's [AssetNode.onStateChange] stream. | 62 /// The subscriptions to each input's [AssetNode.onStateChange] stream. |
| 63 var _inputSubscriptions = new Map<AssetId, StreamSubscription>(); | 63 var _inputSubscriptions = new Map<AssetId, StreamSubscription>(); |
| 64 | 64 |
| 65 /// The controllers for the asset nodes emitted by this node. | 65 /// The controllers for the asset nodes emitted by this node. |
| 66 var _outputControllers = new Map<AssetId, AssetNodeController>(); | 66 var _outputControllers = new Map<AssetId, AssetNodeController>(); |
| 67 | 67 |
| 68 /// A stream that emits an event whenever [this] is no longer dirty. | 68 // TODO(nweiz): It's weird that this is different than the [onDone] stream the |
| 69 // other nodes emit. See if we can make that more consistent. |
| 70 /// A stream that emits an event whenever [onDirty] changes its value. |
| 69 /// | 71 /// |
| 70 /// This is synchronous in order to guarantee that it will emit an event as | 72 /// This is synchronous in order to guarantee that it will emit an event as |
| 71 /// soon as [isDirty] flips from `true` to `false`. | 73 /// soon as [isDirty] changes. It's possible for this to emit multiple events |
| 72 Stream get onDone => _onDoneController.stream; | 74 /// while [isDirty] is `true`. However, it will only emit a single event each |
| 73 final _onDoneController = new StreamController.broadcast(sync: true); | 75 /// time [isDirty] becomes `false`. |
| 76 Stream get onStateChange => _onStateChangeController.stream; |
| 77 final _onStateChangeController = new StreamController.broadcast(sync: true); |
| 74 | 78 |
| 75 /// A stream that emits any new assets emitted by [this]. | 79 /// A stream that emits any new assets emitted by [this]. |
| 76 /// | 80 /// |
| 77 /// Assets are emitted synchronously to ensure that any changes are thoroughly | 81 /// Assets are emitted synchronously to ensure that any changes are thoroughly |
| 78 /// propagated as soon as they occur. | 82 /// propagated as soon as they occur. |
| 79 Stream<AssetNode> get onAsset => _onAssetController.stream; | 83 Stream<AssetNode> get onAsset => _onAssetController.stream; |
| 80 final _onAssetController = new StreamController<AssetNode>(sync: true); | 84 final _onAssetController = new StreamController<AssetNode>(sync: true); |
| 81 | 85 |
| 82 /// A stream that emits an event whenever this transform logs an entry. | 86 /// A stream that emits an event whenever this transform logs an entry. |
| 83 /// | 87 /// |
| (...skipping 27 matching lines...) Expand all Loading... |
| 111 | 115 |
| 112 /// Marks this transform as removed. | 116 /// Marks this transform as removed. |
| 113 /// | 117 /// |
| 114 /// This causes all of the transform's outputs to be marked as removed as | 118 /// This causes all of the transform's outputs to be marked as removed as |
| 115 /// well. Normally this will be automatically done internally based on events | 119 /// well. Normally this will be automatically done internally based on events |
| 116 /// from the primary input, but it's possible for a transform to no longer be | 120 /// from the primary input, but it's possible for a transform to no longer be |
| 117 /// valid even if its primary input still exists. | 121 /// valid even if its primary input still exists. |
| 118 void remove() { | 122 void remove() { |
| 119 _hasBecomeDirty = false; | 123 _hasBecomeDirty = false; |
| 120 _onAssetController.close(); | 124 _onAssetController.close(); |
| 121 _onDoneController.close(); | 125 _onStateChangeController.close(); |
| 122 _primarySubscription.cancel(); | 126 _primarySubscription.cancel(); |
| 123 for (var subscription in _inputSubscriptions.values) { | 127 for (var subscription in _inputSubscriptions.values) { |
| 124 subscription.cancel(); | 128 subscription.cancel(); |
| 125 } | 129 } |
| 126 for (var controller in _outputControllers.values) { | 130 for (var controller in _outputControllers.values) { |
| 127 controller.setRemoved(); | 131 controller.setRemoved(); |
| 128 } | 132 } |
| 129 } | 133 } |
| 130 | 134 |
| 131 /// If [transformer] is lazy, ensures that its concrete outputs will be | 135 /// If [transformer] is lazy, ensures that its concrete outputs will be |
| (...skipping 17 matching lines...) Expand all Loading... |
| 149 | 153 |
| 150 /// Marks this transform as dirty. | 154 /// Marks this transform as dirty. |
| 151 /// | 155 /// |
| 152 /// This causes all of the transform's outputs to be marked as dirty as well. | 156 /// This causes all of the transform's outputs to be marked as dirty as well. |
| 153 void _dirty() { | 157 void _dirty() { |
| 154 for (var controller in _outputControllers.values) { | 158 for (var controller in _outputControllers.values) { |
| 155 controller.setDirty(); | 159 controller.setDirty(); |
| 156 } | 160 } |
| 157 | 161 |
| 158 _hasBecomeDirty = true; | 162 _hasBecomeDirty = true; |
| 163 _onStateChangeController.add(null); |
| 159 if (!_isApplying && !_pendingIsPrimary) _apply(); | 164 if (!_isApplying && !_pendingIsPrimary) _apply(); |
| 160 } | 165 } |
| 161 | 166 |
| 162 /// Applies this transform. | 167 /// Applies this transform. |
| 163 void _apply() { | 168 void _apply() { |
| 164 assert(!_onAssetController.isClosed); | 169 assert(!_onAssetController.isClosed); |
| 165 | 170 |
| 166 // Clear all the old input subscriptions. If an input is re-used, we'll | 171 // Clear all the old input subscriptions. If an input is re-used, we'll |
| 167 // re-subscribe. | 172 // re-subscribe. |
| 168 for (var subscription in _inputSubscriptions.values) { | 173 for (var subscription in _inputSubscriptions.values) { |
| 169 subscription.cancel(); | 174 subscription.cancel(); |
| 170 } | 175 } |
| 171 _inputSubscriptions.clear(); | 176 _inputSubscriptions.clear(); |
| 172 | 177 |
| 173 _isApplying = true; | 178 _isApplying = true; |
| 179 _onStateChangeController.add(null); |
| 174 primary.whenAvailable((_) { | 180 primary.whenAvailable((_) { |
| 175 _hasBecomeDirty = false; | 181 _hasBecomeDirty = false; |
| 176 | 182 |
| 177 // TODO(nweiz): If [transformer] is a [DeclaringTransformer] but not a | 183 // TODO(nweiz): If [transformer] is a [DeclaringTransformer] but not a |
| 178 // [LazyTransformer], we can get some mileage out of doing a declarative | 184 // [LazyTransformer], we can get some mileage out of doing a declarative |
| 179 // first so we know how to hook up the assets. | 185 // first so we know how to hook up the assets. |
| 180 if (_isLazy) return _declareLazy(); | 186 if (_isLazy) return _declareLazy(); |
| 181 return _applyImmediate(); | 187 return _applyImmediate(); |
| 182 }).catchError((error, stackTrace) { | 188 }).catchError((error, stackTrace) { |
| 183 // If the transform became dirty while processing, ignore any errors from | 189 // If the transform became dirty while processing, ignore any errors from |
| (...skipping 16 matching lines...) Expand all Loading... |
| 200 }).then((_) { | 206 }).then((_) { |
| 201 if (_onAssetController.isClosed) return; | 207 if (_onAssetController.isClosed) return; |
| 202 | 208 |
| 203 _isApplying = false; | 209 _isApplying = false; |
| 204 if (_hasBecomeDirty) { | 210 if (_hasBecomeDirty) { |
| 205 // Re-apply the transform if it became dirty while applying. | 211 // Re-apply the transform if it became dirty while applying. |
| 206 if (!_pendingIsPrimary) _apply(); | 212 if (!_pendingIsPrimary) _apply(); |
| 207 } else { | 213 } else { |
| 208 assert(!isDirty); | 214 assert(!isDirty); |
| 209 // Otherwise, notify the parent nodes that it's no longer dirty. | 215 // Otherwise, notify the parent nodes that it's no longer dirty. |
| 210 _onDoneController.add(null); | 216 _onStateChangeController.add(null); |
| 211 } | 217 } |
| 212 }); | 218 }); |
| 213 } | 219 } |
| 214 | 220 |
| 215 /// Gets the asset for an input [id]. | 221 /// Gets the asset for an input [id]. |
| 216 /// | 222 /// |
| 217 /// If an input with that ID cannot be found, throws an | 223 /// If an input with that ID cannot be found, throws an |
| 218 /// [AssetNotFoundException]. | 224 /// [AssetNotFoundException]. |
| 219 Future<Asset> getInput(AssetId id) { | 225 Future<Asset> getInput(AssetId id) { |
| 220 return phase.getInput(id).then((node) { | 226 return phase.getInput(id).then((node) { |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 320 void _log(AssetId asset, LogLevel level, String message, Span span) { | 326 void _log(AssetId asset, LogLevel level, String message, Span span) { |
| 321 // If the log isn't already associated with an asset, use the primary. | 327 // If the log isn't already associated with an asset, use the primary. |
| 322 if (asset == null) asset = primary.id; | 328 if (asset == null) asset = primary.id; |
| 323 var entry = new LogEntry(info, asset, level, message, span); | 329 var entry = new LogEntry(info, asset, level, message, span); |
| 324 _onLogController.add(entry); | 330 _onLogController.add(entry); |
| 325 } | 331 } |
| 326 | 332 |
| 327 String toString() => | 333 String toString() => |
| 328 "transform node in $_location for $transformer on $primary"; | 334 "transform node in $_location for $transformer on $primary"; |
| 329 } | 335 } |
| OLD | NEW |