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

Side by Side Diff: packages/observable/lib/src/observable_map.dart

Issue 2989763002: Update charted to 0.4.8 and roll (Closed)
Patch Set: Removed Cutch from list of reviewers Created 3 years, 4 months 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, 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.observable_map; 5 library observable.src.observable_map;
6 6
7 import 'dart:collection'; 7 import 'dart:collection';
8 import 'package:observe/observe.dart';
9 8
9 import 'change_record.dart' show ChangeRecord;
10 import 'observable.dart' show Observable;
11 import 'property_change_record.dart' show PropertyChangeRecord;
10 12
11 // TODO(jmesserly): this needs to be faster. We currently require multiple 13 // TODO(jmesserly): this needs to be faster. We currently require multiple
12 // lookups per key to get the old value. 14 // lookups per key to get the old value.
13 // TODO(jmesserly): this doesn't implement the precise interfaces like 15 // TODO(jmesserly): this doesn't implement the precise interfaces like
14 // LinkedHashMap, SplayTreeMap or HashMap. However it can use them for the 16 // LinkedHashMap, SplayTreeMap or HashMap. However it can use them for the
15 // backing store. 17 // backing store.
16 18
17 // TODO(jmesserly): should we summarize map changes like we do for list changes? 19 // TODO(jmesserly): should we summarize map changes like we do for list changes?
18 class MapChangeRecord<K, V> extends ChangeRecord { 20 class MapChangeRecord<K, V> extends ChangeRecord {
19 // TODO(jmesserly): we could store this more compactly if it matters, with 21 // TODO(jmesserly): we could store this more compactly if it matters, with
20 // subtypes for inserted and removed. 22 // subtypes for inserted and removed.
21 23
22 /// The map key that changed. 24 /// The map key that changed.
23 final K key; 25 final K key;
24 26
25 /// The previous value associated with this key. 27 /// The previous value associated with this key.
26 final V oldValue; 28 final V oldValue;
27 29
28 /// The new value associated with this key. 30 /// The new value associated with this key.
29 final V newValue; 31 final V newValue;
30 32
31 /// True if this key was inserted. 33 /// True if this key was inserted.
32 final bool isInsert; 34 final bool isInsert;
33 35
34 /// True if this key was removed. 36 /// True if this key was removed.
35 final bool isRemove; 37 final bool isRemove;
36 38
37 MapChangeRecord(this.key, this.oldValue, this.newValue) 39 MapChangeRecord(this.key, this.oldValue, this.newValue)
38 : isInsert = false, isRemove = false; 40 : isInsert = false,
41 isRemove = false;
39 42
40 MapChangeRecord.insert(this.key, this.newValue) 43 MapChangeRecord.insert(this.key, this.newValue)
41 : isInsert = true, isRemove = false, oldValue = null; 44 : isInsert = true,
45 isRemove = false,
46 oldValue = null;
42 47
43 MapChangeRecord.remove(this.key, this.oldValue) 48 MapChangeRecord.remove(this.key, this.oldValue)
44 : isInsert = false, isRemove = true, newValue = null; 49 : isInsert = false,
50 isRemove = true,
51 newValue = null;
45 52
46 String toString() { 53 String toString() {
47 var kind = isInsert ? 'insert' : isRemove ? 'remove' : 'set'; 54 var kind = isInsert ? 'insert' : isRemove ? 'remove' : 'set';
48 return '#<MapChangeRecord $kind $key from: $oldValue to: $newValue>'; 55 return '#<MapChangeRecord $kind $key from: $oldValue to: $newValue>';
49 } 56 }
50 } 57 }
51 58
52 /// Represents an observable map of model values. If any items are added, 59 /// Represents an observable map of model values. If any items are added,
53 /// removed, or replaced, then observers that are listening to [changes] 60 /// removed, or replaced, then observers that are listening to [changes]
54 /// will be notified. 61 /// will be notified.
55 class ObservableMap<K, V> extends ChangeNotifier implements Map<K, V> { 62 class ObservableMap<K, V> extends Observable implements Map<K, V> {
56 final Map<K, V> _map; 63 final Map<K, V> _map;
57 64
58 /// Creates an observable map. 65 /// Creates an observable map.
59 ObservableMap() : _map = new HashMap<K, V>(); 66 ObservableMap() : _map = new HashMap<K, V>();
60 67
61 /// Creates a new observable map using a [LinkedHashMap]. 68 /// Creates a new observable map using a [LinkedHashMap].
62 ObservableMap.linked() : _map = new LinkedHashMap<K, V>(); 69 ObservableMap.linked() : _map = new LinkedHashMap<K, V>();
63 70
64 /// Creates a new observable map using a [SplayTreeMap]. 71 /// Creates a new observable map using a [SplayTreeMap].
65 ObservableMap.sorted() : _map = new SplayTreeMap<K, V>(); 72 ObservableMap.sorted() : _map = new SplayTreeMap<K, V>();
66 73
67 /// Creates an observable map that contains all key value pairs of [other]. 74 /// Creates an observable map that contains all key value pairs of [other].
68 /// It will attempt to use the same backing map type if the other map is a 75 /// It will attempt to use the same backing map type if the other map is a
69 /// [LinkedHashMap], [SplayTreeMap], or [HashMap]. Otherwise it defaults to 76 /// [LinkedHashMap], [SplayTreeMap], or [HashMap]. Otherwise it defaults to
70 /// [HashMap]. 77 /// [HashMap].
71 /// 78 ///
72 /// Note this will perform a shallow conversion. If you want a deep conversion 79 /// Note this will perform a shallow conversion. If you want a deep conversion
73 /// you should use [toObservable]. 80 /// you should use [toObservable].
74 factory ObservableMap.from(Map<K, V> other) { 81 factory ObservableMap.from(Map<K, V> other) {
75 return new ObservableMap<K, V>.createFromType(other)..addAll(other); 82 return new ObservableMap<K, V>.createFromType(other)..addAll(other);
76 } 83 }
77 84
78 /// Like [ObservableMap.from], but creates an empty map. 85 /// Like [ObservableMap.from], but creates an empty map.
79 factory ObservableMap.createFromType(Map<K, V> other) { 86 factory ObservableMap.createFromType(Map<K, V> other) {
80 ObservableMap result; 87 ObservableMap<K, V> result;
81 if (other is SplayTreeMap) { 88 if (other is SplayTreeMap) {
82 result = new ObservableMap<K, V>.sorted(); 89 result = new ObservableMap<K, V>.sorted();
83 } else if (other is LinkedHashMap) { 90 } else if (other is LinkedHashMap) {
84 result = new ObservableMap<K, V>.linked(); 91 result = new ObservableMap<K, V>.linked();
85 } else { 92 } else {
86 result = new ObservableMap<K, V>(); 93 result = new ObservableMap<K, V>();
87 } 94 }
88 return result; 95 return result;
89 } 96 }
90 97
91 @reflectable Iterable<K> get keys => _map.keys; 98 Iterable<K> get keys => _map.keys;
92 99
93 @reflectable Iterable<V> get values => _map.values; 100 Iterable<V> get values => _map.values;
94 101
95 @reflectable int get length =>_map.length; 102 int get length => _map.length;
96 103
97 @reflectable bool get isEmpty => length == 0; 104 bool get isEmpty => length == 0;
98 105
99 @reflectable bool get isNotEmpty => !isEmpty; 106 bool get isNotEmpty => !isEmpty;
100 107
101 @reflectable bool containsValue(Object value) => _map.containsValue(value); 108 bool containsValue(Object value) => _map.containsValue(value);
102 109
103 @reflectable bool containsKey(Object key) => _map.containsKey(key); 110 bool containsKey(Object key) => _map.containsKey(key);
104 111
105 @reflectable V operator [](Object key) => _map[key]; 112 V operator [](Object key) => _map[key];
106 113
107 @reflectable void operator []=(K key, V value) { 114 void operator []=(K key, V value) {
108 if (!hasObservers) { 115 if (!hasObservers) {
109 _map[key] = value; 116 _map[key] = value;
110 return; 117 return;
111 } 118 }
112 119
113 int len = _map.length; 120 int len = _map.length;
114 V oldValue = _map[key]; 121 V oldValue = _map[key];
115 122
116 _map[key] = value; 123 _map[key] = value;
117 124
118 if (len != _map.length) { 125 if (len != _map.length) {
119 notifyPropertyChange(#length, len, _map.length); 126 notifyPropertyChange(#length, len, _map.length);
120 notifyChange(new MapChangeRecord.insert(key, value)); 127 notifyChange(new MapChangeRecord.insert(key, value));
121 _notifyKeysValuesChanged(); 128 _notifyKeysValuesChanged();
122 } else if (oldValue != value) { 129 } else if (oldValue != value) {
123 notifyChange(new MapChangeRecord(key, oldValue, value)); 130 notifyChange(new MapChangeRecord(key, oldValue, value));
124 _notifyValuesChanged(); 131 _notifyValuesChanged();
125 } 132 }
126 } 133 }
127 134
128 void addAll(Map<K, V> other) { 135 void addAll(Map<K, V> other) {
129 other.forEach((K key, V value) { this[key] = value; }); 136 other.forEach((K key, V value) {
137 this[key] = value;
138 });
130 } 139 }
131 140
132 V putIfAbsent(K key, V ifAbsent()) { 141 V putIfAbsent(K key, V ifAbsent()) {
133 int len = _map.length; 142 int len = _map.length;
134 V result = _map.putIfAbsent(key, ifAbsent); 143 V result = _map.putIfAbsent(key, ifAbsent);
135 if (hasObservers && len != _map.length) { 144 if (hasObservers && len != _map.length) {
136 notifyPropertyChange(#length, len, _map.length); 145 notifyPropertyChange(#length, len, _map.length);
137 notifyChange(new MapChangeRecord.insert(key, result)); 146 notifyChange(new MapChangeRecord.insert(key, result));
138 _notifyKeysValuesChanged(); 147 _notifyKeysValuesChanged();
139 } 148 }
140 return result; 149 return result;
141 } 150 }
142 151
143 V remove(Object key) { 152 V remove(Object key) {
144 int len = _map.length; 153 int len = _map.length;
145 V result = _map.remove(key); 154 V result = _map.remove(key);
146 if (hasObservers && len != _map.length) { 155 if (hasObservers && len != _map.length) {
147 notifyChange(new MapChangeRecord.remove(key, result)); 156 notifyChange(new MapChangeRecord.remove(key, result));
148 notifyPropertyChange(#length, len, _map.length); 157 notifyPropertyChange(#length, len, _map.length);
149 _notifyKeysValuesChanged(); 158 _notifyKeysValuesChanged();
150 } 159 }
151 return result; 160 return result;
152 } 161 }
153 162
154 void clear() { 163 void clear() {
155 int len = _map.length; 164 int len = _map.length;
(...skipping 15 matching lines...) Expand all
171 // But this should fix "keys" and "values" in templates with minimal overhead. 180 // But this should fix "keys" and "values" in templates with minimal overhead.
172 void _notifyKeysValuesChanged() { 181 void _notifyKeysValuesChanged() {
173 notifyChange(new PropertyChangeRecord(this, #keys, null, null)); 182 notifyChange(new PropertyChangeRecord(this, #keys, null, null));
174 _notifyValuesChanged(); 183 _notifyValuesChanged();
175 } 184 }
176 185
177 void _notifyValuesChanged() { 186 void _notifyValuesChanged() {
178 notifyChange(new PropertyChangeRecord(this, #values, null, null)); 187 notifyChange(new PropertyChangeRecord(this, #values, null, null));
179 } 188 }
180 } 189 }
OLDNEW
« no previous file with comments | « packages/observable/lib/src/observable_list.dart ('k') | packages/observable/lib/src/property_change_record.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698