| 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 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 115 /// [callback] is called synchronously if this is already in such a state. | 115 /// [callback] is called synchronously if this is already in such a state. |
| 116 /// | 116 /// |
| 117 /// The return value of [callback] is piped to the returned Future. | 117 /// The return value of [callback] is piped to the returned Future. |
| 118 Future _waitForState(bool test(AssetState state), | 118 Future _waitForState(bool test(AssetState state), |
| 119 callback(AssetState state)) { | 119 callback(AssetState state)) { |
| 120 if (test(state)) return syncFuture(() => callback(state)); | 120 if (test(state)) return syncFuture(() => callback(state)); |
| 121 return onStateChange.firstWhere(test).then((_) => callback(state)); | 121 return onStateChange.firstWhere(test).then((_) => callback(state)); |
| 122 } | 122 } |
| 123 | 123 |
| 124 AssetNode._(this.id, this._transform, this._origin) | 124 AssetNode._(this.id, this._transform, this._origin) |
| 125 : _state = AssetState.DIRTY; | 125 : _state = AssetState.RUNNING; |
| 126 | 126 |
| 127 AssetNode._available(Asset asset, this._transform, this._origin) | 127 AssetNode._available(Asset asset, this._transform, this._origin) |
| 128 : id = asset.id, | 128 : id = asset.id, |
| 129 _asset = asset, | 129 _asset = asset, |
| 130 _state = AssetState.AVAILABLE; | 130 _state = AssetState.AVAILABLE; |
| 131 | 131 |
| 132 AssetNode._lazy(this.id, this._transform, this._origin, this._lazyCallback) | 132 AssetNode._lazy(this.id, this._transform, this._origin, this._lazyCallback) |
| 133 : _state = AssetState.DIRTY; | 133 : _state = AssetState.RUNNING; |
| 134 | 134 |
| 135 /// If [this] is lazy, force it to generate a concrete asset; otherwise, do | 135 /// If [this] is lazy, force it to generate a concrete asset; otherwise, do |
| 136 /// nothing. | 136 /// nothing. |
| 137 /// | 137 /// |
| 138 /// See [AssetNodeController.lazy]. | 138 /// See [AssetNodeController.lazy]. |
| 139 void force() { | 139 void force() { |
| 140 if (_origin != null) { | 140 if (_origin != null) { |
| 141 _origin.force(); | 141 _origin.force(); |
| 142 } else if (_lazyCallback != null) { | 142 } else if (_lazyCallback != null) { |
| 143 _lazyCallback(); | 143 _lazyCallback(); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 186 /// If [node] is lazy, the returned node will also be lazy. | 186 /// If [node] is lazy, the returned node will also be lazy. |
| 187 AssetNodeController.from(AssetNode node) | 187 AssetNodeController.from(AssetNode node) |
| 188 : node = new AssetNode._(node.id, node.transform, node.origin) { | 188 : node = new AssetNode._(node.id, node.transform, node.origin) { |
| 189 if (node.state.isAvailable) { | 189 if (node.state.isAvailable) { |
| 190 setAvailable(node.asset); | 190 setAvailable(node.asset); |
| 191 } else if (node.state.isRemoved) { | 191 } else if (node.state.isRemoved) { |
| 192 setRemoved(); | 192 setRemoved(); |
| 193 } | 193 } |
| 194 } | 194 } |
| 195 | 195 |
| 196 /// Marks the node as [AssetState.DIRTY]. | 196 /// Marks the node as [AssetState.RUNNING]. |
| 197 void setDirty() { | 197 void setDirty() { |
| 198 assert(node._state != AssetState.REMOVED); | 198 assert(node._state != AssetState.REMOVED); |
| 199 node._asset = null; | 199 node._asset = null; |
| 200 node._lazyCallback = null; | 200 node._lazyCallback = null; |
| 201 | 201 |
| 202 // Don't re-emit a dirty event to avoid cases where we try to dispatch an | 202 // Don't re-emit a dirty event to avoid cases where we try to dispatch an |
| 203 // event while handling another event (e.g. an output is marked lazy, which | 203 // event while handling another event (e.g. an output is marked lazy, which |
| 204 // causes it to be forced, which causes it to be marked dirty). | 204 // causes it to be forced, which causes it to be marked dirty). |
| 205 if (node._state.isDirty) return; | 205 if (node._state.isDirty) return; |
| 206 node._state = AssetState.DIRTY; | 206 node._state = AssetState.RUNNING; |
| 207 node._stateChangeController.add(AssetState.DIRTY); | 207 node._stateChangeController.add(AssetState.RUNNING); |
| 208 } | 208 } |
| 209 | 209 |
| 210 /// Marks the node as [AssetState.REMOVED]. | 210 /// Marks the node as [AssetState.REMOVED]. |
| 211 /// | 211 /// |
| 212 /// Once a node is marked as removed, it can't be marked as any other state. | 212 /// Once a node is marked as removed, it can't be marked as any other state. |
| 213 /// If a new asset is created with the same id, it will get a new node. | 213 /// If a new asset is created with the same id, it will get a new node. |
| 214 void setRemoved() { | 214 void setRemoved() { |
| 215 assert(node._state != AssetState.REMOVED); | 215 assert(node._state != AssetState.REMOVED); |
| 216 node._state = AssetState.REMOVED; | 216 node._state = AssetState.REMOVED; |
| 217 node._asset = null; | 217 node._asset = null; |
| 218 node._lazyCallback = null; | 218 node._lazyCallback = null; |
| 219 node._stateChangeController.add(AssetState.REMOVED); | 219 node._stateChangeController.add(AssetState.REMOVED); |
| 220 } | 220 } |
| 221 | 221 |
| 222 /// Marks the node as [AssetState.AVAILABLE] with the given concrete [asset]. | 222 /// Marks the node as [AssetState.AVAILABLE] with the given concrete [asset]. |
| 223 /// | 223 /// |
| 224 /// It's an error to mark an already-available node as available. It should be | 224 /// It's an error to mark an already-available node as available. It should be |
| 225 /// marked as dirty first. | 225 /// marked as dirty first. |
| 226 void setAvailable(Asset asset) { | 226 void setAvailable(Asset asset) { |
| 227 assert(asset.id == node.id); | 227 assert(asset.id == node.id); |
| 228 assert(node._state != AssetState.REMOVED); | 228 assert(node._state != AssetState.REMOVED); |
| 229 assert(node._state != AssetState.AVAILABLE); | 229 assert(node._state != AssetState.AVAILABLE); |
| 230 node._state = AssetState.AVAILABLE; | 230 node._state = AssetState.AVAILABLE; |
| 231 node._asset = asset; | 231 node._asset = asset; |
| 232 node._lazyCallback = null; | 232 node._lazyCallback = null; |
| 233 node._stateChangeController.add(AssetState.AVAILABLE); | 233 node._stateChangeController.add(AssetState.AVAILABLE); |
| 234 } | 234 } |
| 235 | 235 |
| 236 /// Marks the node as [AssetState.DIRTY] and lazy. | 236 /// Marks the node as [AssetState.RUNNING] and lazy. |
| 237 /// | 237 /// |
| 238 /// Lazy nodes aren't expected to have their values generated until needed. | 238 /// Lazy nodes aren't expected to have their values generated until needed. |
| 239 /// Once it's necessary, [callback] will be called. [callback] is guaranteed | 239 /// Once it's necessary, [callback] will be called. [callback] is guaranteed |
| 240 /// to be called only once. | 240 /// to be called only once. |
| 241 /// | 241 /// |
| 242 /// See also [AssetNodeController.lazy]. | 242 /// See also [AssetNodeController.lazy]. |
| 243 void setLazy(void callback()) { | 243 void setLazy(void callback()) { |
| 244 assert(node._state != AssetState.REMOVED); | 244 assert(node._state != AssetState.REMOVED); |
| 245 node._state = AssetState.DIRTY; | 245 node._state = AssetState.RUNNING; |
| 246 node._asset = null; | 246 node._asset = null; |
| 247 node._lazyCallback = callback; | 247 node._lazyCallback = callback; |
| 248 node._stateChangeController.add(AssetState.DIRTY); | 248 node._stateChangeController.add(AssetState.RUNNING); |
| 249 } | 249 } |
| 250 | 250 |
| 251 String toString() => "controller for $node"; | 251 String toString() => "controller for $node"; |
| 252 } | 252 } |
| 253 | 253 |
| 254 // TODO(nweiz): add an error state. | 254 // TODO(nweiz): add an error state. |
| 255 /// An enum of states that an [AssetNode] can be in. | 255 /// An enum of states that an [AssetNode] can be in. |
| 256 class AssetState { | 256 class AssetState { |
| 257 /// The node has a concrete asset loaded, available, and up-to-date. The asset | 257 /// The node has a concrete asset loaded, available, and up-to-date. The asset |
| 258 /// is accessible via [AssetNode.asset]. An asset can only be marked available | 258 /// is accessible via [AssetNode.asset]. An asset can only be marked available |
| 259 /// again from the [AssetState.DIRTY] state. | 259 /// again from the [AssetState.RUNNING] state. |
| 260 static final AVAILABLE = const AssetState._("available"); | 260 static final AVAILABLE = const AssetState._("available"); |
| 261 | 261 |
| 262 /// The asset is no longer available, possibly for good. A removed asset will | 262 /// The asset is no longer available, possibly for good. A removed asset will |
| 263 /// never enter another state. | 263 /// never enter another state. |
| 264 static final REMOVED = const AssetState._("removed"); | 264 static final REMOVED = const AssetState._("removed"); |
| 265 | 265 |
| 266 /// The asset will exist in the future (unless it's removed), but the concrete | 266 /// The asset will exist in the future (unless it's removed), but the concrete |
| 267 /// asset is not yet available. | 267 /// asset is not yet available. |
| 268 static final DIRTY = const AssetState._("dirty"); | 268 static final RUNNING = const AssetState._("dirty"); |
| 269 | 269 |
| 270 /// Whether this state is [AssetState.AVAILABLE]. | 270 /// Whether this state is [AssetState.AVAILABLE]. |
| 271 bool get isAvailable => this == AssetState.AVAILABLE; | 271 bool get isAvailable => this == AssetState.AVAILABLE; |
| 272 | 272 |
| 273 /// Whether this state is [AssetState.REMOVED]. | 273 /// Whether this state is [AssetState.REMOVED]. |
| 274 bool get isRemoved => this == AssetState.REMOVED; | 274 bool get isRemoved => this == AssetState.REMOVED; |
| 275 | 275 |
| 276 /// Whether this state is [AssetState.DIRTY]. | 276 /// Whether this state is [AssetState.RUNNING]. |
| 277 bool get isDirty => this == AssetState.DIRTY; | 277 bool get isDirty => this == AssetState.RUNNING; |
| 278 | 278 |
| 279 final String name; | 279 final String name; |
| 280 | 280 |
| 281 const AssetState._(this.name); | 281 const AssetState._(this.name); |
| 282 | 282 |
| 283 String toString() => name; | 283 String toString() => name; |
| 284 } | 284 } |
| OLD | NEW |