13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2011 the V8 project authors. All rights reserved.
23ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Redistribution and use in source and binary forms, with or without
33ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// modification, are permitted provided that the following conditions are
43ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// met:
53ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//
63ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//     * Redistributions of source code must retain the above copyright
73ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//       notice, this list of conditions and the following disclaimer.
83ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//     * Redistributions in binary form must reproduce the above
93ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//       copyright notice, this list of conditions and the following
103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//       disclaimer in the documentation and/or other materials provided
113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//       with the distribution.
123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//     * Neither the name of Google Inc. nor the names of its
133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//       contributors may be used to endorse or promote products derived
143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//       from this software without specific prior written permission.
153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//
163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch/**
303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch * This function provides requestAnimationFrame in a cross browser way.
313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch * http://paulirish.com/2011/requestanimationframe-for-smart-animating/
323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch */
333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochif ( !window.requestAnimationFrame ) {
343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  window.requestAnimationFrame = ( function() {
353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return window.webkitRequestAnimationFrame ||
363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        window.mozRequestAnimationFrame ||
373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        window.oRequestAnimationFrame ||
383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        window.msRequestAnimationFrame ||
393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        function(callback, element) {
403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          window.setTimeout( callback, 1000 / 60 );
413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        };
423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  } )();
433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvar kNPoints = 8000;
463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvar kNModifications = 20;
473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvar kNVisiblePoints = 200;
483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvar kDecaySpeed = 20;
493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvar kPointRadius = 4;
513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvar kInitialLifeForce = 100;
523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvar livePoints = void 0;
543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvar dyingPoints = void 0;
553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvar scene = void 0;
563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvar renderingStartTime = void 0;
573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvar scene = void 0;
583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvar pausePlot = void 0;
593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvar splayTree = void 0;
603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvar numberOfFrames = 0;
613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvar sumOfSquaredPauses = 0;
623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvar benchmarkStartTime = void 0;
633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvar benchmarkTimeLimit = void 0;
643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvar autoScale = void 0;
653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvar pauseDistribution = [];
663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochfunction Point(x, y, z, payload) {
693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.x = x;
703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.y = y;
713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.z = z;
723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.next = null;
743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.prev = null;
753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.payload = payload;
763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.lifeForce = kInitialLifeForce;
773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
803ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochPoint.prototype.color = function () {
813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return "rgba(0, 0, 0, " + (this.lifeForce / kInitialLifeForce) + ")";
823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch};
833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
853ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochPoint.prototype.decay = function () {
863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.lifeForce -= kDecaySpeed;
873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return this.lifeForce <= 0;
883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch};
893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochfunction PointsList() {
923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.head = null;
933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.count = 0;
943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
973ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochPointsList.prototype.add = function (point) {
983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (this.head !== null) this.head.prev = point;
993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  point.next = this.head;
1003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.head = point;
1013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.count++;
1023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
1033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1053ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochPointsList.prototype.remove = function (point) {
1063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (point.next !== null) {
1073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    point.next.prev = point.prev;
1083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
1093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (point.prev !== null) {
1103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    point.prev.next = point.next;
1113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  } else {
1123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    this.head = point.next;
1133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
1143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.count--;
1153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
1163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochfunction GeneratePayloadTree(depth, tag) {
1193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (depth == 0) {
1203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return {
1213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      array  : [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ],
1223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      string : 'String for key ' + tag + ' in leaf node'
1233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    };
1243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  } else {
1253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return {
1263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      left:  GeneratePayloadTree(depth - 1, tag),
1273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      right: GeneratePayloadTree(depth - 1, tag)
1283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    };
1293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
1303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
1313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// To make the benchmark results predictable, we replace Math.random
1343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// with a 100% deterministic alternative.
1353ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochMath.random = (function() {
1363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  var seed = 49734321;
1373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return function() {
1383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // Robert Jenkins' 32 bit integer hash function.
1393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    seed = ((seed + 0x7ed55d16) + (seed << 12))  & 0xffffffff;
1403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    seed = ((seed ^ 0xc761c23c) ^ (seed >>> 19)) & 0xffffffff;
1413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    seed = ((seed + 0x165667b1) + (seed << 5))   & 0xffffffff;
1423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    seed = ((seed + 0xd3a2646c) ^ (seed << 9))   & 0xffffffff;
1433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    seed = ((seed + 0xfd7046c5) + (seed << 3))   & 0xffffffff;
1443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    seed = ((seed ^ 0xb55a4f09) ^ (seed >>> 16)) & 0xffffffff;
1453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return (seed & 0xfffffff) / 0x10000000;
1463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  };
1473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch})();
1483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochfunction GenerateKey() {
1513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // The benchmark framework guarantees that Math.random is
1523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // deterministic; see base.js.
1533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return Math.random();
1543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
1553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochfunction CreateNewPoint() {
1573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Insert new node with a unique key.
1583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  var key;
1593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  do { key = GenerateKey(); } while (splayTree.find(key) != null);
1603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  var point = new Point(Math.random() * 40 - 20,
1623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                        Math.random() * 40 - 20,
1633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                        Math.random() * 40 - 20,
1643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                        GeneratePayloadTree(5, "" + key));
1653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  livePoints.add(point);
1673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  splayTree.insert(key, point);
1693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return key;
1703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
1713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochfunction ModifyPointsSet() {
1733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (livePoints.count < kNPoints) {
1743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    for (var i = 0; i < kNModifications; i++) {
1753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      CreateNewPoint();
1763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
1773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  } else if (kNModifications === 20) {
1783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    kNModifications = 80;
1793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    kDecay = 30;
1803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
1813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  for (var i = 0; i < kNModifications; i++) {
1833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    var key = CreateNewPoint();
1843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    var greatest = splayTree.findGreatestLessThan(key);
1853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (greatest == null) {
1863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      var point = splayTree.remove(key).value;
1873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    } else {
1883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      var point = splayTree.remove(greatest.key).value;
1893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
1903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    livePoints.remove(point);
1913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    point.payload = null;
1923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    dyingPoints.add(point);
1933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
1943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
1953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochfunction PausePlot(width, height, size, scale) {
1983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  var canvas = document.createElement("canvas");
1993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  canvas.width = this.width = width;
2003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  canvas.height = this.height = height;
2013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  document.body.appendChild(canvas);
2023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.ctx = canvas.getContext('2d');
2043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (typeof scale !== "number") {
2063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    this.autoScale = true;
2073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    this.maxPause = 0;
2083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  } else {
2093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    this.autoScale = false;
2103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    this.maxPause = scale;
2113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
2123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.size = size;
2143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Initialize cyclic buffer for pauses.
2163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.pauses = new Array(this.size);
2173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.start = this.size;
2183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.idx = 0;
2193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
2203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2223ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochPausePlot.prototype.addPause = function (p) {
2233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (this.idx === this.size) {
2243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    this.idx = 0;
2253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
2263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (this.idx === this.start) {
2283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    this.start++;
2293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
2303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (this.start === this.size) {
2323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    this.start = 0;
2333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
2343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.pauses[this.idx++] = p;
2363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch};
2373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2393ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochPausePlot.prototype.iteratePauses = function (f) {
2403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (this.start < this.idx) {
2413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    for (var i = this.start; i < this.idx; i++) {
2423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      f.call(this, i - this.start, this.pauses[i]);
2433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
2443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  } else {
2453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    for (var i = this.start; i < this.size; i++) {
2463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      f.call(this, i - this.start, this.pauses[i]);
2473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
2483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    var offs = this.size - this.start;
2503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    for (var i = 0; i < this.idx; i++) {
2513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      f.call(this, i + offs, this.pauses[i]);
2523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
2533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
2543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch};
2553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2573ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochPausePlot.prototype.draw = function () {
2583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  var first = null;
2593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (this.autoScale) {
2613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    this.iteratePauses(function (i, v) {
2623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      if (first === null) {
2633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        first = v;
2643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      }
2653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      this.maxPause = Math.max(v, this.maxPause);
2663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    });
2673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
2683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  var dx = this.width / this.size;
2703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  var dy = this.height / this.maxPause;
2713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.ctx.save();
2733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.ctx.clearRect(0, 0, this.width, this.height);
2743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.ctx.beginPath();
2753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.ctx.moveTo(1, dy * this.pauses[this.start]);
2763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  var p = first;
2773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.iteratePauses(function (i, v) {
2783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    var delta = v - p;
2793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    var x = 1 + dx * i;
2803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    var y = dy * v;
2813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    this.ctx.lineTo(x, y);
2823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (delta > 2 * (p / 3)) {
2833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      this.ctx.font = "bold 12px sans-serif";
2843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      this.ctx.textBaseline = "bottom";
2853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      this.ctx.fillText(v + "ms", x + 2, y);
2863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
2873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    p = v;
2883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  });
2893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.ctx.strokeStyle = "black";
2903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.ctx.stroke();
2913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.ctx.restore();
2923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
2933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochfunction Scene(width, height) {
2963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  var canvas = document.createElement("canvas");
2973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  canvas.width = width;
2983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  canvas.height = height;
2993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  document.body.appendChild(canvas);
3003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.ctx = canvas.getContext('2d');
3023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.width = canvas.width;
3033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.height = canvas.height;
3043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Projection configuration.
3063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.x0 = canvas.width / 2;
3073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.y0 = canvas.height / 2;
3083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.z0 = 100;
3093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.f  = 1000;  // Focal length.
3103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Camera is rotating around y-axis.
3123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.angle = 0;
3133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
3143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3163ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochScene.prototype.drawPoint = function (x, y, z, color) {
3173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Rotate the camera around y-axis.
3183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  var rx = x * Math.cos(this.angle) - z * Math.sin(this.angle);
3193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  var ry = y;
3203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  var rz = x * Math.sin(this.angle) + z * Math.cos(this.angle);
3213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Perform perspective projection.
3233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  var px = (this.f * rx) / (rz - this.z0) + this.x0;
3243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  var py = (this.f * ry) / (rz - this.z0) + this.y0;
3253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.ctx.save();
3273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.ctx.fillStyle = color
3283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.ctx.beginPath();
3293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.ctx.arc(px, py, kPointRadius, 0, 2 * Math.PI, true);
3303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.ctx.fill();
3313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.ctx.restore();
3323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch};
3333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3353ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochScene.prototype.drawDyingPoints = function () {
3363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  var point_next = null;
3373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  for (var point = dyingPoints.head; point !== null; point = point_next) {
3383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // Rotate the scene around y-axis.
3393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    scene.drawPoint(point.x, point.y, point.z, point.color());
3403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    point_next = point.next;
3423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // Decay the current point and remove it from the list
3443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // if it's life-force ran out.
3453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (point.decay()) {
3463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      dyingPoints.remove(point);
3473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
3483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
3493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch};
3503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3523ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochScene.prototype.draw = function () {
3533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.ctx.save();
3543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.ctx.clearRect(0, 0, this.width, this.height);
3553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.drawDyingPoints();
3563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.ctx.restore();
3573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.angle += Math.PI / 90.0;
3593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch};
3603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochfunction updateStats(pause) {
3633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  numberOfFrames++;
3643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (pause > 20) {
3653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    sumOfSquaredPauses += (pause - 20) * (pause - 20);
3663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
3673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  pauseDistribution[Math.floor(pause / 10)] |= 0;
3683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  pauseDistribution[Math.floor(pause / 10)]++;
3693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
3703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochfunction renderStats() {
3733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  var msg = document.createElement("p");
3743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  msg.innerHTML = "Score " +
3753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Math.round(numberOfFrames * 1000 / sumOfSquaredPauses);
3763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  var table = document.createElement("table");
3773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  table.align = "center";
3783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  for (var i = 0; i < pauseDistribution.length; i++) {
3793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (pauseDistribution[i] > 0) {
3803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      var row = document.createElement("tr");
3813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      var time = document.createElement("td");
3823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      var count = document.createElement("td");
3833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      time.innerHTML = i*10 + "-" + (i+1)*10 + "ms";
3843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      count.innerHTML = " => " + pauseDistribution[i];
3853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      row.appendChild(time);
3863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      row.appendChild(count);
3873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      table.appendChild(row);
3883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
3893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
3903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  div.appendChild(msg);
3913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  div.appendChild(table);
3923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
3933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochfunction render() {
3963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (typeof renderingStartTime === 'undefined') {
3973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    renderingStartTime = Date.now();
3983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    benchmarkStartTime = renderingStartTime;
3993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
4003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ModifyPointsSet();
4023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  scene.draw();
4043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  var renderingEndTime = Date.now();
4063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  var pause = renderingEndTime - renderingStartTime;
4073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  pausePlot.addPause(pause);
4083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  renderingStartTime = renderingEndTime;
4093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  pausePlot.draw();
4113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  updateStats(pause);
4133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  div.innerHTML =
4153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      livePoints.count + "/" + dyingPoints.count + " " +
4163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      pause + "(max = " + pausePlot.maxPause + ") ms " +
4173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      numberOfFrames + " frames";
4183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (renderingEndTime < benchmarkStartTime + benchmarkTimeLimit) {
4203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // Schedule next frame.
4213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    requestAnimationFrame(render);
4223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  } else {
4233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    renderStats();
4243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
4253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
4263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochfunction Form() {
4293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  function create(tag) { return document.createElement(tag); }
4303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  function text(value) { return document.createTextNode(value); }
4313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.form = create("form");
4333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.form.setAttribute("action", "javascript:start()");
4343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  var table = create("table");
4363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  table.setAttribute("style", "margin-left: auto; margin-right: auto;");
4373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  function col(a) {
4393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    var td = create("td");
4403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    td.appendChild(a);
4413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return td;
4423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
4433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  function row(a, b) {
4453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    var tr = create("tr");
4463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    tr.appendChild(col(a));
4473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    tr.appendChild(col(b));
4483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return tr;
4493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
4503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.timelimit = create("input");
4523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.timelimit.setAttribute("value", "60");
4533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  table.appendChild(row(text("Time limit in seconds"), this.timelimit));
4553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.autoscale = create("input");
4573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.autoscale.setAttribute("type", "checkbox");
4583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.autoscale.setAttribute("checked", "true");
4593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  table.appendChild(row(text("Autoscale pauses plot"), this.autoscale));
4603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  var button = create("input");
4623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  button.setAttribute("type", "submit");
4633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  button.setAttribute("value", "Start");
4643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.form.appendChild(table);
4653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.form.appendChild(button);
4663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  document.body.appendChild(this.form);
4683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
4693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4713ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochForm.prototype.remove = function () {
4723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  document.body.removeChild(this.form);
4733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch};
4743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochfunction init() {
4773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  livePoints = new PointsList;
4783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  dyingPoints = new PointsList;
4793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  splayTree = new SplayTree();
4813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  scene = new Scene(640, 480);
4833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  div = document.createElement("div");
4853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  document.body.appendChild(div);
4863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  pausePlot = new PausePlot(480, autoScale ? 240 : 500, 160, autoScale ? void 0 : 500);
4883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
4893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochfunction start() {
4913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  benchmarkTimeLimit = form.timelimit.value * 1000;
4923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  autoScale = form.autoscale.checked;
4933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  form.remove();
4943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  init();
4953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  render();
4963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
4973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvar form = new Form();
499