Chromium Code Reviews| 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'; |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 43 /// The current state of the asset node. | 43 /// The current state of the asset node. |
| 44 AssetState get state => _state; | 44 AssetState get state => _state; |
| 45 AssetState _state; | 45 AssetState _state; |
| 46 | 46 |
| 47 /// The concrete asset that this node represents. | 47 /// The concrete asset that this node represents. |
| 48 /// | 48 /// |
| 49 /// This is null unless [state] is [AssetState.AVAILABLE]. | 49 /// This is null unless [state] is [AssetState.AVAILABLE]. |
| 50 Asset get asset => _asset; | 50 Asset get asset => _asset; |
| 51 Asset _asset; | 51 Asset _asset; |
| 52 | 52 |
| 53 /// The callback to be called to notify this asset node's creator that the | |
| 54 /// asset should be materialized. | |
| 55 /// | |
| 56 /// This is only non-null for lazy asset nodes (see | |
|
Bob Nystrom
2014/01/30 19:33:44
"only non-null for lazy" -> "null for non-lazy"
nweiz
2014/01/31 03:43:27
Done.
| |
| 57 /// [AssetNodeController.lazy]). Once this is called, it's set to null and | |
| 58 /// [this] is no longer considered lazy. | |
| 59 Function _lazyCallback; | |
|
Bob Nystrom
2014/01/30 19:33:44
I'm all for using callbacks in barback, but isn't
nweiz
2014/01/31 03:43:27
I chose a callback instead because it's guaranteed
| |
| 60 | |
| 53 /// A broadcast stream that emits an event whenever the node changes state. | 61 /// A broadcast stream that emits an event whenever the node changes state. |
| 54 /// | 62 /// |
| 55 /// This stream is synchronous to ensure that when a source asset is modified | 63 /// This stream is synchronous to ensure that when a source asset is modified |
| 56 /// or removed, the appropriate portion of the asset graph is dirtied before | 64 /// or removed, the appropriate portion of the asset graph is dirtied before |
| 57 /// any [Barback.getAssetById] calls emit newly-incorrect values. | 65 /// any [Barback.getAssetById] calls emit newly-incorrect values. |
| 58 Stream<AssetState> get onStateChange => _stateChangeController.stream; | 66 Stream<AssetState> get onStateChange => _stateChangeController.stream; |
| 59 | 67 |
| 60 /// This is synchronous so that a source being updated will always be | 68 /// This is synchronous so that a source being updated will always be |
| 61 /// propagated through the build graph before anything that depends on it is | 69 /// propagated through the build graph before anything that depends on it is |
| 62 /// requested. | 70 /// requested. |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 130 return onStateChange.firstWhere(test).then((_) => callback(state)); | 138 return onStateChange.firstWhere(test).then((_) => callback(state)); |
| 131 } | 139 } |
| 132 | 140 |
| 133 AssetNode._(this.id, this._transform, this._origin) | 141 AssetNode._(this.id, this._transform, this._origin) |
| 134 : _state = AssetState.DIRTY; | 142 : _state = AssetState.DIRTY; |
| 135 | 143 |
| 136 AssetNode._available(Asset asset, this._transform, this._origin) | 144 AssetNode._available(Asset asset, this._transform, this._origin) |
| 137 : id = asset.id, | 145 : id = asset.id, |
| 138 _asset = asset, | 146 _asset = asset, |
| 139 _state = AssetState.AVAILABLE; | 147 _state = AssetState.AVAILABLE; |
| 148 | |
| 149 AssetNode._lazy(this.id, this._transform, this._origin, this._lazyCallback) | |
| 150 : _state = AssetState.DIRTY; | |
| 151 | |
| 152 /// If [this] is lazy, materialize it; otherwise, do nothing. | |
| 153 /// | |
| 154 /// See [AssetNodeController.lazy]. | |
| 155 void materialize() { | |
| 156 if (_origin != null) { | |
| 157 _origin.materialize(); | |
| 158 } else if (_lazyCallback != null) { | |
| 159 _lazyCallback(); | |
| 160 _lazyCallback = null; | |
| 161 } | |
| 162 } | |
| 140 } | 163 } |
| 141 | 164 |
| 142 /// The controller for an [AssetNode]. | 165 /// The controller for an [AssetNode]. |
| 143 /// | 166 /// |
| 144 /// This controls which state the node is in. | 167 /// This controls which state the node is in. |
| 145 class AssetNodeController { | 168 class AssetNodeController { |
| 146 final AssetNode node; | 169 final AssetNode node; |
| 147 | 170 |
| 148 /// Creates a controller for a dirty node. | 171 /// Creates a controller for a dirty node. |
| 149 AssetNodeController(AssetId id, [TransformNode transform]) | 172 AssetNodeController(AssetId id, [TransformNode transform]) |
| 150 : node = new AssetNode._(id, transform, null); | 173 : node = new AssetNode._(id, transform, null); |
| 151 | 174 |
| 152 /// Creates a controller for an available node with the given concrete | 175 /// Creates a controller for an available node with the given concrete |
| 153 /// [asset]. | 176 /// [asset]. |
| 154 AssetNodeController.available(Asset asset, [TransformNode transform]) | 177 AssetNodeController.available(Asset asset, [TransformNode transform]) |
| 155 : node = new AssetNode._available(asset, transform, null); | 178 : node = new AssetNode._available(asset, transform, null); |
| 156 | 179 |
| 180 /// Creates a controller for a lazy node. | |
| 181 /// | |
| 182 /// For the most party, this node works like any other dirty node. However, | |
|
Bob Nystrom
2014/01/30 19:33:44
I'm always trying to maximize my party too, but he
nweiz
2014/01/31 03:43:27
Done.
| |
| 183 /// the owner of its controller isn't expected to do the work to make it | |
| 184 /// available as soon as possible like they would for a non-lazy node. | |
|
Bob Nystrom
2014/01/30 19:33:44
they -> it
TransformNodes are gender-less, not ge
nweiz
2014/01/31 03:43:27
"They" actually refers to "the owner" here, who is
| |
| 185 /// Instead, when its value is needed, [callback] will fire to indicate that | |
| 186 /// it should be made available as soon as possible. | |
| 187 /// | |
| 188 /// [callback] is guaranteed to only fire once. | |
| 189 AssetNodeController.lazy(AssetId id, void callback(), | |
| 190 [TransformNode transform]) | |
| 191 : node = new AssetNode._lazy(id, transform, null, callback); | |
| 192 | |
| 157 /// Creates a controller for a node whose initial state matches the current | 193 /// Creates a controller for a node whose initial state matches the current |
| 158 /// state of [node]. | 194 /// state of [node]. |
| 159 /// | 195 /// |
| 160 /// [AssetNode.origin] of the returned node will automatically be set to | 196 /// [AssetNode.origin] of the returned node will automatically be set to |
| 161 /// `node.origin`. | 197 /// `node.origin`. |
| 198 /// | |
| 199 /// If [node] is lazy, the returned node will also be lazy. If the returned | |
| 200 /// node is materialized, [node] will be materialized as well. | |
| 162 AssetNodeController.from(AssetNode node) | 201 AssetNodeController.from(AssetNode node) |
| 163 : node = new AssetNode._(node.id, node.transform, node.origin) { | 202 : node = new AssetNode._(node.id, node.transform, node.origin) { |
| 164 if (node.state.isAvailable) { | 203 if (node.state.isAvailable) { |
| 165 setAvailable(node.asset); | 204 setAvailable(node.asset); |
| 166 } else if (node.state.isRemoved) { | 205 } else if (node.state.isRemoved) { |
| 167 setRemoved(); | 206 setRemoved(); |
| 168 } | 207 } |
| 169 } | 208 } |
| 170 | 209 |
| 171 /// Marks the node as [AssetState.DIRTY]. | 210 /// Marks the node as [AssetState.DIRTY]. |
| 172 void setDirty() { | 211 void setDirty() { |
| 173 assert(node._state != AssetState.REMOVED); | 212 assert(node._state != AssetState.REMOVED); |
| 174 node._state = AssetState.DIRTY; | 213 node._state = AssetState.DIRTY; |
| 175 node._asset = null; | 214 node._asset = null; |
| 215 node._lazyCallback = null; | |
| 176 node._stateChangeController.add(AssetState.DIRTY); | 216 node._stateChangeController.add(AssetState.DIRTY); |
| 177 } | 217 } |
| 178 | 218 |
| 179 /// Marks the node as [AssetState.REMOVED]. | 219 /// Marks the node as [AssetState.REMOVED]. |
| 180 /// | 220 /// |
| 181 /// Once a node is marked as removed, it can't be marked as any other state. | 221 /// Once a node is marked as removed, it can't be marked as any other state. |
| 182 /// If a new asset is created with the same id, it will get a new node. | 222 /// If a new asset is created with the same id, it will get a new node. |
| 183 void setRemoved() { | 223 void setRemoved() { |
| 184 assert(node._state != AssetState.REMOVED); | 224 assert(node._state != AssetState.REMOVED); |
| 185 node._state = AssetState.REMOVED; | 225 node._state = AssetState.REMOVED; |
| 186 node._asset = null; | 226 node._asset = null; |
| 227 node._lazyCallback = null; | |
| 187 node._stateChangeController.add(AssetState.REMOVED); | 228 node._stateChangeController.add(AssetState.REMOVED); |
| 188 } | 229 } |
| 189 | 230 |
| 190 /// Marks the node as [AssetState.AVAILABLE] with the given concrete [asset]. | 231 /// Marks the node as [AssetState.AVAILABLE] with the given concrete [asset]. |
| 191 /// | 232 /// |
| 192 /// It's an error to mark an already-available node as available. It should be | 233 /// It's an error to mark an already-available node as available. It should be |
| 193 /// marked as dirty first. | 234 /// marked as dirty first. |
| 194 void setAvailable(Asset asset) { | 235 void setAvailable(Asset asset) { |
| 195 assert(asset.id == node.id); | 236 assert(asset.id == node.id); |
| 196 assert(node._state != AssetState.REMOVED); | 237 assert(node._state != AssetState.REMOVED); |
| 197 assert(node._state != AssetState.AVAILABLE); | 238 assert(node._state != AssetState.AVAILABLE); |
| 198 node._state = AssetState.AVAILABLE; | 239 node._state = AssetState.AVAILABLE; |
| 199 node._asset = asset; | 240 node._asset = asset; |
| 241 node._lazyCallback = null; | |
| 200 node._stateChangeController.add(AssetState.AVAILABLE); | 242 node._stateChangeController.add(AssetState.AVAILABLE); |
| 201 } | 243 } |
| 244 | |
| 245 /// Marks the node as [AssetState.DIRTY] and lazy. | |
| 246 /// | |
| 247 /// Lazy nodes aren't expected to have their values generated until it's | |
|
Bob Nystrom
2014/01/30 19:33:44
"it's necessary" -> "needed".
nweiz
2014/01/31 03:43:27
Done.
| |
| 248 /// necessary. Once it's necessary, [callback] will be called. [callback] is | |
| 249 /// guaranteed to be called only once. | |
| 250 /// | |
| 251 /// See also [AssetNodeController.lazy]. | |
| 252 void setLazy(void callback()) { | |
| 253 assert(node._state != AssetState.REMOVED); | |
| 254 node._state = AssetState.DIRTY; | |
| 255 node._asset = null; | |
| 256 node._lazyCallback = callback; | |
| 257 node._stateChangeController.add(AssetState.DIRTY); | |
| 258 } | |
| 202 } | 259 } |
| 203 | 260 |
| 204 // TODO(nweiz): add an error state. | 261 // TODO(nweiz): add an error state. |
| 205 /// An enum of states that an [AssetNode] can be in. | 262 /// An enum of states that an [AssetNode] can be in. |
| 206 class AssetState { | 263 class AssetState { |
| 207 /// The node has a concrete asset loaded, available, and up-to-date. The asset | 264 /// The node has a concrete asset loaded, available, and up-to-date. The asset |
| 208 /// is accessible via [AssetNode.asset]. An asset can only be marked available | 265 /// is accessible via [AssetNode.asset]. An asset can only be marked available |
| 209 /// again from the [AssetState.DIRTY] state. | 266 /// again from the [AssetState.DIRTY] state. |
| 210 static final AVAILABLE = const AssetState._("available"); | 267 static final AVAILABLE = const AssetState._("available"); |
| 211 | 268 |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 225 | 282 |
| 226 /// Whether this state is [AssetState.DIRTY]. | 283 /// Whether this state is [AssetState.DIRTY]. |
| 227 bool get isDirty => this == AssetState.DIRTY; | 284 bool get isDirty => this == AssetState.DIRTY; |
| 228 | 285 |
| 229 final String name; | 286 final String name; |
| 230 | 287 |
| 231 const AssetState._(this.name); | 288 const AssetState._(this.name); |
| 232 | 289 |
| 233 String toString() => name; | 290 String toString() => name; |
| 234 } | 291 } |
| OLD | NEW |