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 |