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

Side by Side Diff: pkg/observe/lib/src/observable.dart

Issue 51483002: fix PathObserver to avoid try+catch (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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « pkg/observe/lib/src/metadata.dart ('k') | pkg/observe/lib/src/observable_box.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 part of observe; 5 library observe.src.observable;
6
7 import 'dart:async';
8 import 'dart:collection';
9
10 // Note: ObservableProperty is in this list only for the unusual use case of
11 // dart2js without deploy tool. The deploy tool (see "transformer.dart") will
12 // add the @reflectable annotation, which makes it work with Polymer's
13 // @published.
14 @MirrorsUsed(metaTargets: const [Reflectable, ObservableProperty],
15 override: 'observe.src.observable')
16 import 'dart:mirrors';
17
18 import 'package:observe/observe.dart';
19
20 // Note: this is an internal library so we can import it from tests.
21 // TODO(jmesserly): ideally we could import this with a prefix, but it caused
22 // strange problems on the VM when I tested out the dirty-checking example
23 // above.
24 import 'dirty_check.dart';
6 25
7 /** 26 /**
8 * Represents an object with observable properties. This is used by data in 27 * Represents an object with observable properties. This is used by data in
9 * model-view architectures to notify interested parties of [changes] to the 28 * model-view architectures to notify interested parties of [changes] to the
10 * object's properties (fields or getter/setter pairs). 29 * object's properties (fields or getter/setter pairs).
11 * 30 *
12 * The interface does not require any specific technique to implement 31 * The interface does not require any specific technique to implement
13 * observability. You can implement it in the following ways: 32 * observability. You can implement it in the following ways:
14 * 33 *
15 * - extend or mixin this class, and let the application call [dirtyCheck] 34 * - extend or mixin this class, and let the application call [dirtyCheck]
16 * periodically to check for changes to your object. 35 * periodically to check for changes to your object.
17 * - extend or mixin [ChangeNotifier], and implement change notifications 36 * - extend or mixin [ChangeNotifier], and implement change notifications
18 * manually by calling [notifyPropertyChange] from your setters. 37 * manually by calling [notifyPropertyChange] from your setters.
19 * - implement this interface and provide your own implementation. 38 * - implement this interface and provide your own implementation.
20 */ 39 */
21 abstract class Observable { 40 abstract class Observable {
22 /** 41 /**
23 * Performs dirty checking of objects that inherit from [Observable]. 42 * Performs dirty checking of objects that inherit from [Observable].
24 * This scans all observed objects using mirrors and determines if any fields 43 * This scans all observed objects using mirrors and determines if any fields
25 * have changed. If they have, it delivers the changes for the object. 44 * have changed. If they have, it delivers the changes for the object.
26 */ 45 */
27 static void dirtyCheck() => dirtyCheckObservables(); 46 static void dirtyCheck() => dirtyCheckObservables();
28 47
29 StreamController _changes; 48 StreamController _changes;
30 InstanceMirror _mirror; 49 InstanceMirror _mirror;
31 50
32 Map<Symbol, Object> _values; 51 Map<Symbol, Object> _values;
33 List<ChangeRecord> _records; 52 List<ChangeRecord> _records;
34 53
35 static final _objectType = reflectClass(Object);
36
37 /** 54 /**
38 * The stream of change records to this object. Records will be delivered 55 * The stream of change records to this object. Records will be delivered
39 * asynchronously. 56 * asynchronously.
40 * 57 *
41 * [deliverChanges] can be called to force synchronous delivery. 58 * [deliverChanges] can be called to force synchronous delivery.
42 */ 59 */
43 Stream<List<ChangeRecord>> get changes { 60 Stream<List<ChangeRecord>> get changes {
44 if (_changes == null) { 61 if (_changes == null) {
45 _changes = new StreamController.broadcast(sync: true, 62 _changes = new StreamController.broadcast(sync: true,
46 onListen: _observed, onCancel: _unobserved); 63 onListen: _observed, onCancel: _unobserved);
(...skipping 10 matching lines...) Expand all
57 void _observed() { 74 void _observed() {
58 // Register this object for dirty checking purposes. 75 // Register this object for dirty checking purposes.
59 registerObservable(this); 76 registerObservable(this);
60 77
61 var mirror = reflect(this); 78 var mirror = reflect(this);
62 var values = new Map<Symbol, Object>(); 79 var values = new Map<Symbol, Object>();
63 80
64 // Note: we scan for @observable regardless of whether the base type 81 // Note: we scan for @observable regardless of whether the base type
65 // actually includes this mixin. While perhaps too inclusive, it lets us 82 // actually includes this mixin. While perhaps too inclusive, it lets us
66 // avoid complex logic that walks "with" and "implements" clauses. 83 // avoid complex logic that walks "with" and "implements" clauses.
67 for (var type = mirror.type; type != _objectType; type = type.superclass) { 84 for (var type = mirror.type; type != objectType; type = type.superclass) {
68 for (var field in type.variables.values) { 85 for (var field in type.variables.values) {
69 if (field.isFinal || field.isStatic || field.isPrivate) continue; 86 if (field.isFinal || field.isStatic || field.isPrivate) continue;
70 87
71 for (var meta in field.metadata) { 88 for (var meta in field.metadata) {
72 if (meta.reflectee is ObservableProperty) { 89 if (meta.reflectee is ObservableProperty) {
73 var name = field.simpleName; 90 var name = field.simpleName;
74 // Note: since this is a field, getting the value shouldn't execute 91 // Note: since this is a field, getting the value shouldn't execute
75 // user code, so we don't need to worry about errors. 92 // user code, so we don't need to worry about errors.
76 values[name] = mirror.getField(name).reflectee; 93 values[name] = mirror.getField(name).reflectee;
77 break; 94 break;
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
141 158
142 /** 159 /**
143 * Notify that the field [name] of this object has been changed. 160 * Notify that the field [name] of this object has been changed.
144 * 161 *
145 * The [oldValue] and [newValue] are also recorded. If the two values are 162 * The [oldValue] and [newValue] are also recorded. If the two values are
146 * equal, no change will be recorded. 163 * equal, no change will be recorded.
147 * 164 *
148 * For convenience this returns [newValue]. 165 * For convenience this returns [newValue].
149 */ 166 */
150 notifyPropertyChange(Symbol field, Object oldValue, Object newValue) 167 notifyPropertyChange(Symbol field, Object oldValue, Object newValue)
151 => _notifyPropertyChange(this, field, oldValue, newValue); 168 => notifyPropertyChangeHelper(this, field, oldValue, newValue);
152 169
153 /** 170 /**
154 * Notify observers of a change. 171 * Notify observers of a change.
155 * 172 *
156 * For most objects [Observable.notifyPropertyChange] is more convenient, but 173 * For most objects [Observable.notifyPropertyChange] is more convenient, but
157 * collections sometimes deliver other types of changes such as a 174 * collections sometimes deliver other types of changes such as a
158 * [ListChangeRecord]. 175 * [ListChangeRecord].
159 * 176 *
160 * Notes: 177 * Notes:
161 * - This is *not* required for fields if you mixin or extend [Observable], 178 * - This is *not* required for fields if you mixin or extend [Observable],
(...skipping 19 matching lines...) Expand all
181 * 198 *
182 * target.notifyChange(new PropertyChangeRecord(target, name, null, null)); 199 * target.notifyChange(new PropertyChangeRecord(target, name, null, null));
183 */ 200 */
184 @deprecated 201 @deprecated
185 void notifyProperty(Observable target, Symbol name) { 202 void notifyProperty(Observable target, Symbol name) {
186 target.notifyChange(new PropertyChangeRecord(target, name, null, null)); 203 target.notifyChange(new PropertyChangeRecord(target, name, null, null));
187 } 204 }
188 205
189 // TODO(jmesserly): remove the instance method and make this top-level method 206 // TODO(jmesserly): remove the instance method and make this top-level method
190 // public instead? 207 // public instead?
191 _notifyPropertyChange(Observable obj, Symbol field, Object oldValue, 208 // NOTE: this is not exported publically.
209 notifyPropertyChangeHelper(Observable obj, Symbol field, Object oldValue,
192 Object newValue) { 210 Object newValue) {
193 211
194 if (obj.hasObservers && oldValue != newValue) { 212 if (obj.hasObservers && oldValue != newValue) {
195 obj.notifyChange(new PropertyChangeRecord(obj, field, oldValue, newValue)); 213 obj.notifyChange(new PropertyChangeRecord(obj, field, oldValue, newValue));
196 } 214 }
197 return newValue; 215 return newValue;
198 } 216 }
217
218 // NOTE: this is not exported publically.
219 final objectType = reflectClass(Object);
OLDNEW
« no previous file with comments | « pkg/observe/lib/src/metadata.dart ('k') | pkg/observe/lib/src/observable_box.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698