| Index: pkg/barback/lib/src/transform_node.dart
|
| diff --git a/pkg/barback/lib/src/transform_node.dart b/pkg/barback/lib/src/transform_node.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..49222be9e5af2e184eb0c45e30520ab2c55d53fd
|
| --- /dev/null
|
| +++ b/pkg/barback/lib/src/transform_node.dart
|
| @@ -0,0 +1,107 @@
|
| +// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
|
| +// for details. All rights reserved. Use of this source code is governed by a
|
| +// BSD-style license that can be found in the LICENSE file.
|
| +
|
| +library barback.transform_node;
|
| +
|
| +import 'dart:async';
|
| +
|
| +import 'asset.dart';
|
| +import 'asset_graph.dart';
|
| +import 'asset_id.dart';
|
| +import 'asset_node.dart';
|
| +import 'errors.dart';
|
| +import 'phase.dart';
|
| +import 'transform.dart';
|
| +import 'transformer.dart';
|
| +
|
| +/// Describes a transform on a set of assets and its relationship to the build
|
| +/// dependency graph.
|
| +///
|
| +/// Keeps track of whether it's dirty and needs to be run and which assets it
|
| +/// depends on.
|
| +class TransformNode {
|
| + /// The [Phase] that this transform runs in.
|
| + final Phase phase;
|
| +
|
| + /// The [Transformer] to apply to this node's inputs.
|
| + final Transformer _transformer;
|
| +
|
| + /// The node for the primary asset this transform depends on.
|
| + final AssetNode primary;
|
| +
|
| + /// True if an input has been modified since the last time this transform
|
| + /// was run.
|
| + bool get isDirty => _isDirty;
|
| + var _isDirty = true;
|
| +
|
| + /// The inputs read by this transform the last time it was run.
|
| + ///
|
| + /// Used to tell if an input was removed in a later run.
|
| + var _inputs = new Set<AssetNode>();
|
| +
|
| + /// The outputs created by this transform the last time it was run.
|
| + ///
|
| + /// Used to tell if an output was removed in a later run.
|
| + var _outputs = new Set<AssetId>();
|
| +
|
| + TransformNode(this.phase, this._transformer, this.primary);
|
| +
|
| + /// Marks this transform as needing to be run.
|
| + void dirty() {
|
| + _isDirty = true;
|
| + }
|
| +
|
| + /// Applies this transform.
|
| + ///
|
| + /// Returns a [TransformOutputs] describing the resulting outputs compared to
|
| + /// previous runs.
|
| + Future<TransformOutputs> apply() {
|
| + var newInputs = new Set<AssetNode>();
|
| + var newOutputs = new Map<AssetId, Asset>();
|
| + var transform = createTransform(this, newInputs, newOutputs);
|
| + return _transformer.apply(transform).catchError((error) {
|
| + // Catch all transformer errors and pipe them to the results stream.
|
| + // This is so a broken transformer doesn't take down the whole graph.
|
| + phase.graph.reportError(error);
|
| +
|
| + // Don't allow partial results from a failed transform.
|
| + newOutputs.clear();
|
| + }).then((_) {
|
| + _isDirty = false;
|
| +
|
| + // Stop watching any inputs that were removed.
|
| + for (var oldInput in _inputs) {
|
| + oldInput.consumers.remove(this);
|
| + }
|
| +
|
| + // Watch any new inputs so this transform will be re-processed when an
|
| + // input is modified.
|
| + for (var newInput in newInputs) {
|
| + newInput.consumers.add(this);
|
| + }
|
| +
|
| + _inputs = newInputs;
|
| +
|
| + // See which outputs are missing from the last run.
|
| + var outputIds = newOutputs.keys.toSet();
|
| + var removed = _outputs.difference(outputIds);
|
| + _outputs = outputIds;
|
| +
|
| + return new TransformOutputs(newOutputs, removed);
|
| + });
|
| + }
|
| +}
|
| +
|
| +/// The result of running a [Transform], compared to the previous time it was
|
| +/// applied.
|
| +class TransformOutputs {
|
| + /// The outputs that are new or were modified since the last run.
|
| + final Map<AssetId, Asset> updated;
|
| +
|
| + /// The outputs that were created by the previous run but were not generated
|
| + /// by the most recent run.
|
| + final Set<AssetId> removed;
|
| +
|
| + TransformOutputs(this.updated, this.removed);
|
| +}
|
|
|