Chromium Code Reviews| Index: runtime/observatory/lib/src/elements/helpers/rendering_scheduler.dart |
| diff --git a/runtime/observatory/lib/src/elements/helpers/rendering_scheduler.dart b/runtime/observatory/lib/src/elements/helpers/rendering_scheduler.dart |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..100c9b51280fff0528646754a3f5188f01e624d4 |
| --- /dev/null |
| +++ b/runtime/observatory/lib/src/elements/helpers/rendering_scheduler.dart |
| @@ -0,0 +1,108 @@ |
| +// Copyright (c) 2016, 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. |
| + |
| +import 'dart:async'; |
| + |
| +import 'package:observatory/src/elements/helpers/rendering_queue.dart'; |
| +export 'package:observatory/src/elements/helpers/rendering_queue.dart'; |
| + |
| +/// A generic renderable object. |
| +abstract class Renderable { |
| + void render(); |
| +} |
| + |
| +/// Even related to a Renderable rendering phase. |
|
Cutch
2016/07/18 17:36:39
Event
cbernaschina
2016/07/18 17:39:29
Done.
|
| +class RenderedEvent<T extends Renderable> { |
| + /// Renderable to which the event is related |
| + final T element; |
| + /// Is another rendering scheduled for this element. |
| + final bool otherRenderScheduled; |
| + |
| + RenderedEvent(this.element, this.otherRenderScheduled) { |
| + assert(element != null); |
| + assert(otherRenderScheduled != null); |
| + } |
| +} |
| + |
| +/// Scheduler for rendering operations. |
| +class RenderingScheduler<T extends Renderable> implements RenderingTask { |
| + bool _enabled = false; |
| + bool _dirty = false; |
| + bool _renderingScheduled = false; |
| + bool _notificationScheduled = false; |
| + /// Element managed by this scheduler. |
| + final T element; |
| + /// Queue used for rendering operations. |
| + final RenderingQueue queue; |
| + |
| + final StreamController<RenderedEvent<T>> _onRendered = |
| + new StreamController<RenderedEvent<T>>.broadcast(); |
| + Stream<RenderedEvent<T>> get onRendered => _onRendered.stream; |
| + |
| + /// Creates a new scheduler for an element. |
| + /// If no queue is provided it will create a new default configured queue. |
| + factory RenderingScheduler(T element, {RenderingQueue queue}) { |
| + assert(element != null); |
| + if (queue == null) { queue = new RenderingQueue(); } |
| + return new RenderingScheduler<T>._(element, queue); |
| + } |
| + |
| + RenderingScheduler._(this.element, this.queue); |
| + |
| + /// Enable the scheduler. |
| + /// New dirty or schedule request will be considered. |
| + void enable() { |
| + if (_enabled) return; |
| + _enabled = true; |
| + scheduleRendering(); |
| + } |
| + |
| + /// Disable the scheduler. |
| + /// New dirty or schedule request will be discarded. |
| + /// [optional] notify: send a final RenderEvent. |
| + void disable({bool notify: false}) { |
| + assert(notify != null); |
| + if (!_enabled) return; |
| + _enabled = false; |
| + if (notify) scheduleNotification(); |
| + } |
| + |
| + /// Set the object as dirty. A rendering will be scheduled. |
| + void dirty() { |
| + if (_dirty) return; |
| + _dirty = true; |
| + scheduleRendering(); |
| + } |
| + |
| + /// Schedules a new rendering phase. |
| + void scheduleRendering() { |
| + if (_renderingScheduled) return; |
| + if (!_enabled) return; |
| + queue.enqueue(this); |
| + _renderingScheduled = true; |
| + } |
| + |
| + /// Renders the element (if the scheduler is enabled). |
| + /// It will clear the dirty flag. |
| + void render(){ |
|
Cutch
2016/07/18 17:36:39
() {
cbernaschina
2016/07/18 17:39:29
Done.
|
| + if (!_enabled) return; |
| + _dirty = false; |
| + element.render(); |
| + _renderingScheduled = false; |
| + scheduleNotification(); |
| + if (_dirty) scheduleRendering(); |
| + } |
| + |
| + /// Schedules a notification. |
| + void scheduleNotification() { |
| + if (_notificationScheduled) return; |
| + _notify(); |
| + _notificationScheduled = true; |
| + } |
| + |
| + Future _notify() async { |
| + _onRendered.add(new RenderedEvent<T>(element, _dirty)); |
| + _notificationScheduled = false; |
| + } |
| +} |