Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(14)

Unified Diff: client/html/src/Measurement.dart

Issue 8363040: Implement measurement using futures (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: take2 Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: client/html/src/Measurement.dart
diff --git a/client/html/src/Measurement.dart b/client/html/src/Measurement.dart
new file mode 100644
index 0000000000000000000000000000000000000000..a48cf226776744840e8e4734d9a4116501ddb289
--- /dev/null
+++ b/client/html/src/Measurement.dart
@@ -0,0 +1,99 @@
+// Copyright (c) 2011, 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.
+
+typedef Object ComputeValue();
+
+class MeasurementRequest<T> {
+ final ComputeValue computeValue;
+ final Completer<T> completer;
+ Object value;
+ bool exception = false;
+ MeasurementRequest(this.computeValue, this.completer);
+}
+
+final _MEASUREMENT_MESSAGE = "DART-MEASURE";
+List<MeasurementRequest> _pendingRequests;
+List<TimeoutHandler> _pendingMeasurementFrameCallbacks;
+bool _nextMeasurementFrameScheduled = false;
+bool _firstMeasurementRequest = true;
+
+void _maybeScheduleMeasurementFrame() {
+ if (_nextMeasurementFrameScheduled == false) {
arv (Not doing code reviews) 2011/10/27 05:50:24 if (!_nextMeasurementFrameScheduled) {
Jacob 2011/10/27 20:59:25 Done.
+ _nextMeasurementFrameScheduled = true;
+ // postMessage gives us a way to receive a callback after the current
+ // event listener has unwound but before the browser has repainted.
+ if (_firstMeasurementRequest) {
+ // Messages from other windows do not cause a security risk as
arv (Not doing code reviews) 2011/10/27 05:50:24 as as
Jacob 2011/10/27 20:59:25 as as ==> as all done done
+ // as we care about is that _onCompleteMeasurementRequests is called
+ // after the current event loop is unwound and calling the function is
+ // a noop if no requests are pending.
+ window.on.message.add(Isolate.bind(
arv (Not doing code reviews) 2011/10/27 05:50:24 If anyone else is listening to on message they wil
Jacob 2011/10/27 20:59:25 Do you have any ideas? Creating an iframe just for
+ (e) => _onCompleteMeasurementFutures()
+ ));
+ _firstMeasurementRequest = false;
+ }
+
+ // TODO(jacobr): other mechanisms such as setImmediate and
+ // requestAnimationFrame may work better of platforms that support them.
+ // The key is we need a way to execute code immediately after the current
+ // event listener queue unwinds.
+ window.postMessage(_MEASUREMENT_MESSAGE, "*");
+ }
+}
+
+void _addMeasurementFrameCallback(TimeoutHandler callback) {
+ if (null == _pendingMeasurementFrameCallbacks) {
+ _pendingMeasurementFrameCallbacks = <TimeoutHandler>[];
+ _maybeScheduleMeasurementFrame();
+ }
+ _pendingMeasurementFrameCallbacks.add(callback);
+}
+
+Future _createMeasurementFuture(ComputeValue computeValue, Completer completer) {
arv (Not doing code reviews) 2011/10/27 05:50:24 long line
Jacob 2011/10/27 20:59:25 Done.
+ if (null == _pendingRequests) {
+ _pendingRequests = <MeasurementRequest>[];
+ _maybeScheduleMeasurementFrame();
+ }
+ _pendingRequests.add(new MeasurementRequest(computeValue, completer));
+ return completer.future;
+}
+
+void _onCompleteMeasurementFutures() {
+ if (_nextMeasurementFrameScheduled == false) {
+ // Ignore spurious call to this function.
+ return;
+ }
+
+ _nextMeasurementFrameScheduled = false;
+ // We must compute all new values before fulfilling the futures as
+ // the onComplete callbacks for the futures could modify the DOM making
+ // subsequent measurement calculations expensive to compute.
+ for (MeasurementRequest request in _pendingRequests) {
+ try {
+ request.value = request.computeValue();
+ } catch(var e) {
+ request.value = e;
+ request.exception = true;
+ }
+ }
+
+ final completedRequests = _pendingRequests;
+ final readyMeasurementFrameCallbacks = _pendingMeasurementFrameCallbacks;
+ _pendingRequests = null;
+ _pendingMeasurementFrameCallbacks = null;
+ for (MeasurementRequest request in completedRequests) {
+ if (request.exception) {
+ request.completer.completeException(request.value);
+ } else {
+ request.completer.complete(request.value);
+ }
+ }
+
+ if (null != readyMeasurementFrameCallbacks) {
+ for (TimeoutHandler handler in readyMeasurementFrameCallbacks) {
+ // TODO(jacobr): wrap each call to a handler in a try-catch block.
+ handler();
+ }
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698