| Index: pkg/barback/lib/src/asset/asset_node.dart
|
| diff --git a/pkg/barback/lib/src/asset/asset_node.dart b/pkg/barback/lib/src/asset/asset_node.dart
|
| deleted file mode 100644
|
| index 45d1b1771c215f165a2e3c001afb4a7ee5715e00..0000000000000000000000000000000000000000
|
| --- a/pkg/barback/lib/src/asset/asset_node.dart
|
| +++ /dev/null
|
| @@ -1,283 +0,0 @@
|
| -// 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.asset.asset_node;
|
| -
|
| -import 'dart:async';
|
| -
|
| -import '../errors.dart';
|
| -import '../graph/transform_node.dart';
|
| -import '../utils.dart';
|
| -import 'asset.dart';
|
| -import 'asset_id.dart';
|
| -
|
| -/// Describes the current state of an asset as part of a transformation graph.
|
| -///
|
| -/// An asset node can be in one of three states (see [AssetState]). It provides
|
| -/// an [onStateChange] stream that emits an event whenever it changes state.
|
| -///
|
| -/// Asset nodes are controlled using [AssetNodeController]s.
|
| -class AssetNode {
|
| - /// The id of the asset that this node represents.
|
| - final AssetId id;
|
| -
|
| - /// The [AssetNode] from which [this] is forwarded.
|
| - ///
|
| - /// For nodes that aren't forwarded, this will return [this]. Otherwise, it
|
| - /// will return the first node in the forwarding chain.
|
| - ///
|
| - /// This is used to determine whether two nodes are forwarded from the same
|
| - /// source.
|
| - AssetNode get origin => _origin == null ? this : _origin;
|
| - AssetNode _origin;
|
| -
|
| - /// The transform that created this asset node.
|
| - ///
|
| - /// This is `null` for source assets. It can change if the upstream transform
|
| - /// that created this asset changes; this change will *not* cause an
|
| - /// [onStateChange] event.
|
| - TransformNode get transform => _transform;
|
| - TransformNode _transform;
|
| -
|
| - /// The current state of the asset node.
|
| - AssetState get state => _state;
|
| - AssetState _state;
|
| -
|
| - /// The concrete asset that this node represents.
|
| - ///
|
| - /// This is null unless [state] is [AssetState.AVAILABLE].
|
| - Asset get asset => _asset;
|
| - Asset _asset;
|
| -
|
| - /// The callback to be called to notify this asset node's creator that the
|
| - /// concrete asset should be generated.
|
| - ///
|
| - /// This is null for non-lazy asset nodes (see [AssetNodeController.lazy]).
|
| - /// Once this is called, it's set to null and [this] is no longer considered
|
| - /// lazy.
|
| - Function _lazyCallback;
|
| -
|
| - /// Whether this node is lazy, meaning that [force] must be called to
|
| - /// guarantee that it will eventually become available.
|
| - bool get isLazy => _lazyCallback != null ||
|
| - (_origin != null && _origin.isLazy);
|
| -
|
| - /// A broadcast stream that emits an event whenever the node changes state.
|
| - ///
|
| - /// This stream is synchronous to ensure that when a source asset is modified
|
| - /// or removed, the appropriate portion of the asset graph is dirtied before
|
| - /// any [Barback.getAssetById] calls emit newly-incorrect values.
|
| - Stream<AssetState> get onStateChange => _stateChangeController.stream;
|
| -
|
| - /// This is synchronous so that a source being updated will always be
|
| - /// propagated through the build graph before anything that depends on it is
|
| - /// requested.
|
| - final _stateChangeController =
|
| - new StreamController<AssetState>.broadcast(sync: true);
|
| -
|
| - /// Calls [callback] when the node's asset is available.
|
| - ///
|
| - /// If the asset is currently available, this calls [callback] synchronously
|
| - /// to ensure that the asset is still available.
|
| - ///
|
| - /// The return value of [callback] is piped to the returned Future. If the
|
| - /// asset is removed before becoming available, the returned future will throw
|
| - /// an [AssetNotFoundException].
|
| - Future whenAvailable(callback(Asset asset)) {
|
| - return _waitForState((state) => state.isAvailable || state.isRemoved,
|
| - (state) {
|
| - if (state.isRemoved) throw new AssetNotFoundException(id);
|
| - return callback(asset);
|
| - });
|
| - }
|
| -
|
| - /// Calls [callback] when the node's asset is removed.
|
| - ///
|
| - /// If the asset is already removed when this is called, it calls [callback]
|
| - /// synchronously.
|
| - ///
|
| - /// The return value of [callback] is piped to the returned Future.
|
| - Future whenRemoved(callback()) =>
|
| - _waitForState((state) => state.isRemoved, (_) => callback());
|
| -
|
| - /// Returns a [Future] that completes when [state] changes from its current
|
| - /// value to any other value.
|
| - ///
|
| - /// The returned [Future] will contain the new state.
|
| - Future<AssetState> whenStateChanges() {
|
| - var startState = state;
|
| - return _waitForState((state) => state != startState, (state) => state);
|
| - }
|
| -
|
| - /// Calls [callback] as soon as the node is in a state that matches [test].
|
| - ///
|
| - /// [callback] is called synchronously if this is already in such a state.
|
| - ///
|
| - /// The return value of [callback] is piped to the returned Future.
|
| - Future _waitForState(bool test(AssetState state),
|
| - callback(AssetState state)) {
|
| - if (test(state)) return syncFuture(() => callback(state));
|
| - return onStateChange.firstWhere(test).then((_) => callback(state));
|
| - }
|
| -
|
| - AssetNode._(this.id, this._transform, this._origin)
|
| - : _state = AssetState.RUNNING;
|
| -
|
| - AssetNode._available(Asset asset, this._transform, this._origin)
|
| - : id = asset.id,
|
| - _asset = asset,
|
| - _state = AssetState.AVAILABLE;
|
| -
|
| - AssetNode._lazy(this.id, this._transform, this._origin, this._lazyCallback)
|
| - : _state = AssetState.RUNNING;
|
| -
|
| - /// If [this] is lazy, force it to generate a concrete asset; otherwise, do
|
| - /// nothing.
|
| - ///
|
| - /// See [AssetNodeController.lazy].
|
| - void force() {
|
| - if (_origin != null) {
|
| - _origin.force();
|
| - } else if (_lazyCallback != null) {
|
| - _lazyCallback();
|
| - _lazyCallback = null;
|
| - }
|
| - }
|
| -
|
| - String toString() => "${isLazy ? 'lazy' : state} asset $id";
|
| -}
|
| -
|
| -/// The controller for an [AssetNode].
|
| -///
|
| -/// This controls which state the node is in.
|
| -class AssetNodeController {
|
| - final AssetNode node;
|
| -
|
| - /// Creates a controller for a dirty node.
|
| - AssetNodeController(AssetId id, [TransformNode transform])
|
| - : node = new AssetNode._(id, transform, null);
|
| -
|
| - /// Creates a controller for an available node with the given concrete
|
| - /// [asset].
|
| - AssetNodeController.available(Asset asset, [TransformNode transform])
|
| - : node = new AssetNode._available(asset, transform, null);
|
| -
|
| - /// Creates a controller for a lazy node.
|
| - ///
|
| - /// For the most part, this node works like any other dirty node. However, the
|
| - /// owner of its controller isn't expected to do the work to make it available
|
| - /// as soon as possible like they would for a non-lazy node. Instead, when its
|
| - /// value is needed, [callback] will fire to indicate that it should be made
|
| - /// available as soon as possible.
|
| - ///
|
| - /// [callback] is guaranteed to only fire once.
|
| - AssetNodeController.lazy(AssetId id, void callback(),
|
| - [TransformNode transform])
|
| - : node = new AssetNode._lazy(id, transform, null, callback);
|
| -
|
| - /// Creates a controller for a node whose initial state matches the current
|
| - /// state of [node].
|
| - ///
|
| - /// [AssetNode.origin] of the returned node will automatically be set to
|
| - /// `node.origin`.
|
| - ///
|
| - /// If [node] is lazy, the returned node will also be lazy.
|
| - AssetNodeController.from(AssetNode node)
|
| - : node = new AssetNode._(node.id, node.transform, node.origin) {
|
| - if (node.state.isAvailable) {
|
| - setAvailable(node.asset);
|
| - } else if (node.state.isRemoved) {
|
| - setRemoved();
|
| - }
|
| - }
|
| -
|
| - /// Marks the node as [AssetState.RUNNING].
|
| - void setDirty() {
|
| - assert(node._state != AssetState.REMOVED);
|
| - node._asset = null;
|
| - node._lazyCallback = null;
|
| -
|
| - // Don't re-emit a dirty event to avoid cases where we try to dispatch an
|
| - // event while handling another event (e.g. an output is marked lazy, which
|
| - // causes it to be forced, which causes it to be marked dirty).
|
| - if (node._state.isDirty) return;
|
| - node._state = AssetState.RUNNING;
|
| - node._stateChangeController.add(AssetState.RUNNING);
|
| - }
|
| -
|
| - /// Marks the node as [AssetState.REMOVED].
|
| - ///
|
| - /// Once a node is marked as removed, it can't be marked as any other state.
|
| - /// If a new asset is created with the same id, it will get a new node.
|
| - void setRemoved() {
|
| - assert(node._state != AssetState.REMOVED);
|
| - node._state = AssetState.REMOVED;
|
| - node._asset = null;
|
| - node._lazyCallback = null;
|
| - node._stateChangeController.add(AssetState.REMOVED);
|
| - }
|
| -
|
| - /// Marks the node as [AssetState.AVAILABLE] with the given concrete [asset].
|
| - ///
|
| - /// It's an error to mark an already-available node as available. It should be
|
| - /// marked as dirty first.
|
| - void setAvailable(Asset asset) {
|
| - assert(asset.id == node.id);
|
| - assert(node._state != AssetState.REMOVED);
|
| - assert(node._state != AssetState.AVAILABLE);
|
| - node._state = AssetState.AVAILABLE;
|
| - node._asset = asset;
|
| - node._lazyCallback = null;
|
| - node._stateChangeController.add(AssetState.AVAILABLE);
|
| - }
|
| -
|
| - /// Marks the node as [AssetState.RUNNING] and lazy.
|
| - ///
|
| - /// Lazy nodes aren't expected to have their values generated until needed.
|
| - /// Once it's necessary, [callback] will be called. [callback] is guaranteed
|
| - /// to be called only once.
|
| - ///
|
| - /// See also [AssetNodeController.lazy].
|
| - void setLazy(void callback()) {
|
| - assert(node._state != AssetState.REMOVED);
|
| - node._state = AssetState.RUNNING;
|
| - node._asset = null;
|
| - node._lazyCallback = callback;
|
| - node._stateChangeController.add(AssetState.RUNNING);
|
| - }
|
| -
|
| - String toString() => "controller for $node";
|
| -}
|
| -
|
| -// TODO(nweiz): add an error state.
|
| -/// An enum of states that an [AssetNode] can be in.
|
| -class AssetState {
|
| - /// The node has a concrete asset loaded, available, and up-to-date. The asset
|
| - /// is accessible via [AssetNode.asset]. An asset can only be marked available
|
| - /// again from the [AssetState.RUNNING] state.
|
| - static final AVAILABLE = const AssetState._("available");
|
| -
|
| - /// The asset is no longer available, possibly for good. A removed asset will
|
| - /// never enter another state.
|
| - static final REMOVED = const AssetState._("removed");
|
| -
|
| - /// The asset will exist in the future (unless it's removed), but the concrete
|
| - /// asset is not yet available.
|
| - static final RUNNING = const AssetState._("dirty");
|
| -
|
| - /// Whether this state is [AssetState.AVAILABLE].
|
| - bool get isAvailable => this == AssetState.AVAILABLE;
|
| -
|
| - /// Whether this state is [AssetState.REMOVED].
|
| - bool get isRemoved => this == AssetState.REMOVED;
|
| -
|
| - /// Whether this state is [AssetState.RUNNING].
|
| - bool get isDirty => this == AssetState.RUNNING;
|
| -
|
| - final String name;
|
| -
|
| - const AssetState._(this.name);
|
| -
|
| - String toString() => name;
|
| -}
|
|
|