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

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

Issue 23311006: Add the ability to dynamically modify transforms to barback. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Code review changes. Created 7 years, 4 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/package_provider.dart ('k') | pkg/barback/lib/src/utils.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/barback/lib/src/phase.dart
diff --git a/pkg/barback/lib/src/phase.dart b/pkg/barback/lib/src/phase.dart
index 3c9f3f9d2b94818b06860c424ccb2995386d2414..263741de931d6c3c3d0997b3b39b8a1d43c0a9e0 100644
--- a/pkg/barback/lib/src/phase.dart
+++ b/pkg/barback/lib/src/phase.dart
@@ -36,7 +36,7 @@ class Phase {
/// The transformers that can access [inputs].
///
/// Their outputs will be available to the next phase.
- final List<Transformer> _transformers;
+ final Set<Transformer> _transformers;
/// The inputs that are available for transforms in this phase to consume.
///
@@ -102,7 +102,8 @@ class Phase {
/// The phase after this one.
///
/// Outputs from this phase will be passed to it.
- final Phase _next;
+ Phase get next => _next;
+ Phase _next;
/// Returns all currently-available output assets for this phase.
AssetSet get availableOutputs {
@@ -112,7 +113,8 @@ class Phase {
.map((node) => node.asset));
}
- Phase(this.cascade, this._transformers, this._next) {
+ Phase(this.cascade, Iterable<Transformer> transformers)
+ : _transformers = transformers.toSet() {
_onDirtyPool.add(_onDirtyController.stream);
}
@@ -195,6 +197,60 @@ class Phase {
});
}
+ /// Set this phase's transformers to [transformers].
+ void updateTransformers(Iterable<Transformer> transformers) {
+ _onDirtyController.add(null);
+
+ var newTransformers = transformers.toSet();
+ var oldTransformers = _transformers.toSet();
+ for (var removedTransformer in
+ oldTransformers.difference(newTransformers)) {
+ _transformers.remove(removedTransformer);
+
+ // Remove old transforms for which [removedTransformer] was a transformer.
+ for (var id in _inputs.keys) {
+ // If the transformers are being adjusted for [id], it will
+ // automatically pick up on [removedTransformer] being gone.
+ if (_adjustTransformersFutures.containsKey(id)) continue;
+
+ _transforms[id].removeWhere((transform) {
+ if (transform.transformer != removedTransformer) return false;
+ transform.remove();
+ return true;
+ });
+
+ if (!_transforms[id].isEmpty) continue;
+ _passThroughControllers.putIfAbsent(id, () {
+ return new AssetNodeController.available(
+ _inputs[id].asset, _inputs[id].transform);
+ });
+ }
+ }
+
+ var brandNewTransformers = newTransformers.difference(oldTransformers);
+ if (brandNewTransformers.isEmpty) return;
+ brandNewTransformers.forEach(_transformers.add);
+
+ // If there are any new transformers, start re-adjusting the transforms for
+ // all inputs so we pick up which inputs the new transformers apply to.
+ _inputs.forEach((id, node) {
+ if (_adjustTransformersFutures.containsKey(id)) return;
+ _adjustTransformers(node);
+ });
+ }
+
+ /// Add a new phase after this one with [transformers].
+ ///
+ /// This may only be called on a phase with no phase following it.
+ Phase addPhase(Iterable<Transformer> transformers) {
+ assert(_next == null);
+ _next = new Phase(cascade, transformers);
+ for (var outputs in _outputs.values) {
+ _next.addInput(outputs.first);
+ }
+ return _next;
+ }
+
/// Asynchronously determines which transformers can consume [node] as a
/// primary input and creates transforms for them.
///
@@ -214,12 +270,13 @@ class Phase {
// Once the input is available, hook up transformers for it. If it changes
// while that's happening, try again.
- _adjustTransformersFutures[node.id] = node.tryUntilStable((asset) {
+ _adjustTransformersFutures[node.id] = _tryUntilStable(node,
+ (asset, transformers) {
var oldTransformers = _transforms[node.id]
.map((transform) => transform.transformer).toSet();
- return _removeStaleTransforms(asset)
- .then((_) => _addFreshTransforms(node, oldTransformers));
+ return _removeStaleTransforms(asset, transformers).then((_) =>
+ _addFreshTransforms(node, transformers, oldTransformers));
}).then((_) {
_adjustPassThrough(node);
@@ -258,11 +315,15 @@ class Phase {
// Remove any old transforms that used to have [asset] as a primary asset but
// no longer apply to its new contents.
- Future _removeStaleTransforms(Asset asset) {
+ Future _removeStaleTransforms(Asset asset, Set<Transformer> transformers) {
return Future.wait(_transforms[asset.id].map((transform) {
- // TODO(rnystrom): Catch all errors from isPrimary() and redirect to
- // results.
- return transform.transformer.isPrimary(asset).then((isPrimary) {
+ return newFuture(() {
+ if (!transformers.contains(transform.transformer)) return false;
+
+ // TODO(rnystrom): Catch all errors from isPrimary() and redirect to
+ // results.
+ return transform.transformer.isPrimary(asset);
+ }).then((isPrimary) {
if (isPrimary) return;
_transforms[asset.id].remove(transform);
_onDirtyPool.remove(transform.onDirty);
@@ -274,11 +335,13 @@ class Phase {
// Add new transforms for transformers that consider [node]'s asset to be a
// primary input.
//
- // [oldTransformers] is the set of transformers that had [node] as a primary
- // input prior to this. They don't need to be checked, since they were removed
- // or preserved in [_removeStaleTransforms].
- Future _addFreshTransforms(AssetNode node, Set<Transformer> oldTransformers) {
- return Future.wait(_transformers.map((transformer) {
+ // [oldTransformers] is the set of transformers for which there were
+ // transforms that had [node] as a primary input prior to this. They don't
+ // need to be checked, since their transforms were removed or preserved in
+ // [_removeStaleTransforms].
+ Future _addFreshTransforms(AssetNode node, Set<Transformer> transformers,
+ Set<Transformer> oldTransformers) {
+ return Future.wait(transformers.map((transformer) {
if (oldTransformers.contains(transformer)) return new Future.value();
// If the asset is unavailable, the results of this [_adjustTransformers]
@@ -321,6 +384,20 @@ class Phase {
}
}
+ /// Like [AssetNode.tryUntilStable], but also re-runs [callback] if this
+ /// phase's transformers are modified.
+ Future _tryUntilStable(AssetNode node,
+ Future callback(Asset asset, Set<Transformer> transformers)) {
+ var oldTransformers;
+ return node.tryUntilStable((asset) {
+ oldTransformers = _transformers.toSet();
+ return callback(asset, _transformers);
+ }).then((result) {
+ if (setEquals(oldTransformers, _transformers)) return result;
+ return _tryUntilStable(node, callback);
+ });
+ }
+
/// Processes this phase.
///
/// Returns a future that completes when processing is done. If there is
« no previous file with comments | « pkg/barback/lib/src/package_provider.dart ('k') | pkg/barback/lib/src/utils.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698