| 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 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 89 | 89 |
| 90 /// Calls [callback] when the node's asset is removed. | 90 /// Calls [callback] when the node's asset is removed. |
| 91 /// | 91 /// |
| 92 /// If the asset is already removed when this is called, it calls [callback] | 92 /// If the asset is already removed when this is called, it calls [callback] |
| 93 /// synchronously. | 93 /// synchronously. |
| 94 /// | 94 /// |
| 95 /// The return value of [callback] is piped to the returned Future. | 95 /// The return value of [callback] is piped to the returned Future. |
| 96 Future whenRemoved(callback()) => | 96 Future whenRemoved(callback()) => |
| 97 _waitForState((state) => state.isRemoved, (_) => callback()); | 97 _waitForState((state) => state.isRemoved, (_) => callback()); |
| 98 | 98 |
| 99 /// Runs [callback] repeatedly until the node's asset has maintained the same | 99 /// Returns a [Future] that completes when [state] changes from its current |
| 100 /// value for the duration. | 100 /// value to any other value. |
| 101 /// | 101 /// |
| 102 /// This will run [callback] as soon as the asset is available (synchronously | 102 /// The returned [Future] will contain the new state. |
| 103 /// if it's available immediately). If the [state] changes at all while | 103 Future<AssetState> whenStateChanges() { |
| 104 /// waiting for the Future returned by [callback] to complete, it will be | 104 var startState = state; |
| 105 /// re-run as soon as it completes and the asset is available again. This will | 105 return _waitForState((state) => state != startState, (state) => state); |
| 106 /// continue until [state] doesn't change at all. | |
| 107 /// | |
| 108 /// If this asset is removed, this will throw an [AssetNotFoundException] as | |
| 109 /// soon as [callback]'s Future is finished running. | |
| 110 Future tryUntilStable(Future callback(Asset asset)) { | |
| 111 return whenAvailable((asset) { | |
| 112 var modifiedDuringCallback = false; | |
| 113 var subscription; | |
| 114 subscription = onStateChange.listen((_) { | |
| 115 modifiedDuringCallback = true; | |
| 116 subscription.cancel(); | |
| 117 }); | |
| 118 | |
| 119 return callback(asset).then((result) { | |
| 120 subscription.cancel(); | |
| 121 | |
| 122 // If the asset was modified at all while running the callback, the | |
| 123 // result was invalid and we should try again. | |
| 124 if (modifiedDuringCallback) return tryUntilStable(callback); | |
| 125 return result; | |
| 126 }); | |
| 127 }); | |
| 128 } | 106 } |
| 129 | 107 |
| 130 /// Calls [callback] as soon as the node is in a state that matches [test]. | 108 /// Calls [callback] as soon as the node is in a state that matches [test]. |
| 131 /// | 109 /// |
| 132 /// [callback] is called synchronously if this is already in such a state. | 110 /// [callback] is called synchronously if this is already in such a state. |
| 133 /// | 111 /// |
| 134 /// The return value of [callback] is piped to the returned Future. | 112 /// The return value of [callback] is piped to the returned Future. |
| 135 Future _waitForState(bool test(AssetState state), | 113 Future _waitForState(bool test(AssetState state), |
| 136 callback(AssetState state)) { | 114 callback(AssetState state)) { |
| 137 if (test(state)) return syncFuture(() => callback(state)); | 115 if (test(state)) return syncFuture(() => callback(state)); |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 287 | 265 |
| 288 /// Whether this state is [AssetState.DIRTY]. | 266 /// Whether this state is [AssetState.DIRTY]. |
| 289 bool get isDirty => this == AssetState.DIRTY; | 267 bool get isDirty => this == AssetState.DIRTY; |
| 290 | 268 |
| 291 final String name; | 269 final String name; |
| 292 | 270 |
| 293 const AssetState._(this.name); | 271 const AssetState._(this.name); |
| 294 | 272 |
| 295 String toString() => name; | 273 String toString() => name; |
| 296 } | 274 } |
| OLD | NEW |