| 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.asset_node; | 5 library barback.asset.asset_node; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 | 8 |
| 9 import '../errors.dart'; | 9 import '../errors.dart'; |
| 10 import '../graph/transform_node.dart'; | 10 import '../graph/transform_node.dart'; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 52 /// The callback to be called to notify this asset node's creator that the | 52 /// The callback to be called to notify this asset node's creator that the |
| 53 /// concrete asset should be generated. | 53 /// concrete asset should be generated. |
| 54 /// | 54 /// |
| 55 /// This is null for non-lazy asset nodes (see [AssetNodeController.lazy]). | 55 /// This is null for non-lazy asset nodes (see [AssetNodeController.lazy]). |
| 56 /// Once this is called, it's set to null and [this] is no longer considered | 56 /// Once this is called, it's set to null and [this] is no longer considered |
| 57 /// lazy. | 57 /// lazy. |
| 58 Function _lazyCallback; | 58 Function _lazyCallback; |
| 59 | 59 |
| 60 /// Whether this node is lazy, meaning that [force] must be called to | 60 /// Whether this node is lazy, meaning that [force] must be called to |
| 61 /// guarantee that it will eventually become available. | 61 /// guarantee that it will eventually become available. |
| 62 bool get isLazy => _lazyCallback != null || | 62 bool get isLazy => |
| 63 (_origin != null && _origin.isLazy); | 63 _lazyCallback != null || (_origin != null && _origin.isLazy); |
| 64 | 64 |
| 65 /// A broadcast stream that emits an event whenever the node changes state. | 65 /// A broadcast stream that emits an event whenever the node changes state. |
| 66 /// | 66 /// |
| 67 /// This stream is synchronous to ensure that when a source asset is modified | 67 /// This stream is synchronous to ensure that when a source asset is modified |
| 68 /// or removed, the appropriate portion of the asset graph is dirtied before | 68 /// or removed, the appropriate portion of the asset graph is dirtied before |
| 69 /// any [Barback.getAssetById] calls emit newly-incorrect values. | 69 /// any [Barback.getAssetById] calls emit newly-incorrect values. |
| 70 Stream<AssetState> get onStateChange => _stateChangeController.stream; | 70 Stream<AssetState> get onStateChange => _stateChangeController.stream; |
| 71 | 71 |
| 72 /// This is synchronous so that a source being updated will always be | 72 /// This is synchronous so that a source being updated will always be |
| 73 /// propagated through the build graph before anything that depends on it is | 73 /// propagated through the build graph before anything that depends on it is |
| 74 /// requested. | 74 /// requested. |
| 75 final _stateChangeController = | 75 final _stateChangeController = |
| 76 new StreamController<AssetState>.broadcast(sync: true); | 76 new StreamController<AssetState>.broadcast(sync: true); |
| 77 | 77 |
| 78 /// Calls [callback] when the node's asset is available. | 78 /// Calls [callback] when the node's asset is available. |
| 79 /// | 79 /// |
| 80 /// If the asset is currently available, this calls [callback] synchronously | 80 /// If the asset is currently available, this calls [callback] synchronously |
| 81 /// to ensure that the asset is still available. | 81 /// to ensure that the asset is still available. |
| 82 /// | 82 /// |
| 83 /// The return value of [callback] is piped to the returned Future. If the | 83 /// The return value of [callback] is piped to the returned Future. If the |
| 84 /// asset is removed before becoming available, the returned future will throw | 84 /// asset is removed before becoming available, the returned future will throw |
| 85 /// an [AssetNotFoundException]. | 85 /// an [AssetNotFoundException]. |
| 86 Future/*<T>*/ whenAvailable/*<T>*/(/*=T*/ callback(Asset asset)) { | 86 Future<T> whenAvailable<T>(T callback(Asset asset)) { |
| 87 return _waitForState((state) => state.isAvailable || state.isRemoved, | 87 return _waitForState((state) => state.isAvailable || state.isRemoved, |
| 88 (state) { | 88 (state) { |
| 89 if (state.isRemoved) throw new AssetNotFoundException(id); | 89 if (state.isRemoved) throw new AssetNotFoundException(id); |
| 90 return callback(asset); | 90 return callback(asset); |
| 91 }); | 91 }); |
| 92 } | 92 } |
| 93 | 93 |
| 94 /// Calls [callback] when the node's asset is removed. | 94 /// Calls [callback] when the node's asset is removed. |
| 95 /// | 95 /// |
| 96 /// If the asset is already removed when this is called, it calls [callback] | 96 /// If the asset is already removed when this is called, it calls [callback] |
| 97 /// synchronously. | 97 /// synchronously. |
| 98 /// | 98 /// |
| 99 /// The return value of [callback] is piped to the returned Future. | 99 /// The return value of [callback] is piped to the returned Future. |
| 100 Future whenRemoved(callback()) => | 100 Future whenRemoved(callback()) => |
| 101 _waitForState((state) => state.isRemoved, (_) => callback()); | 101 _waitForState((state) => state.isRemoved, (_) => callback()); |
| 102 | 102 |
| 103 /// Returns a [Future] that completes when [state] changes from its current | 103 /// Returns a [Future] that completes when [state] changes from its current |
| 104 /// value to any other value. | 104 /// value to any other value. |
| 105 /// | 105 /// |
| 106 /// The returned [Future] will contain the new state. | 106 /// The returned [Future] will contain the new state. |
| 107 Future<AssetState> whenStateChanges() { | 107 Future<AssetState> whenStateChanges() { |
| 108 var startState = state; | 108 var startState = state; |
| 109 return _waitForState((state) => state != startState, (state) => state); | 109 return _waitForState((state) => state != startState, (state) => state); |
| 110 } | 110 } |
| 111 | 111 |
| 112 /// Calls [callback] as soon as the node is in a state that matches [test]. | 112 /// Calls [callback] as soon as the node is in a state that matches [test]. |
| 113 /// | 113 /// |
| 114 /// [callback] is called synchronously if this is already in such a state. | 114 /// [callback] is called synchronously if this is already in such a state. |
| 115 /// | 115 /// |
| 116 /// The return value of [callback] is piped to the returned Future. | 116 /// The return value of [callback] is piped to the returned Future. |
| 117 Future/*<T>*/ _waitForState/*<T>*/(bool test(AssetState state), | 117 Future<T> _waitForState<T>( |
| 118 /*=T*/ callback(AssetState state)) { | 118 bool test(AssetState state), T callback(AssetState state)) { |
| 119 if (test(state)) return new Future.sync(() => callback(state)); | 119 if (test(state)) return new Future.sync(() => callback(state)); |
| 120 return onStateChange.firstWhere(test).then((_) => callback(state)); | 120 return onStateChange.firstWhere(test).then((_) => callback(state)); |
| 121 } | 121 } |
| 122 | 122 |
| 123 AssetNode._(this.id, this._transform, this._origin) | 123 AssetNode._(this.id, this._transform, this._origin) |
| 124 : _state = AssetState.RUNNING; | 124 : _state = AssetState.RUNNING; |
| 125 | 125 |
| 126 AssetNode._available(Asset asset, this._transform, this._origin) | 126 AssetNode._available(Asset asset, this._transform, this._origin) |
| 127 : id = asset.id, | 127 : id = asset.id, |
| 128 _asset = asset, | 128 _asset = asset, |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 165 /// Creates a controller for a lazy node. | 165 /// Creates a controller for a lazy node. |
| 166 /// | 166 /// |
| 167 /// For the most part, this node works like any other dirty node. However, the | 167 /// For the most part, this node works like any other dirty node. However, the |
| 168 /// owner of its controller isn't expected to do the work to make it available | 168 /// owner of its controller isn't expected to do the work to make it available |
| 169 /// as soon as possible like they would for a non-lazy node. Instead, when its | 169 /// as soon as possible like they would for a non-lazy node. Instead, when its |
| 170 /// value is needed, [callback] will fire to indicate that it should be made | 170 /// value is needed, [callback] will fire to indicate that it should be made |
| 171 /// available as soon as possible. | 171 /// available as soon as possible. |
| 172 /// | 172 /// |
| 173 /// [callback] is guaranteed to only fire once. | 173 /// [callback] is guaranteed to only fire once. |
| 174 AssetNodeController.lazy(AssetId id, void callback(), | 174 AssetNodeController.lazy(AssetId id, void callback(), |
| 175 [TransformNode transform]) | 175 [TransformNode transform]) |
| 176 : node = new AssetNode._lazy(id, transform, null, callback); | 176 : node = new AssetNode._lazy(id, transform, null, callback); |
| 177 | 177 |
| 178 /// Creates a controller for a node whose initial state matches the current | 178 /// Creates a controller for a node whose initial state matches the current |
| 179 /// state of [node]. | 179 /// state of [node]. |
| 180 /// | 180 /// |
| 181 /// [AssetNode.origin] of the returned node will automatically be set to | 181 /// [AssetNode.origin] of the returned node will automatically be set to |
| 182 /// `node.origin`. | 182 /// `node.origin`. |
| 183 /// | 183 /// |
| 184 /// If [node] is lazy, the returned node will also be lazy. | 184 /// If [node] is lazy, the returned node will also be lazy. |
| 185 AssetNodeController.from(AssetNode node) | 185 AssetNodeController.from(AssetNode node) |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 273 | 273 |
| 274 /// Whether this state is [AssetState.RUNNING]. | 274 /// Whether this state is [AssetState.RUNNING]. |
| 275 bool get isDirty => this == AssetState.RUNNING; | 275 bool get isDirty => this == AssetState.RUNNING; |
| 276 | 276 |
| 277 final String name; | 277 final String name; |
| 278 | 278 |
| 279 const AssetState._(this.name); | 279 const AssetState._(this.name); |
| 280 | 280 |
| 281 String toString() => name; | 281 String toString() => name; |
| 282 } | 282 } |
| OLD | NEW |