Update to pkg/observable 0.17.0 (#92)
* Revert "Revert "Update to pkg/observable 0.17.0""
This reverts commit 77f5f61154c21aecf16fbf1242115efea5382d33.
* Perf tweak
diff --git a/benchmark/index.dart b/benchmark/index.dart
deleted file mode 100644
index 49e7cad..0000000
--- a/benchmark/index.dart
+++ /dev/null
@@ -1,171 +0,0 @@
-// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-library observe.test.benchmark.index;
-
-import 'dart:async';
-import 'dart:html';
-import 'package:benchmark_harness/benchmark_harness.dart';
-import 'package:chart/chart.dart';
-import 'package:observe/mirrors_used.dart' as mu; // Makes output smaller.
-import 'package:smoke/mirrors.dart';
-import 'object_benchmark.dart';
-import 'setup_object_benchmark.dart';
-import 'observable_list_benchmark.dart';
-import 'setup_observable_list_benchmark.dart';
-import 'path_benchmark.dart';
-import 'setup_path_benchmark.dart';
-
-/// Benchmark names to factory functions.
-/// Uses [mu].
-typedef BenchmarkBase BenchmarkFactory(
- int objectCount, int mutationCount, String config);
-final Map<String, BenchmarkFactory> benchmarkFactories = {
- 'ObjectBenchmark': (int o, int m, String c) => new ObjectBenchmark(o, m, c),
- 'SetupObjectBenchmark': (int o, int m, String c) =>
- new SetupObjectBenchmark(o, c),
- 'ObservableListBenchmark': (int o, int m, String c) =>
- new ObservableListBenchmark(o, m, c),
- 'SetupObservableListBenchmark': (int o, int m, String c) =>
- new SetupObservableListBenchmark(o, c),
- 'PathBenchmark': (int o, int m, String c) => new PathBenchmark(o, m, c),
- 'SetupPathBenchmark': (int o, int m, String c) =>
- new SetupPathBenchmark(o, c),
-};
-
-/// Benchmark names to possible configs.
-final Map<String, List<String>> benchmarkConfigs = {
- 'ObjectBenchmark': [],
- 'SetupObjectBenchmark': [],
- 'ObservableListBenchmark': ['splice', 'update', 'push/pop', 'shift/unshift'],
- 'SetupObservableListBenchmark': [],
- 'PathBenchmark': ['leaf', 'root'],
- 'SetupPathBenchmark': [],
-};
-
-Iterable<int> objectCounts;
-Iterable<int> mutationCounts;
-
-final ButtonElement goButton = querySelector('#go');
-final InputElement objectCountInput = querySelector('#objectCountInput');
-final InputElement mutationCountInput = querySelector('#mutationCountInput');
-final SpanElement mutationCountWrapper = querySelector('#mutationCountWrapper');
-final SpanElement statusSpan = querySelector('#status');
-final DivElement canvasWrapper = querySelector('#canvasWrapper');
-final SelectElement benchmarkSelect = querySelector('#benchmarkSelect');
-final SelectElement configSelect = querySelector('#configSelect');
-final UListElement legendList = querySelector('#legendList');
-final List<String> colors = [
- [0, 0, 255],
- [138, 43, 226],
- [165, 42, 42],
- [100, 149, 237],
- [220, 20, 60],
- [184, 134, 11]
-].map((rgb) => 'rgba(' + rgb.join(',') + ',.7)').toList();
-
-main() {
- // TODO(jakemac): Use a transformer to generate the smoke config so we can see
- // how that affects the benchmark.
- useMirrors();
-
- benchmarkSelect.onChange.listen((_) => changeBenchmark());
- changeBenchmark();
-
- goButton.onClick.listen((_) async {
- canvasWrapper.children.clear();
- goButton.disabled = true;
- goButton.text = 'Running...';
- legendList.text = '';
- objectCounts =
- objectCountInput.value.split(',').map((val) => int.parse(val));
-
- if (benchmarkSelect.value.startsWith('Setup')) {
- mutationCounts = [0];
- } else {
- mutationCounts =
- mutationCountInput.value.split(',').map((val) => int.parse(val));
- }
-
- var i = 0;
- mutationCounts.forEach((count) {
- var li = document.createElement('li');
- li.text = '$count mutations.';
- li.style.color = colors[i % colors.length];
- legendList.append(li);
- i++;
- });
-
- var results = <List<double>>[];
- for (int objectCount in objectCounts) {
- int x = 0;
- for (int mutationCount in mutationCounts) {
- statusSpan.text =
- 'Testing: $objectCount objects with $mutationCount mutations';
- // Let the status text render before running the next benchmark.
- await new Future(() {});
- var factory = benchmarkFactories[benchmarkSelect.value];
- var benchmark = factory(objectCount, mutationCount, configSelect.value);
- // Divide by 10 because benchmark_harness returns the amount of time it
- // took to run 10 times, not once :(.
- var resultMicros = benchmark.measure() / 10;
-
- if (results.length <= x) results.add([]);
- results[x].add(resultMicros / 1000);
- x++;
- }
- }
-
- drawBenchmarks(results);
- });
-}
-
-void drawBenchmarks(List<List<double>> results) {
- var datasets = [];
- for (int i = 0; i < results.length; i++) {
- datasets.add({
- 'fillColor': 'rgba(255, 255, 255, 0)',
- 'strokeColor': colors[i % colors.length],
- 'pointColor': colors[i % colors.length],
- 'pointStrokeColor': "#fff",
- 'data': results[i],
- });
- }
- var data = {
- 'labels': objectCounts.map((c) => '$c').toList(),
- 'datasets': datasets,
- };
-
- new Line(data, {
- 'bezierCurve': false,
- }).show(canvasWrapper);
- goButton.disabled = false;
- goButton.text = 'Run Benchmarks';
- statusSpan.text = '';
-}
-
-void changeBenchmark() {
- var configs = benchmarkConfigs[benchmarkSelect.value];
- configSelect.text = '';
- configs.forEach((config) {
- var option = document.createElement('option');
- option.text = config;
- configSelect.append(option);
- });
-
- document.title = benchmarkSelect.value;
-
- // Don't show the configSelect if there are no configs.
- if (configs.isEmpty) {
- configSelect.style.display = 'none';
- } else {
- configSelect.style.display = 'inline';
- }
-
- // Don't show the mutation counts box if running a Setup* benchmark.
- if (benchmarkSelect.value.startsWith('Setup')) {
- mutationCountWrapper.style.display = 'none';
- } else {
- mutationCountWrapper.style.display = 'inline';
- }
-}
diff --git a/benchmark/index.html b/benchmark/index.html
deleted file mode 100644
index ce2bf9f..0000000
--- a/benchmark/index.html
+++ /dev/null
@@ -1,73 +0,0 @@
-<html>
-<!--
-Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
-This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
-The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
-The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
-Code distributed by Google as part of the polymer project is also
-subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
--->
-<head>
- <title>Observation Benchmarks</title>
- <meta charset="utf-8">
- <style>
- * {
- font-family: arial, helvetica, sans-serif;
- font-weight: 400;
- }
- body {
- margin: 0;
- padding: 0;
- background-color: rgba(0, 0, 0, .1);
- }
- #canvasWrapper {
- width: 800px;
- height: 400px;
- }
- </style>
-</head>
-<body>
-<h1>Observation Benchmarks</h1>
-
-<select id="benchmarkSelect">
- <option>ObjectBenchmark</option>
- <option>SetupObjectBenchmark</option>
- <option>ObservableListBenchmark</option>
- <option>SetupObservableListBenchmark</option>
- <option>PathBenchmark</option>
- <option>SetupPathBenchmark</option>
-</select>
-<select id="configSelect">
-</select>
-
-<button id="go">Run Benchmarks</button>
-
-<span>Object Count: </span>
-<input id="objectCountInput" style="width: 200px" value="4000, 8000, 16000, 32000">
-<span id="mutationCountWrapper">
- <span>Mutation Count: </span>
- <input id="mutationCountInput" style="width: 200px"
- value="0, 100, 200, 400, 800, 1600"><br>
-</span>
-<br>
-<span id="status"></span>
-
-<section style="width: 100%">
- <article>
- <div style="display:inline-block; padding-bottom: 20px">
- Times in ms
- </div>
- <div id="canvasWrapper" style="display:inline-block">
- </div>
- <div style="display:inline-block">
- <ul id="legendList">
- </ul>
- </div>
- </article>
-</section>
-<h3 style="margin-left: 440px">Object Set Size</h3>
-<script type="application/dart" src="index.dart"></script>
-<script src="packages/browser/dart.js">
-</script>
-</body>
-</html>
diff --git a/benchmark/object_benchmark.dart b/benchmark/object_benchmark.dart
deleted file mode 100644
index 91282be..0000000
--- a/benchmark/object_benchmark.dart
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-library observe.test.benchmark.object_benchmark;
-
-import 'observation_benchmark_base.dart';
-import 'test_observable.dart';
-
-class ObjectBenchmark extends ObservationBenchmarkBase<TestObservable> {
- ObjectBenchmark(int objectCount, int mutationCount, String config)
- : super('ObjectBenchmark:$objectCount:$mutationCount:$config',
- objectCount, mutationCount, config);
-
- @override
- int mutateObject(TestObservable obj) {
- // Modify the first 5 properties.
- obj.a++;
- obj.b++;
- obj.c++;
- obj.d++;
- obj.e++;
- // Return # of modifications.
- return 5;
- }
-
- @override
- TestObservable newObject() => new TestObservable();
-}
diff --git a/benchmark/observable_list_benchmark.dart b/benchmark/observable_list_benchmark.dart
deleted file mode 100644
index d0f8ad9..0000000
--- a/benchmark/observable_list_benchmark.dart
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-library observe.test.benchmark.observable_list_benchmark;
-
-import 'package:observable/observable.dart';
-import 'observation_benchmark_base.dart';
-
-class ObservableListBenchmark extends ObservationBenchmarkBase<ObservableList> {
- final int elementCount = 100;
-
- ObservableListBenchmark(int objectCount, int mutationCount, String config)
- : super('ObservableListBenchmark:$objectCount:$mutationCount:$config',
- objectCount, mutationCount, config);
-
- @override
- int mutateObject(ObservableList obj) {
- switch (config) {
- case 'update':
- var size = (elementCount / 10).floor();
- for (var j = 0; j < size; j++) {
- obj[j * size]++;
- }
- return size;
-
- case 'splice':
- var size = (elementCount / 5).floor();
- // No splice equivalent in List, so we hardcode it.
- var removed = obj.sublist(size, size * 2);
- obj.removeRange(size, size * 2);
- obj.insertAll(size * 2, removed);
- return size * 2;
-
- case 'push/pop':
- var val = obj.removeLast();
- obj.add(val + 1);
- return 2;
-
- case 'shift/unshift':
- var val = obj.removeAt(0);
- obj.insert(0, val + 1);
- return 2;
-
- default:
- throw new ArgumentError(
- 'Invalid config for ObservableListBenchmark: $config');
- }
- }
-
- @override
- ObservableList newObject() {
- var list = new ObservableList();
- for (int i = 0; i < elementCount; i++) {
- list.add(i);
- }
- return list;
- }
-}
diff --git a/benchmark/observation_benchmark_base.dart b/benchmark/observation_benchmark_base.dart
deleted file mode 100644
index f8fc983..0000000
--- a/benchmark/observation_benchmark_base.dart
+++ /dev/null
@@ -1,120 +0,0 @@
-// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-library observe.test.benchmark.observation_benchmark_base;
-
-import 'dart:async';
-import 'dart:html';
-
-import 'package:observable/observable.dart';
-import 'package:observe/observe.dart';
-import 'package:benchmark_harness/benchmark_harness.dart';
-
-abstract class ObservationBenchmarkBase<T extends Observable>
- extends BenchmarkBase {
- /// The number of objects to create and observe.
- final int objectCount;
-
- /// The number of mutations to perform.
- final int mutationCount;
-
- /// The current configuration.
- final String config;
-
- /// The number of pending mutations left to observe.
- int mutations;
-
- /// The objects we want to observe.
- List<T> objects;
-
- /// The change listeners on all of our objects.
- List observers;
-
- /// The current object being mutated.
- int objectIndex;
-
- ObservationBenchmarkBase(
- String name, this.objectCount, this.mutationCount, this.config)
- : super(name);
-
- /// Subclasses should use this method to perform mutations on an object. The
- /// return value indicates how many mutations were performed on the object.
- int mutateObject(T obj);
-
- /// Subclasses should use this method to return an observable object to be
- /// benchmarked.
- T newObject();
-
- /// Subclasses should override this to do anything other than a default change
- /// listener. It must return either a StreamSubscription or a PathObserver.
- /// If overridden this observer should decrement [mutations] each time a
- /// change is observed.
- newObserver(T obj) {
- decrement(_) => mutations--;
- if (obj is ObservableList) return obj.listChanges.listen(decrement);
- return obj.changes.listen(decrement);
- }
-
- /// Set up each benchmark by creating all the objects and listeners.
- @override
- void setup() {
- mutations = 0;
-
- objects = [];
- observers = [];
- objectIndex = 0;
-
- while (objects.length < objectCount) {
- var obj = newObject();
- objects.add(obj);
- observers.add(newObserver(obj));
- }
- }
-
- /// Tear down each benchmark and make sure that [mutations] is 0.
- @override
- void teardown() {
- if (mutations != 0) {
- window.alert('$mutations mutation sets were not observed!');
- }
- mutations = 0;
-
- while (observers.isNotEmpty) {
- var observer = observers.removeLast();
- if (observer is StreamSubscription) {
- observer.cancel();
- } else if (observer is PathObserver) {
- observer.close();
- } else {
- throw 'Unknown observer type ${observer.runtimeType}. Only '
- '[PathObserver] and [StreamSubscription] are supported.';
- }
- }
- observers = null;
-
- bool leakedObservers = false;
- while (objects.isNotEmpty) {
- leakedObservers = objects.removeLast().hasObservers || leakedObservers;
- }
- if (leakedObservers) window.alert('Observers leaked!');
- objects = null;
- }
-
- /// Run the benchmark
- @override
- void run() {
- var mutationsLeft = mutationCount;
- while (mutationsLeft > 0) {
- var obj = objects[objectIndex];
- mutationsLeft -= mutateObject(obj);
- this.mutations++;
- this.objectIndex++;
- if (this.objectIndex == this.objects.length) {
- this.objectIndex = 0;
- }
- obj.deliverChanges();
- if (obj is ObservableList) obj.deliverListChanges();
- }
- AutoObservable.dirtyCheck();
- }
-}
diff --git a/benchmark/path_benchmark.dart b/benchmark/path_benchmark.dart
deleted file mode 100644
index a612c55..0000000
--- a/benchmark/path_benchmark.dart
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-library observe.test.benchmark.path_benchmark;
-
-import 'package:observe/observe.dart';
-import 'observation_benchmark_base.dart';
-import 'test_path_observable.dart';
-
-class PathBenchmark extends ObservationBenchmarkBase<TestPathObservable> {
- final PropertyPath path = new PropertyPath('foo.bar.baz');
-
- PathBenchmark(int objectCount, int mutationCount, String config)
- : super('PathBenchmark:$objectCount:$mutationCount:$config', objectCount,
- mutationCount, config);
-
- @override
- int mutateObject(TestPathObservable obj) {
- switch (config) {
- case 'leaf':
- obj.foo.bar.baz += 1;
- // Make sure [obj.foo.bar] delivers its changes synchronously. The base
- // class already handles this for [obj].
- obj.foo.bar.deliverChanges();
- return 1;
-
- case 'root':
- obj.foo = new Foo(obj.foo.bar.baz + 1);
- return 1;
-
- default:
- throw new ArgumentError('Invalid config for PathBenchmark: $config');
- }
- }
-
- @override
- TestPathObservable newObject() => new TestPathObservable(1);
-
- @override
- PathObserver newObserver(TestPathObservable obj) =>
- new PathObserver(obj, path)..open((_) => mutations--);
-}
diff --git a/benchmark/setup_object_benchmark.dart b/benchmark/setup_object_benchmark.dart
deleted file mode 100644
index 6fda9fc..0000000
--- a/benchmark/setup_object_benchmark.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-library observe.test.benchmark.setup_object_benchmark;
-
-import 'setup_observation_benchmark_base.dart';
-import 'test_observable.dart';
-
-class SetupObjectBenchmark extends SetupObservationBenchmarkBase {
- SetupObjectBenchmark(int objectCount, String config)
- : super('SetupObjectBenchmark:$objectCount:$config', objectCount, config);
-
- @override
- TestObservable newObject() => new TestObservable();
-}
diff --git a/benchmark/setup_observable_list_benchmark.dart b/benchmark/setup_observable_list_benchmark.dart
deleted file mode 100644
index b40aced..0000000
--- a/benchmark/setup_observable_list_benchmark.dart
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-library observe.test.benchmark.setup_observable_list_benchmark;
-
-import 'package:observable/observable.dart';
-import 'setup_observation_benchmark_base.dart';
-
-class SetupObservableListBenchmark extends SetupObservationBenchmarkBase {
- final int elementCount = 100;
-
- SetupObservableListBenchmark(int objectCount, String config)
- : super('SetupObservableListBenchmark:$objectCount:$config', objectCount,
- config);
-
- @override
- ObservableList newObject() {
- var list = new ObservableList();
- for (int i = 0; i < elementCount; i++) {
- list.add(i);
- }
- list.deliverChanges();
- list.deliverListChanges();
- return list;
- }
-}
diff --git a/benchmark/setup_observation_benchmark_base.dart b/benchmark/setup_observation_benchmark_base.dart
deleted file mode 100644
index 2b26b72..0000000
--- a/benchmark/setup_observation_benchmark_base.dart
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-library observe.test.benchmark.setup_observation_benchmark_base;
-
-import 'dart:async';
-import 'dart:html';
-import 'package:observable/observable.dart';
-import 'package:observe/observe.dart';
-import 'package:benchmark_harness/benchmark_harness.dart';
-
-abstract class SetupObservationBenchmarkBase<T extends Observable>
- extends BenchmarkBase {
- /// The number of objects to create and observe.
- final int objectCount;
-
- /// The current configuration.
- final String config;
-
- /// The objects we want to observe.
- List<T> objects;
-
- SetupObservationBenchmarkBase(String name, this.objectCount, this.config)
- : super(name);
-
- /// Subclasses should use this method to return an observable object to be
- /// benchmarked.
- T newObject();
-
- /// Subclasses should override this to do anything other than a default change
- /// listener. It must return either a StreamSubscription or a PathObserver.
- newObserver(T obj) => obj.changes.listen((_) {});
-
- /// Set up each benchmark by creating all the objects.
- @override
- void setup() {
- objects = [];
- while (objects.length < objectCount) {
- objects.add(newObject());
- }
- }
-
- /// Tear down each the benchmark and remove all listeners.
- @override
- void teardown() {
- while (objects.isNotEmpty) {
- var obj = objects.removeLast();
- if (obj.hasObservers || (obj is ObservableList && obj.hasListObservers)) {
- window.alert('Observers leaked!');
- }
- }
- objects = null;
- }
-
- /// Run the benchmark by creating a listener on each object.
- @override
- void run() {
- for (var object in objects) {
- var observer = newObserver(object);
-
- // **Note:** This is different than the JS implementation. Since run can
- // be called an arbitrary number of times between [setup] and [teardown],
- // we clean up all observers as we go. This means we are measuring both
- // the setup and teardown of observers, versus the setup only in the
- // JS benchmark. Not cleaning these up ends up giving `oh snap` errors.
- if (observer is StreamSubscription) {
- observer.cancel();
- } else if (observer is PathObserver) {
- observer.close();
- } else {
- throw 'Unknown observer type ${observer.runtimeType}. Only '
- '[PathObserver] and [StreamSubscription] are supported.';
- }
- }
- }
-}
diff --git a/benchmark/setup_path_benchmark.dart b/benchmark/setup_path_benchmark.dart
deleted file mode 100644
index 72bba82..0000000
--- a/benchmark/setup_path_benchmark.dart
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-library observe.test.benchmark.setup_path_benchmark;
-
-import 'package:observe/observe.dart';
-import 'setup_observation_benchmark_base.dart';
-import 'test_path_observable.dart';
-
-class SetupPathBenchmark
- extends SetupObservationBenchmarkBase<TestPathObservable> {
- final PropertyPath path = new PropertyPath('foo.bar.baz');
-
- SetupPathBenchmark(int objectCount, String config)
- : super('SetupPathBenchmark:$objectCount:$config', objectCount, config);
-
- @override
- TestPathObservable newObject() => new TestPathObservable(1);
-
- @override
- PathObserver newObserver(TestPathObservable obj) =>
- new PathObserver(obj, path)..open(() {});
-}
diff --git a/benchmark/test_observable.dart b/benchmark/test_observable.dart
deleted file mode 100644
index 15ef2d7..0000000
--- a/benchmark/test_observable.dart
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-library observe.test.benchmark.test_observable;
-
-import 'package:observe/observe.dart';
-
-class TestObservable extends AutoObservable {
- @observable
- int a = 0;
- @observable
- int b = 0;
- @observable
- int c = 0;
- @observable
- int d = 0;
- @observable
- int e = 0;
- @observable
- int f = 0;
- @observable
- int g = 0;
- @observable
- int h = 0;
- @observable
- int i = 0;
- @observable
- int j = 0;
- @observable
- int k = 0;
- @observable
- int l = 0;
- @observable
- int m = 0;
- @observable
- int n = 0;
- @observable
- int o = 0;
-}
diff --git a/benchmark/test_path_observable.dart b/benchmark/test_path_observable.dart
deleted file mode 100644
index 6675822..0000000
--- a/benchmark/test_path_observable.dart
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-library observe.test.benchmark.test_observable;
-
-import 'package:observe/observe.dart';
-
-class Bar extends AutoObservable {
- @observable
- int baz;
-
- Bar(this.baz);
-}
-
-class Foo extends AutoObservable {
- @observable
- Bar bar;
-
- Foo(int value) : bar = new Bar(value);
-}
-
-class TestPathObservable extends AutoObservable {
- @observable
- Foo foo;
-
- TestPathObservable(int value) : foo = new Foo(value);
-}
diff --git a/lib/html.dart b/lib/html.dart
index 5000a78..e29b0db 100644
--- a/lib/html.dart
+++ b/lib/html.dart
@@ -19,7 +19,7 @@
/// An observable version of [window.location.hash].
final ObservableLocationHash windowLocation = new ObservableLocationHash._();
-class ObservableLocationHash extends Observable {
+class ObservableLocationHash extends PropertyChangeNotifier {
Object _currentHash;
ObservableLocationHash._() {
diff --git a/lib/src/auto_observable.dart b/lib/src/auto_observable.dart
index bcb486a..2fae812 100644
--- a/lib/src/auto_observable.dart
+++ b/lib/src/auto_observable.dart
@@ -13,7 +13,7 @@
import 'dirty_check.dart' show dirtyCheckObservables, registerObservable;
import 'metadata.dart' show ObservableProperty;
-abstract class AutoObservable implements Observable {
+abstract class AutoObservable implements ChangeNotifier {
/// Performs dirty checking of objects that inherit from [AutoObservable].
/// This scans all observed objects using mirrors and determines if any fields
/// have changed. If they have, it delivers the changes for the object.
@@ -147,9 +147,8 @@
/// - Unlike [Observable] this will not schedule [deliverChanges]; use
/// [AutoObservable.dirtyCheck] instead.
@override
- void notifyChange(ChangeRecord record) {
- if (!hasObservers) return;
-
+ void notifyChange([ChangeRecord record]) {
+ if (record == null || !hasObservers) return;
if (_records == null) _records = [];
_records.add(record);
}
diff --git a/lib/src/list_path_observer.dart b/lib/src/list_path_observer.dart
index 09f1b6c..c329103 100644
--- a/lib/src/list_path_observer.dart
+++ b/lib/src/list_path_observer.dart
@@ -14,7 +14,7 @@
/// Observes a path starting from each item in the list.
@deprecated
-class ListPathObserver<E, P> extends Observable {
+class ListPathObserver<E, P> extends PropertyChangeNotifier {
final ObservableList<E> list;
final String _itemPath;
final List<PathObserver> _observers = <PathObserver>[];
diff --git a/lib/src/metadata.dart b/lib/src/metadata.dart
index 6811332..15e7905 100644
--- a/lib/src/metadata.dart
+++ b/lib/src/metadata.dart
@@ -37,7 +37,7 @@
/// it available to `PathObserver` at runtime. For example:
///
/// @reflectable
-/// class Monster extends Observable {
+/// class Monster extends AutoObservable {
/// int _health;
/// int get health => _health;
/// ...
diff --git a/lib/src/observable_box.dart b/lib/src/observable_box.dart
index 51c584a..5749890 100644
--- a/lib/src/observable_box.dart
+++ b/lib/src/observable_box.dart
@@ -13,7 +13,7 @@
/// value. For other cases, it is better to use [AutoObservableList],
/// [AutoObservableMap], or a custom [AutoObservable] implementation based on
/// [AutoObservable]. The property name for changes is "value".
-class ObservableBox<T> extends Observable {
+class ObservableBox<T> extends PropertyChangeNotifier {
T _value;
ObservableBox([T initialValue]) : _value = initialValue;
diff --git a/pubspec.yaml b/pubspec.yaml
index e74974a..e9a4b36 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
name: observe
-version: 0.14.0
+version: 0.15.0
author: Polymer.dart Authors <web-ui-dev@dartlang.org>
description: >
Observable properties and objects for use in template_binding.
@@ -13,7 +13,7 @@
barback: '>=0.14.2 <0.16.0'
func: ^0.1.0
logging: '>=0.9.0 <0.12.0'
- observable: '^0.14.0'
+ observable: '^0.17.0'
path: '>=0.9.0 <2.0.0'
smoke: '>=0.1.0 <0.4.0'
source_maps: '>=0.9.4 <0.11.0'
diff --git a/test/list_path_observer_test.dart b/test/list_path_observer_test.dart
index e3df022..f0e89b5 100644
--- a/test/list_path_observer_test.dart
+++ b/test/list_path_observer_test.dart
@@ -85,7 +85,7 @@
_nextMicrotask(_) => new Future(() {});
@reflectable
-class TestModel extends Observable {
+class TestModel extends PropertyChangeNotifier {
var _a, _b;
TestModel();
diff --git a/test/path_observer_test.dart b/test/path_observer_test.dart
index ba9cc22..bc7731a 100644
--- a/test/path_observer_test.dart
+++ b/test/path_observer_test.dart
@@ -175,7 +175,8 @@
});
test('get value at path ObservableBox', () {
- var obj = new ObservableBox(new ObservableBox(new ObservableBox(1)));
+ var obj =
+ new ObservableBox<dynamic>(new ObservableBox(new ObservableBox(1)));
expect(new PathObserver(obj, '').value, obj);
expect(new PathObserver(obj, 'value').value, obj.value);
@@ -188,7 +189,7 @@
obj.value.value = new ObservableBox(3);
expect(new PathObserver(obj, 'value.value.value').value, 3);
- obj.value = new ObservableBox(4);
+ obj.value = new ObservableBox<int>(4);
expect(() => new PathObserver(obj, 'value.value.value').value,
_throwsNSM('value'));
expect(new PathObserver(obj, 'value.value').value, 4);
@@ -753,7 +754,7 @@
}
@reflectable
-class TestModel extends Observable implements WatcherModel {
+class TestModel extends ChangeNotifier implements WatcherModel {
var _a, _b, _c;
TestModel([this._a, this._b, this._c]);
@@ -775,6 +776,15 @@
void set c(newValue) {
_c = notifyPropertyChange(#c, _c, newValue);
}
+
+ @override
+ /*=T*/ notifyPropertyChange/*<T>*/(
+ Symbol field, /*=T*/ oldValue, /*=T*/ newValue) {
+ if (hasObservers && oldValue != newValue) {
+ notifyChange(new PropertyChangeRecord(this, field, oldValue, newValue));
+ }
+ return newValue;
+ }
}
class WatcherModel extends AutoObservable {