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 observe.src.list_path_observer; | 5 library observe.src.list_path_observer; |
6 | 6 |
7 import 'dart:async'; | 7 import 'dart:async'; |
8 import 'package:observe/observe.dart'; | 8 import 'package:observe/observe.dart'; |
9 | 9 |
10 // Inspired by ArrayReduction at: | 10 // Inspired by ArrayReduction at: |
11 // https://raw.github.com/rafaelw/ChangeSummary/master/util/array_reduction.js | 11 // https://raw.github.com/rafaelw/ChangeSummary/master/util/array_reduction.js |
12 // The main difference is we support anything on the rich Dart Iterable API. | 12 // The main difference is we support anything on the rich Dart Iterable API. |
13 | 13 |
14 /// Observes a path starting from each item in the list. | 14 /// Observes a path starting from each item in the list. |
15 @deprecated | 15 @deprecated |
16 class ListPathObserver<E, P> extends ChangeNotifier { | 16 class ListPathObserver<E, P> extends ChangeNotifier { |
17 final ObservableList<E> list; | 17 final ObservableList<E> list; |
18 final String _itemPath; | 18 final String _itemPath; |
19 final List<PathObserver> _observers = <PathObserver>[]; | 19 final List<PathObserver> _observers = <PathObserver>[]; |
20 StreamSubscription _sub; | 20 StreamSubscription _sub; |
21 bool _scheduled = false; | 21 bool _scheduled = false; |
22 Iterable<P> _value; | 22 Iterable<P> _value; |
23 | 23 |
24 ListPathObserver(this.list, String path) | 24 ListPathObserver(this.list, String path) : _itemPath = path { |
25 : _itemPath = path { | |
26 | |
27 // TODO(jmesserly): delay observation until we are observed. | 25 // TODO(jmesserly): delay observation until we are observed. |
28 _sub = list.listChanges.listen((records) { | 26 _sub = list.listChanges.listen((records) { |
29 for (var record in records) { | 27 for (var record in records) { |
30 _observeItems(record.addedCount - record.removed.length); | 28 _observeItems(record.addedCount - record.removed.length); |
31 } | 29 } |
32 _scheduleReduce(null); | 30 _scheduleReduce(null); |
33 }); | 31 }); |
34 | 32 |
35 _observeItems(list.length); | 33 _observeItems(list.length); |
36 _reduce(); | 34 _reduce(); |
37 } | 35 } |
38 | 36 |
39 @reflectable Iterable<P> get value => _value; | 37 @reflectable Iterable<P> get value => _value; |
40 | 38 |
41 void dispose() { | 39 void dispose() { |
42 if (_sub != null) _sub.cancel(); | 40 if (_sub != null) _sub.cancel(); |
43 _observers.forEach((o) => o.close()); | 41 _observers.forEach((o) => o.close()); |
44 _observers.clear(); | 42 _observers.clear(); |
45 } | 43 } |
46 | 44 |
47 void _reduce() { | 45 void _reduce() { |
48 _scheduled = false; | 46 _scheduled = false; |
49 var newValue = _observers.map((o) => o.value); | 47 var newValue = _observers.map((o) => o.value); |
50 _value = notifyPropertyChange(#value, _value, newValue); | 48 _value = notifyPropertyChange(#value, _value, newValue) as Iterable<P>; |
vsm
2016/01/22 16:47:15
Perhaps we need to be more permissive on casts fro
Jennifer Messerly
2016/01/22 17:45:00
generic methods FTW!
notifyPropertyChange<T>(
vsm
2016/01/22 18:49:22
Done.
| |
51 } | 49 } |
52 | 50 |
53 void _scheduleReduce(_) { | 51 void _scheduleReduce(_) { |
54 if (_scheduled) return; | 52 if (_scheduled) return; |
55 _scheduled = true; | 53 _scheduled = true; |
56 scheduleMicrotask(_reduce); | 54 scheduleMicrotask(_reduce); |
57 } | 55 } |
58 | 56 |
59 void _observeItems(int lengthAdjust) { | 57 void _observeItems(int lengthAdjust) { |
60 if (lengthAdjust > 0) { | 58 if (lengthAdjust > 0) { |
61 for (int i = 0; i < lengthAdjust; i++) { | 59 for (int i = 0; i < lengthAdjust; i++) { |
62 int len = _observers.length; | 60 int len = _observers.length; |
63 var pathObs = new PathObserver(list, '[$len].$_itemPath'); | 61 var pathObs = new PathObserver(list, '[$len].$_itemPath'); |
64 pathObs.open(_scheduleReduce); | 62 pathObs.open(_scheduleReduce); |
65 _observers.add(pathObs); | 63 _observers.add(pathObs); |
66 } | 64 } |
67 } else if (lengthAdjust < 0) { | 65 } else if (lengthAdjust < 0) { |
68 for (int i = 0; i < -lengthAdjust; i++) { | 66 for (int i = 0; i < -lengthAdjust; i++) { |
69 _observers.removeLast().close(); | 67 _observers.removeLast().close(); |
70 } | 68 } |
71 } | 69 } |
72 } | 70 } |
73 } | 71 } |
OLD | NEW |