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

Unified Diff: pkg/barback/lib/src/phase_output.dart

Issue 26413003: Make PhaseOutput emit a new AssetNode whenever it changes outputs. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Code review change Created 7 years, 2 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/barback/lib/src/phase.dart ('k') | pkg/barback/test/package_graph/group_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/barback/lib/src/phase_output.dart
diff --git a/pkg/barback/lib/src/phase_output.dart b/pkg/barback/lib/src/phase_output.dart
index 1de4ec17c8f485c5a91bdb010de54964ce2e122f..31dcdd24c5e5d0f5f1f2c81c18e6b8562d95a442 100644
--- a/pkg/barback/lib/src/phase_output.dart
+++ b/pkg/barback/lib/src/phase_output.dart
@@ -8,6 +8,7 @@ import 'dart:async';
import 'dart:collection';
import 'asset_cascade.dart';
+import 'asset_forwarder.dart';
import 'asset_node.dart';
import 'errors.dart';
import 'phase.dart';
@@ -19,13 +20,22 @@ import 'utils.dart';
/// possible that multiple transformers in the same phase emit assets with the
/// same id, causing collisions. This handles those collisions by forwarding the
/// chronologically first asset.
+///
+/// When the asset being forwarding changes, the old value of [output] will be
+/// marked as removed and a new value will replace it. Users of this class can
+/// be notified of this using [onAsset].
class PhaseOutput {
/// The phase for which this is an output.
final Phase _phase;
/// The asset node for this output.
- AssetNode get output => _outputController.node;
- AssetNodeController _outputController;
+ AssetNode get output => _outputForwarder.node;
+ AssetNodeForwarder _outputForwarder;
+
+ /// A stream that emits an [AssetNode] each time this output starts forwarding
+ /// a new asset.
+ Stream<AssetNode> get onAsset => _onAssetController.stream;
+ final _onAssetController = new StreamController<AssetNode>();
/// The assets for this output.
///
@@ -44,7 +54,7 @@ class PhaseOutput {
}
PhaseOutput(this._phase, AssetNode output)
- : _outputController = new AssetNodeController.from(output) {
+ : _outputForwarder = new AssetForwarder(output) {
assert(!output.state.isRemoved);
add(output);
}
@@ -65,63 +75,38 @@ class PhaseOutput {
/// a new [Phase] to cause consumers of the prior phase's outputs to be to
/// start consuming the new phase's outputs instead.
void removeListeners() {
- _outputController.setRemoved();
- _outputController = new AssetNodeController.from(_assets.first);
+ _outputForwarder.close();
+ _outputForwarder = new AssetForwarder(_assets.first);
+ _onAssetController.add(output);
}
- /// Watches [node] for state changes and adjusts [_assets] and [output]
- /// appropriately when they occur.
+ /// Watches [node] to adjust [_assets] and [output] when it's removed.
void _watchAsset(AssetNode node) {
- node.onStateChange.listen((state) {
- if (state.isRemoved) {
- _removeAsset(node);
+ node.whenRemoved.then((_) {
+ if (_assets.length == 1) {
+ assert(_assets.single == node);
+ _outputForwarder.close();
+ _onAssetController.close();
return;
}
- if (_assets.first != node) return;
- if (state.isAvailable) {
- _outputController.setAvailable(node.asset);
- } else {
- assert(state.isDirty);
- _outputController.setDirty();
+ // If there was more than one asset, we're resolving a collision --
+ // possibly partially.
+ var wasFirst = _assets.first == node;
+ _assets.remove(node);
+
+ // If this was the first asset, we replace it with the next asset
+ // (chronologically).
+ if (wasFirst) removeListeners();
+
+ // If there's still a collision, report it. This lets the user know if
+ // they've successfully resolved the collision or not.
+ if (_assets.length > 1) {
+ // Pump the event queue to ensure that the removal of the input triggers
+ // a new build to which we can attach the error.
+ // TODO(nweiz): report this through the output asset.
+ newFuture(() => _phase.cascade.reportError(collisionException));
}
});
}
-
- /// Removes [node] as an output.
- void _removeAsset(AssetNode node) {
- if (_assets.length == 1) {
- assert(_assets.single == node);
- _outputController.setRemoved();
- return;
- }
-
- // If there was more than one asset, we're resolving a collision --
- // possibly partially.
- var wasFirst = _assets.first == node;
- _assets.remove(node);
-
- // If this was the first asset, we replace it with the next asset
- // (chronologically).
- if (wasFirst) {
- var newOutput = _assets.first;
- _outputController.setOrigin(newOutput.origin);
- if (newOutput.state.isAvailable) {
- if (output.state.isAvailable) _outputController.setDirty();
- _outputController.setAvailable(newOutput.asset);
- } else {
- assert(newOutput.isDirty);
- if (!output.state.isDirty) _outputController.setDirty();
- }
- }
-
- // If there's still a collision, report it. This lets the user know
- // if they've successfully resolved the collision or not.
- if (_assets.length > 1) {
- // Pump the event queue to ensure that the removal of the input triggers
- // a new build to which we can attach the error.
- // TODO(nweiz): report this through the output asset.
- newFuture(() => _phase.cascade.reportError(collisionException));
- }
- }
}
« no previous file with comments | « pkg/barback/lib/src/phase.dart ('k') | pkg/barback/test/package_graph/group_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698