| OLD | NEW |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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 import 'dart:async'; | 5 import 'dart:async'; |
| 6 | 6 |
| 7 import 'package:observatory/src/elements/helpers/rendering_queue.dart'; | 7 import 'package:observatory/src/elements/helpers/rendering_queue.dart'; |
| 8 export 'package:observatory/src/elements/helpers/rendering_queue.dart'; | 8 export 'package:observatory/src/elements/helpers/rendering_queue.dart'; |
| 9 | 9 |
| 10 /// A generic renderable object. | 10 /// A generic renderable object. |
| 11 abstract class Renderable { | 11 abstract class Renderable { |
| 12 void render(); | 12 void render(); |
| 13 } | 13 } |
| 14 | 14 |
| 15 /// Event related to a Renderable rendering phase. | 15 /// Event related to a Renderable rendering phase. |
| 16 class RenderedEvent<T> { | 16 class RenderedEvent<T> { |
| 17 /// Renderable to which the event is related | 17 /// Renderable to which the event is related |
| 18 final T element; | 18 final T element; |
| 19 |
| 19 /// Is another rendering scheduled for this element. | 20 /// Is another rendering scheduled for this element. |
| 20 final bool otherRenderScheduled; | 21 final bool otherRenderScheduled; |
| 21 | 22 |
| 22 RenderedEvent(this.element, this.otherRenderScheduled) { | 23 RenderedEvent(this.element, this.otherRenderScheduled) { |
| 23 assert(element != null); | 24 assert(element != null); |
| 24 assert(otherRenderScheduled != null); | 25 assert(otherRenderScheduled != null); |
| 25 } | 26 } |
| 26 } | 27 } |
| 27 | 28 |
| 28 /// Scheduler for rendering operations. | 29 /// Scheduler for rendering operations. |
| 29 class RenderingScheduler<T extends Renderable> implements RenderingTask { | 30 class RenderingScheduler<T extends Renderable> implements RenderingTask { |
| 30 bool _enabled = false; | 31 bool _enabled = false; |
| 31 bool _dirty = false; | 32 bool _dirty = false; |
| 32 bool _renderingScheduled = false; | 33 bool _renderingScheduled = false; |
| 33 bool _notificationScheduled = false; | 34 bool _notificationScheduled = false; |
| 35 |
| 34 /// Element managed by this scheduler. | 36 /// Element managed by this scheduler. |
| 35 final T element; | 37 final T element; |
| 38 |
| 36 /// Queue used for rendering operations. | 39 /// Queue used for rendering operations. |
| 37 final RenderingQueue queue; | 40 final RenderingQueue queue; |
| 41 |
| 38 /// Does the element need a new rendering cycle. | 42 /// Does the element need a new rendering cycle. |
| 39 bool get isDirty => _dirty; | 43 bool get isDirty => _dirty; |
| 44 |
| 40 /// Is the scheduler enabled. | 45 /// Is the scheduler enabled. |
| 41 bool get isEnabled => _enabled; | 46 bool get isEnabled => _enabled; |
| 42 | 47 |
| 43 final StreamController<RenderedEvent<T>> _onRendered = | 48 final StreamController<RenderedEvent<T>> _onRendered = |
| 44 new StreamController<RenderedEvent<T>>.broadcast(); | 49 new StreamController<RenderedEvent<T>>.broadcast(); |
| 45 Stream<RenderedEvent<T>> get onRendered => _onRendered.stream; | 50 Stream<RenderedEvent<T>> get onRendered => _onRendered.stream; |
| 46 | 51 |
| 47 /// Creates a new scheduler for an element. | 52 /// Creates a new scheduler for an element. |
| 48 /// If no queue is provided it will create a new default configured queue. | 53 /// If no queue is provided it will create a new default configured queue. |
| 49 factory RenderingScheduler(T element, {RenderingQueue queue}) { | 54 factory RenderingScheduler(T element, {RenderingQueue queue}) { |
| 50 assert(element != null); | 55 assert(element != null); |
| 51 if (queue == null) { queue = new RenderingQueue(); } | 56 if (queue == null) { |
| 57 queue = new RenderingQueue(); |
| 58 } |
| 52 return new RenderingScheduler<T>._(element, queue); | 59 return new RenderingScheduler<T>._(element, queue); |
| 53 } | 60 } |
| 54 | 61 |
| 55 RenderingScheduler._(this.element, this.queue); | 62 RenderingScheduler._(this.element, this.queue); |
| 56 | 63 |
| 57 /// Enable the scheduler. | 64 /// Enable the scheduler. |
| 58 /// New dirty or schedule request will be considered. | 65 /// New dirty or schedule request will be considered. |
| 59 void enable() { | 66 void enable() { |
| 60 if (_enabled) return; | 67 if (_enabled) return; |
| 61 _enabled = true; | 68 _enabled = true; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 76 void dirty() { | 83 void dirty() { |
| 77 if (_dirty) return; | 84 if (_dirty) return; |
| 78 _dirty = true; | 85 _dirty = true; |
| 79 scheduleRendering(); | 86 scheduleRendering(); |
| 80 } | 87 } |
| 81 | 88 |
| 82 /// Checks for modification during attribute set. | 89 /// Checks for modification during attribute set. |
| 83 /// If value changes a new rendering is scheduled. | 90 /// If value changes a new rendering is scheduled. |
| 84 /// set attr(T v) => _attr = _r.checkAndReact(_attr, v); | 91 /// set attr(T v) => _attr = _r.checkAndReact(_attr, v); |
| 85 dynamic checkAndReact(dynamic oldValue, dynamic newValue) { | 92 dynamic checkAndReact(dynamic oldValue, dynamic newValue) { |
| 86 if (oldValue != newValue) dirty(); | 93 if (oldValue != newValue) |
| 87 else scheduleNotification(); | 94 dirty(); |
| 95 else |
| 96 scheduleNotification(); |
| 88 return newValue; | 97 return newValue; |
| 89 } | 98 } |
| 90 | 99 |
| 91 /// Schedules a new rendering phase. | 100 /// Schedules a new rendering phase. |
| 92 void scheduleRendering() { | 101 void scheduleRendering() { |
| 93 if (_renderingScheduled) return; | 102 if (_renderingScheduled) return; |
| 94 if (!_enabled) return; | 103 if (!_enabled) return; |
| 95 queue.enqueue(this); | 104 queue.enqueue(this); |
| 96 _renderingScheduled = true; | 105 _renderingScheduled = true; |
| 97 } | 106 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 112 if (_notificationScheduled) return; | 121 if (_notificationScheduled) return; |
| 113 _notify(); | 122 _notify(); |
| 114 _notificationScheduled = true; | 123 _notificationScheduled = true; |
| 115 } | 124 } |
| 116 | 125 |
| 117 Future _notify() async { | 126 Future _notify() async { |
| 118 _onRendered.add(new RenderedEvent<T>(element, _dirty)); | 127 _onRendered.add(new RenderedEvent<T>(element, _dirty)); |
| 119 _notificationScheduled = false; | 128 _notificationScheduled = false; |
| 120 } | 129 } |
| 121 } | 130 } |
| OLD | NEW |