OLD | NEW |
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 library observe.src.path_observer; | 5 library observe.src.path_observer; |
6 | 6 |
7 import 'dart:async'; | 7 import 'dart:async'; |
8 import 'dart:collection'; | 8 import 'dart:collection'; |
9 import 'dart:math' show min; | 9 import 'dart:math' show min; |
10 | 10 |
(...skipping 23 matching lines...) Expand all Loading... |
34 /// See [open] and [value]. | 34 /// See [open] and [value]. |
35 PathObserver(Object object, [path]) | 35 PathObserver(Object object, [path]) |
36 : _object = object, | 36 : _object = object, |
37 _path = path is PropertyPath ? path : new PropertyPath(path); | 37 _path = path is PropertyPath ? path : new PropertyPath(path); |
38 | 38 |
39 bool get _isClosed => _path == null; | 39 bool get _isClosed => _path == null; |
40 | 40 |
41 /// Sets the value at this path. | 41 /// Sets the value at this path. |
42 void set value(Object newValue) { | 42 void set value(Object newValue) { |
43 if (_path != null) _path.setValueFrom(_object, newValue); | 43 if (_path != null) _path.setValueFrom(_object, newValue); |
44 _discardChanges(); | |
45 } | 44 } |
46 | 45 |
47 int get _reportArgumentCount => 2; | 46 int get _reportArgumentCount => 2; |
48 | 47 |
49 /// Initiates observation and returns the initial value. | 48 /// Initiates observation and returns the initial value. |
50 /// The callback will be passed the updated [value], and may optionally be | 49 /// The callback will be passed the updated [value], and may optionally be |
51 /// declared to take a second argument, which will contain the previous value. | 50 /// declared to take a second argument, which will contain the previous value. |
52 open(callback) => super.open(callback); | 51 open(callback) => super.open(callback); |
53 | 52 |
54 void _connect() { | 53 void _connect() { |
(...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
502 | 501 |
503 Function _notifyCallback; | 502 Function _notifyCallback; |
504 int _notifyArgumentCount; | 503 int _notifyArgumentCount; |
505 var _value; | 504 var _value; |
506 | 505 |
507 // abstract members | 506 // abstract members |
508 void _iterateObjects(void observe(obj)); | 507 void _iterateObjects(void observe(obj)); |
509 void _connect(); | 508 void _connect(); |
510 void _disconnect(); | 509 void _disconnect(); |
511 bool get _isClosed; | 510 bool get _isClosed; |
512 _check({bool skipChanges: false}); | 511 bool _check({bool skipChanges: false}); |
513 | 512 |
514 bool get _isOpen => _notifyCallback != null; | 513 bool get _isOpen => _notifyCallback != null; |
515 | 514 |
516 /// The number of arguments the subclass will pass to [_report]. | 515 /// The number of arguments the subclass will pass to [_report]. |
517 int get _reportArgumentCount; | 516 int get _reportArgumentCount; |
518 | 517 |
519 open(callback) { | 518 open(callback) { |
520 if (_isOpen || _isClosed) { | 519 if (_isOpen || _isClosed) { |
521 throw new StateError('Observer has already been opened.'); | 520 throw new StateError('Observer has already been opened.'); |
522 } | 521 } |
(...skipping 18 matching lines...) Expand all Loading... |
541 _disconnect(); | 540 _disconnect(); |
542 _value = null; | 541 _value = null; |
543 _notifyCallback = null; | 542 _notifyCallback = null; |
544 } | 543 } |
545 | 544 |
546 _discardChanges() { | 545 _discardChanges() { |
547 _check(skipChanges: true); | 546 _check(skipChanges: true); |
548 return _value; | 547 return _value; |
549 } | 548 } |
550 | 549 |
551 bool deliver() => _isOpen ? _dirtyCheck() : false; | 550 void deliver() { |
| 551 if (_isOpen) _dirtyCheck(); |
| 552 } |
552 | 553 |
553 bool _dirtyCheck() { | 554 bool _dirtyCheck() { |
554 var cycles = 0; | 555 var cycles = 0; |
555 while (cycles < _MAX_DIRTY_CHECK_CYCLES && _check()) { | 556 while (cycles < _MAX_DIRTY_CHECK_CYCLES && _check()) { |
556 cycles++; | 557 cycles++; |
557 } | 558 } |
558 return cycles > 0; | 559 return cycles > 0; |
559 } | 560 } |
560 | 561 |
561 void _report(newValue, oldValue, [extraArg]) { | 562 void _report(newValue, oldValue, [extraArg]) { |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
671 for (var observer in _observers.values.toList(growable: false)) { | 672 for (var observer in _observers.values.toList(growable: false)) { |
672 if (observer._isOpen) observer._check(); | 673 if (observer._isOpen) observer._check(); |
673 } | 674 } |
674 | 675 |
675 _resetNeeded = true; | 676 _resetNeeded = true; |
676 scheduleMicrotask(reset); | 677 scheduleMicrotask(reset); |
677 } | 678 } |
678 } | 679 } |
679 | 680 |
680 const int _MAX_DIRTY_CHECK_CYCLES = 1000; | 681 const int _MAX_DIRTY_CHECK_CYCLES = 1000; |
OLD | NEW |