Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2597)

Unified Diff: pkg/polymer_expressions/lib/src/globals.dart

Issue 71353012: Make sure 'enumerate' changes when the underlying collection changes. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | pkg/polymer_expressions/test/globals_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/polymer_expressions/lib/src/globals.dart
diff --git a/pkg/polymer_expressions/lib/src/globals.dart b/pkg/polymer_expressions/lib/src/globals.dart
index 281536df329557d2b7ecedbaf35c01262021bdd1..56836f3f4f19757d648184d87d3fa6cf26becf9f 100644
--- a/pkg/polymer_expressions/lib/src/globals.dart
+++ b/pkg/polymer_expressions/lib/src/globals.dart
@@ -10,64 +10,60 @@
// Code from https://github.com/google/quiver-dart/commit/52edc4baf37e99ff6a8f99c648b29b135fc0b880
Jennifer Messerly 2013/11/13 23:51:45 this comment seems wrong now :)
library polymer_expressions.src.globals;
-import 'dart:collection';
-import 'package:observe/observe.dart' show reflectable;
+import 'package:logging/logging.dart';
+import 'package:observe/observe.dart';
/**
* Returns an [Iterable] of [IndexedValue]s where the nth value holds the nth
* element of [iterable] and its index.
*/
-Iterable<IndexedValue> enumerate(Iterable iterable) =>
- new EnumerateIterable(iterable);
+Iterable<IndexedValue> enumerate(Iterable iterable) {
+ var i = 0;
+ var result = iterable.map((e) => new IndexedValue(i++, e));
Jennifer Messerly 2013/11/13 23:51:45 I don't think this works. It looks awfully like a
Jennifer Messerly 2013/11/13 23:53:42 original context: https://github.com/google/quiver
+ if (iterable is! ObservableList) return result;
-@reflectable class IndexedValue<V> {
- final int index;
- final V value;
-
- IndexedValue(this.index, this.value);
+ result = new ObservableList.from(result);
+ (iterable as ObservableList).listChanges.listen(
+ (changes) => _propagateChange(iterable, result, changes));
+ return result;
}
-/**
- * An [Iterable] of [IndexedValue]s where the nth value holds the nth
- * element of [iterable] and its index. See [enumerate].
- */
-// This was inspired by MappedIterable internal to Dart collections.
-class EnumerateIterable<V> extends IterableBase<IndexedValue<V>> {
- final Iterable<V> _iterable;
-
- EnumerateIterable(this._iterable);
-
- Iterator<IndexedValue<V>> get iterator =>
- new EnumerateIterator<V>(_iterable.iterator);
+class IndexedValue<V> {
Jennifer Messerly 2013/11/13 23:51:45 should mixin Observable or probably ChangeNotifier
+ @observable int index;
Jennifer Messerly 2013/11/13 23:51:45 make this immutable? so people don't accidentally
+ @reflectable final V value;
- // Length related functions are independent of the mapping.
- int get length => _iterable.length;
- bool get isEmpty => _iterable.isEmpty;
-
- // Index based lookup can be done before transforming.
- IndexedValue<V> get first => new IndexedValue<V>(0, _iterable.first);
- IndexedValue<V> get last => new IndexedValue<V>(length - 1, _iterable.last);
- IndexedValue<V> get single => new IndexedValue<V>(0, _iterable.single);
- IndexedValue<V> elementAt(int index) =>
- new IndexedValue<V>(index, _iterable.elementAt(index));
+ IndexedValue(this.index, this.value);
}
-/** The [Iterator] returned by [EnumerateIterable.iterator]. */
-class EnumerateIterator<V> extends Iterator<IndexedValue<V>> {
- final Iterator<V> _iterator;
- int _index = 0;
- IndexedValue<V> _current;
+final _logger = new Logger('polymer_expressions');
+
+void _propagateChange(ObservableList original, ObservableList target,
+ List<ListChangeRecord> changes) {
+ // TODO(sigmund): maybe we can expose ObservableList._hasListObservers so we
Jennifer Messerly 2013/11/13 23:51:45 problem is, you'd need the pair of observed/unobse
+ // can skip this work when nobody is listening?
- EnumerateIterator(this._iterator);
+ for (var change in changes) {
+ var index = change.index;
+ var added = change.addedCount;
+ var removed = change.removed.length;
+ if (index < 0 || index > target.length) {
+ _logger.error('enumerate filter seems to be in an inconsistent state. '
+ 'Please report an error at dartbug.com/new with some information '
+ 'to help us reproduce the problem.');
+ return;
+ }
+
+ // Apply the same changes on our view of the original list:
+ target.removeRange(index, index + removed);
+ for (int i = added - 1; i >= 0; i--) {
+ target.insert(index, new IndexedValue(index + i, original[index + i]));
+ }
- IndexedValue<V> get current => _current;
+ // Update indices of the later [IndexedValue]s, if necessary.
+ if (added == removed) continue;
- bool moveNext() {
- if (_iterator.moveNext()) {
- _current = new IndexedValue(_index++, _iterator.current);
- return true;
+ for (int i = index + added; i < target.length; i++) {
+ target[i].index = i;
}
- _current = null;
- return false;
}
}
« no previous file with comments | « no previous file | pkg/polymer_expressions/test/globals_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698