| 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.asset_node; | 5 library barback.asset_node; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 | 8 |
| 9 import 'asset.dart'; | 9 import 'asset.dart'; |
| 10 import 'asset_id.dart'; | 10 import 'asset_id.dart'; |
| 11 import 'errors.dart'; | 11 import 'errors.dart'; |
| 12 import 'transform_node.dart'; | 12 import 'transform_node.dart'; |
| 13 | 13 |
| 14 /// Describes the current state of an asset as part of a transformation graph. | 14 /// Describes the current state of an asset as part of a transformation graph. |
| 15 /// | 15 /// |
| 16 /// An asset node can be in one of three states (see [AssetState]). It provides | 16 /// An asset node can be in one of three states (see [AssetState]). It provides |
| 17 /// an [onStateChange] stream that emits an event whenever it changes state. | 17 /// an [onStateChange] stream that emits an event whenever it changes state. |
| 18 /// | 18 /// |
| 19 /// Asset nodes are controlled using [AssetNodeController]s. | 19 /// Asset nodes are controlled using [AssetNodeController]s. |
| 20 class AssetNode { | 20 class AssetNode { |
| 21 /// The id of the asset that this node represents. | 21 /// The id of the asset that this node represents. |
| 22 final AssetId id; | 22 final AssetId id; |
| 23 | 23 |
| 24 /// The [AssetNode] from which [this] is forwarded. |
| 25 /// |
| 26 /// For nodes that aren't forwarded, this will return [this]. Otherwise, it |
| 27 /// will return the first node in the forwarding chain. |
| 28 /// |
| 29 /// This is used to determine whether two nodes are forwarded from the same |
| 30 /// source. |
| 31 AssetNode get origin => _origin == null ? this : _origin; |
| 32 AssetNode _origin; |
| 33 |
| 24 /// The transform that created this asset node. | 34 /// The transform that created this asset node. |
| 25 /// | 35 /// |
| 26 /// This is `null` for source assets. It can change if the upstream transform | 36 /// This is `null` for source assets. It can change if the upstream transform |
| 27 /// that created this asset changes; this change will *not* cause an | 37 /// that created this asset changes; this change will *not* cause an |
| 28 /// [onStateChange] event. | 38 /// [onStateChange] event. |
| 29 TransformNode get transform => _transform; | 39 TransformNode get transform => _transform; |
| 30 TransformNode _transform; | 40 TransformNode _transform; |
| 31 | 41 |
| 32 /// The current state of the asset node. | 42 /// The current state of the asset node. |
| 33 AssetState get state => _state; | 43 AssetState get state => _state; |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 106 | 116 |
| 107 /// Returns a Future that completes as soon as the node is in a state that | 117 /// Returns a Future that completes as soon as the node is in a state that |
| 108 /// matches [test]. | 118 /// matches [test]. |
| 109 /// | 119 /// |
| 110 /// The Future completes synchronously if this is already in such a state. | 120 /// The Future completes synchronously if this is already in such a state. |
| 111 Future<AssetState> _waitForState(bool test(AssetState state)) { | 121 Future<AssetState> _waitForState(bool test(AssetState state)) { |
| 112 if (test(state)) return new Future.sync(() => state); | 122 if (test(state)) return new Future.sync(() => state); |
| 113 return onStateChange.firstWhere(test); | 123 return onStateChange.firstWhere(test); |
| 114 } | 124 } |
| 115 | 125 |
| 116 AssetNode._(this.id, this._transform) | 126 AssetNode._(this.id, this._transform, this._origin) |
| 117 : _state = AssetState.DIRTY; | 127 : _state = AssetState.DIRTY; |
| 118 | 128 |
| 119 AssetNode._available(Asset asset, this._transform) | 129 AssetNode._available(Asset asset, this._transform, this._origin) |
| 120 : id = asset.id, | 130 : id = asset.id, |
| 121 _asset = asset, | 131 _asset = asset, |
| 122 _state = AssetState.AVAILABLE; | 132 _state = AssetState.AVAILABLE; |
| 123 } | 133 } |
| 124 | 134 |
| 125 /// The controller for an [AssetNode]. | 135 /// The controller for an [AssetNode]. |
| 126 /// | 136 /// |
| 127 /// This controls which state the node is in. | 137 /// This controls which state the node is in. |
| 128 class AssetNodeController { | 138 class AssetNodeController { |
| 129 final AssetNode node; | 139 final AssetNode node; |
| 130 | 140 |
| 131 /// Creates a controller for a dirty node. | 141 /// Creates a controller for a dirty node. |
| 132 AssetNodeController(AssetId id, [TransformNode transform]) | 142 AssetNodeController(AssetId id, [TransformNode transform]) |
| 133 : node = new AssetNode._(id, transform); | 143 : node = new AssetNode._(id, transform, null); |
| 134 | 144 |
| 135 /// Creates a controller for an available node with the given concrete | 145 /// Creates a controller for an available node with the given concrete |
| 136 /// [asset]. | 146 /// [asset]. |
| 137 AssetNodeController.available(Asset asset, [TransformNode transform]) | 147 AssetNodeController.available(Asset asset, [TransformNode transform]) |
| 138 : node = new AssetNode._available(asset, transform); | 148 : node = new AssetNode._available(asset, transform, null); |
| 139 | 149 |
| 140 /// Creates a controller for a node whose initial state matches the current | 150 /// Creates a controller for a node whose initial state matches the current |
| 141 /// state of [node]. | 151 /// state of [node]. |
| 152 /// |
| 153 /// [AssetNode.origin] of the returned node will automatically be set to |
| 154 /// `node.origin`. |
| 142 AssetNodeController.from(AssetNode node) | 155 AssetNodeController.from(AssetNode node) |
| 143 : node = new AssetNode._(node.id, node.transform) { | 156 : node = new AssetNode._(node.id, node.transform, node.origin) { |
| 144 if (node.state.isAvailable) { | 157 if (node.state.isAvailable) { |
| 145 setAvailable(node.asset); | 158 setAvailable(node.asset); |
| 146 } else if (node.state.isRemoved) { | 159 } else if (node.state.isRemoved) { |
| 147 setRemoved(); | 160 setRemoved(); |
| 148 } | 161 } |
| 149 } | 162 } |
| 150 | 163 |
| 151 /// Marks the node as [AssetState.DIRTY]. | 164 /// Marks the node as [AssetState.DIRTY]. |
| 152 void setDirty() { | 165 void setDirty() { |
| 153 assert(node._state != AssetState.REMOVED); | 166 assert(node._state != AssetState.REMOVED); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 173 /// marked as dirty first. | 186 /// marked as dirty first. |
| 174 void setAvailable(Asset asset) { | 187 void setAvailable(Asset asset) { |
| 175 assert(asset.id == node.id); | 188 assert(asset.id == node.id); |
| 176 assert(node._state != AssetState.REMOVED); | 189 assert(node._state != AssetState.REMOVED); |
| 177 assert(node._state != AssetState.AVAILABLE); | 190 assert(node._state != AssetState.AVAILABLE); |
| 178 node._state = AssetState.AVAILABLE; | 191 node._state = AssetState.AVAILABLE; |
| 179 node._asset = asset; | 192 node._asset = asset; |
| 180 node._stateChangeController.add(AssetState.AVAILABLE); | 193 node._stateChangeController.add(AssetState.AVAILABLE); |
| 181 } | 194 } |
| 182 | 195 |
| 183 /// Sets the node's [AssetNode.transform] property. | 196 /// Sets the origin of [node] to [origin] and the transform to |
| 184 /// | 197 /// `origin.transform`. |
| 185 /// This is used when resolving collisions, where a node will stick around but | 198 void setOrigin(AssetNode origin) { |
| 186 /// a different transform will have created it. | 199 node._origin = origin; |
| 187 void setTransform(TransformNode transform) { | 200 node._transform = origin.transform; |
| 188 node._transform = transform; | |
| 189 } | 201 } |
| 190 } | 202 } |
| 191 | 203 |
| 192 // TODO(nweiz): add an error state. | 204 // TODO(nweiz): add an error state. |
| 193 /// An enum of states that an [AssetNode] can be in. | 205 /// An enum of states that an [AssetNode] can be in. |
| 194 class AssetState { | 206 class AssetState { |
| 195 /// The node has a concrete asset loaded, available, and up-to-date. The asset | 207 /// The node has a concrete asset loaded, available, and up-to-date. The asset |
| 196 /// is accessible via [AssetNode.asset]. An asset can only be marked available | 208 /// is accessible via [AssetNode.asset]. An asset can only be marked available |
| 197 /// again from the [AssetState.DIRTY] state. | 209 /// again from the [AssetState.DIRTY] state. |
| 198 static final AVAILABLE = const AssetState._("available"); | 210 static final AVAILABLE = const AssetState._("available"); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 213 | 225 |
| 214 /// Whether this state is [AssetState.DIRTY]. | 226 /// Whether this state is [AssetState.DIRTY]. |
| 215 bool get isDirty => this == AssetState.DIRTY; | 227 bool get isDirty => this == AssetState.DIRTY; |
| 216 | 228 |
| 217 final String name; | 229 final String name; |
| 218 | 230 |
| 219 const AssetState._(this.name); | 231 const AssetState._(this.name); |
| 220 | 232 |
| 221 String toString() => name; | 233 String toString() => name; |
| 222 } | 234 } |
| OLD | NEW |