| OLD | NEW | 
|---|
|  | (Empty) | 
| 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 |  | 
| 3 // BSD-style license that can be found in the LICENSE file. |  | 
| 4 |  | 
| 5 library observe.src.change_notifier; |  | 
| 6 |  | 
| 7 import 'dart:async'; |  | 
| 8 import 'dart:collection' show UnmodifiableListView; |  | 
| 9 import 'package:observe/observe.dart'; |  | 
| 10 import 'package:observe/src/observable.dart' show notifyPropertyChangeHelper; |  | 
| 11 |  | 
| 12 /// Mixin and base class for implementing an [Observable] object that performs |  | 
| 13 /// its own change notifications, and does not need to be considered by |  | 
| 14 /// [Observable.dirtyCheck]. |  | 
| 15 /// |  | 
| 16 /// When a field, property, or indexable item is changed, a derived class should |  | 
| 17 /// call [notifyPropertyChange]. See that method for an example. |  | 
| 18 abstract class ChangeNotifier implements Observable { |  | 
| 19   StreamController _changes; |  | 
| 20   List<ChangeRecord> _records; |  | 
| 21 |  | 
| 22   Stream<List<ChangeRecord>> get changes { |  | 
| 23     if (_changes == null) { |  | 
| 24       _changes = new StreamController.broadcast(sync: true, |  | 
| 25           onListen: observed, onCancel: unobserved); |  | 
| 26     } |  | 
| 27     return _changes.stream; |  | 
| 28   } |  | 
| 29 |  | 
| 30   // TODO(jmesserly): should these be public? They're useful lifecycle methods |  | 
| 31   // for subclasses. Ideally they'd be protected. |  | 
| 32   /// Override this method to be called when the [changes] are first observed. |  | 
| 33   void observed() {} |  | 
| 34 |  | 
| 35   /// Override this method to be called when the [changes] are no longer being |  | 
| 36   /// observed. |  | 
| 37   void unobserved() { |  | 
| 38     // Free some memory |  | 
| 39     _changes = null; |  | 
| 40   } |  | 
| 41 |  | 
| 42   bool deliverChanges() { |  | 
| 43     var records = _records; |  | 
| 44     _records = null; |  | 
| 45     if (hasObservers && records != null) { |  | 
| 46       _changes.add(new UnmodifiableListView<ChangeRecord>(records)); |  | 
| 47       return true; |  | 
| 48     } |  | 
| 49     return false; |  | 
| 50   } |  | 
| 51 |  | 
| 52   /// True if this object has any observers, and should call |  | 
| 53   /// [notifyPropertyChange] for changes. |  | 
| 54   bool get hasObservers => _changes != null && _changes.hasListener; |  | 
| 55 |  | 
| 56   /// Notify that the field [name] of this object has been changed. |  | 
| 57   /// |  | 
| 58   /// The [oldValue] and [newValue] are also recorded. If the two values are |  | 
| 59   /// equal, no change will be recorded. |  | 
| 60   /// |  | 
| 61   /// For convenience this returns [newValue]. This makes it easy to use in a |  | 
| 62   /// setter: |  | 
| 63   /// |  | 
| 64   ///     var _myField; |  | 
| 65   ///     @reflectable get myField => _myField; |  | 
| 66   ///     @reflectable set myField(value) { |  | 
| 67   ///       _myField = notifyPropertyChange(#myField, _myField, value); |  | 
| 68   ///     } |  | 
| 69   notifyPropertyChange(Symbol field, Object oldValue, Object newValue) |  | 
| 70       => notifyPropertyChangeHelper(this, field, oldValue, newValue); |  | 
| 71 |  | 
| 72   void notifyChange(ChangeRecord record) { |  | 
| 73     if (!hasObservers) return; |  | 
| 74 |  | 
| 75     if (_records == null) { |  | 
| 76       _records = []; |  | 
| 77       scheduleMicrotask(deliverChanges); |  | 
| 78     } |  | 
| 79     _records.add(record); |  | 
| 80   } |  | 
| 81 } |  | 
| OLD | NEW | 
|---|