-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Deprecate Observable, add ChangeNotifier, setup travis (#11)
* Deprecate Observable, setup Travis * Make changes suggested via review * Update .travis.yml Remove stable branch, as `collection` dependency won't resolve on it.
- Loading branch information
1 parent
2446d7b
commit d296efa
Showing
15 changed files
with
327 additions
and
108 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
language: dart | ||
|
||
dart: | ||
- dev | ||
# Currently requires a dev-branch in order to use properly. | ||
# - stable | ||
|
||
script: ./tool/presubmit.sh |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
import 'dart:async'; | ||
|
||
import 'package:meta/meta.dart'; | ||
|
||
import 'internal.dart'; | ||
import 'observable.dart'; | ||
import 'records.dart'; | ||
|
||
/// Supplies [changes] and various hooks to implement [Observable]. | ||
/// | ||
/// May use [notifyChange] to queue a change record; they are asynchronously | ||
/// delivered at the end of the VM turn. | ||
/// | ||
/// [ChangeNotifier] may be extended, mixed in, or used as a delegate. | ||
class ChangeNotifier<C extends ChangeRecord> implements Observable<C> { | ||
StreamController<List<C>> _changes; | ||
|
||
bool _scheduled = false; | ||
List<C> _queue; | ||
|
||
/// Emits a list of changes when the state of the object changes. | ||
/// | ||
/// Changes should produced in order, if significant. | ||
@override | ||
Stream<List<C>> get changes { | ||
return (_changes ??= new StreamController<List<C>>.broadcast( | ||
sync: true, | ||
onListen: observed, | ||
onCancel: unobserved, | ||
)) | ||
.stream; | ||
} | ||
|
||
/// May override to be notified when [changes] is first observed. | ||
@override | ||
@protected | ||
@mustCallSuper | ||
void observed() {} | ||
|
||
/// May override to be notified when [changes] is no longer observed. | ||
@override | ||
@protected | ||
@mustCallSuper | ||
void unobserved() { | ||
_changes = _queue = null; | ||
} | ||
|
||
/// If [hasObservers], synchronously emits [changes] that have been queued. | ||
/// | ||
/// Returns `true` if changes were emitted. | ||
@override | ||
@protected | ||
@mustCallSuper | ||
bool deliverChanges() { | ||
List<ChangeRecord> changes; | ||
if (_scheduled && hasObservers) { | ||
if (_queue != null) { | ||
changes = freezeInDevMode(_queue); | ||
_queue = null; | ||
} else { | ||
changes = ChangeRecord.ANY; | ||
} | ||
_scheduled = false; | ||
_changes.add(changes); | ||
} | ||
return changes != null; | ||
} | ||
|
||
/// Whether [changes] has at least one active listener. | ||
/// | ||
/// May be used to optimize whether to produce change records. | ||
@override | ||
bool get hasObservers => _changes?.hasListener == true; | ||
|
||
/// Schedules [change] to be delivered. | ||
/// | ||
/// If [change] is omitted then [ChangeRecord.ANY] will be sent. | ||
/// | ||
/// If there are no listeners to [changes], this method does nothing. | ||
@override | ||
void notifyChange([C change]) { | ||
if (!hasObservers) { | ||
return; | ||
} | ||
if (change != null) { | ||
(_queue ??= <C>[]).add(change); | ||
} | ||
if (!_scheduled) { | ||
scheduleMicrotask(deliverChanges); | ||
_scheduled = true; | ||
} | ||
} | ||
|
||
@Deprecated('Exists to make migrations off Observable easier') | ||
@override | ||
@protected | ||
/*=T*/ notifyPropertyChange/*<T>*/( | ||
Symbol field, | ||
/*=T*/ | ||
oldValue, | ||
/*=T*/ | ||
newValue, | ||
) { | ||
throw new UnsupportedError('Not supported by ChangeNotifier'); | ||
} | ||
} | ||
|
||
/// Implements [notifyPropertyChange] for classes that need support. | ||
/// | ||
/// Will be folded entirely into [PropertyChangeNotifier] in the future. | ||
@Deprecated('Exists to make migrations off Observable easier') | ||
abstract class PropertyChangeMixin implements ChangeNotifier { | ||
@override | ||
/*=T*/ notifyPropertyChange/*<T>*/( | ||
Symbol field, | ||
/*=T*/ | ||
oldValue, | ||
/*=T*/ | ||
newValue, | ||
) { | ||
if (hasObservers && oldValue != newValue) { | ||
notifyChange( | ||
new PropertyChangeRecord/*<T>*/( | ||
this, | ||
field, | ||
oldValue, | ||
newValue, | ||
), | ||
); | ||
} | ||
return newValue; | ||
} | ||
} | ||
|
||
/// Supplies property `changes` and various hooks to implement [Observable]. | ||
/// | ||
/// May use `notifyChange` or `notifyPropertyChange` to queue a property change | ||
/// record; they are asynchronously delivered at the end of the VM turn. | ||
/// | ||
/// [PropertyChangeNotifier] may be extended or used as a delegate. To use as | ||
/// a mixin, instead use with [PropertyChangeMixin]: | ||
/// with ChangeNotifier<PropertyChangeRecord>, PropertyChangeMixin | ||
class PropertyChangeNotifier = ChangeNotifier<PropertyChangeRecord> | ||
with PropertyChangeMixin; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.