| 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..75e13dede1660060cd394519c7f0ebf84d736741
|
| --- /dev/null
|
| +++ b/runtime/observatory/lib/src/elements/helpers/rendering_scheduler.dart
|
| @@ -0,0 +1,88 @@
|
| +// 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';
|
| +
|
| +abstract class Renderable {
|
| + void render();
|
| +}
|
| +
|
| +class RenderedEvent<T> {
|
| + final T element;
|
| + final bool otherRenderScheduled;
|
| + RenderedEvent(this.element, this.otherRenderScheduled);
|
| +}
|
| +
|
| +class RenderingScheduler<T extends Renderable> implements RenderingTask {
|
| + bool _enabled = false;
|
| + bool _dirty = false;
|
| + bool _scheduledRendering = false;
|
| + bool _scheduledNotification = false;
|
| + final T element;
|
| + final RenderingQueue queue;
|
| +
|
| + final StreamController<RenderedEvent<T>> _onRendered;
|
| + final Stream<RenderedEvent<T>> onRendered;
|
| +
|
| + factory RenderingScheduler(T element, {RenderingQueue queue}) {
|
| + assert(element != null);
|
| + if (queue == null) {
|
| + queue = new RenderingQueue();
|
| + }
|
| + var controller = new StreamController<RenderedEvent<T>>();
|
| + var stream = controller.stream.asBroadcastStream();
|
| + return new RenderingScheduler<T>._(element, queue, controller, stream);
|
| + }
|
| +
|
| + RenderingScheduler._(this.element, this.queue, this._onRendered,
|
| + this.onRendered);
|
| +
|
| + void enable() {
|
| + if (_enabled) return;
|
| + _enabled = true;
|
| + scheduleRendering();
|
| + }
|
| +
|
| + void disable({bool notify: false}) {
|
| + if (!_enabled) return;
|
| + _enabled = false;
|
| + if (notify) scheduleNotification();
|
| + }
|
| +
|
| + void dirty() {
|
| + if (_dirty) return;
|
| + _dirty = true;
|
| + scheduleRendering();
|
| + }
|
| +
|
| + void scheduleRendering() {
|
| + if (_scheduledRendering) return;
|
| + if (!_enabled) return;
|
| + queue.enqueue(this);
|
| + _scheduledRendering = true;
|
| + }
|
| +
|
| + void render(){
|
| + if (!_enabled) return;
|
| + _dirty = false;
|
| + element.render();
|
| + _scheduledRendering = false;
|
| + scheduleNotification();
|
| + if (_dirty) scheduleRendering();
|
| + }
|
| +
|
| + void scheduleNotification() {
|
| + if (_scheduledNotification) return;
|
| + _notify();
|
| + _scheduledNotification = true;
|
| + }
|
| +
|
| + Future _notify() async {
|
| + _onRendered.add(new RenderedEvent<T>(element, _dirty));
|
| + _scheduledNotification = false;
|
| + }
|
| +}
|
|
|