Change LICENSE to BSD (#69)
diff --git a/LICENSE b/LICENSE
index ff99443..db5bf46 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,5 +1,26 @@
-Harness:
-Copyright 2012 Google LLC
+Copyright 2021, the Dart project authors.
-Individual benchmarks:
-Each benchmark has an author and license. See benchmark source for details.
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of Google LLC nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
diff --git a/example/DeltaBlue.dart b/example/DeltaBlue.dart
deleted file mode 100644
index 02fb696..0000000
--- a/example/DeltaBlue.dart
+++ /dev/null
@@ -1,710 +0,0 @@
-// @dart=2.8
-// Copyright 2011 Google Inc. All Rights Reserved.
-// Copyright 1996 John Maloney and Mario Wolczko
-//
-// This file is part of GNU Smalltalk.
-//
-// GNU Smalltalk is free software; you can redistribute it and/or modify it
-// under the terms of the GNU General Public License as published by the Free
-// Software Foundation; either version 2, or (at your option) any later version.
-//
-// GNU Smalltalk is distributed in the hope that it will be useful, but WITHOUT
-// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-// details.
-//
-// You should have received a copy of the GNU General Public License along with
-// GNU Smalltalk; see the file COPYING. If not, write to the Free Software
-// Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-//
-// Translated first from Smalltalk to JavaScript, and finally to
-// Dart by Google 2008-2010.
-
-/// A Dart implementation of the DeltaBlue constraint-solving
-/// algorithm, as described in:
-///
-/// "The DeltaBlue Algorithm: An Incremental Constraint Hierarchy Solver"
-/// Bjorn N. Freeman-Benson and John Maloney
-/// January 1990 Communications of the ACM,
-/// also available as University of Washington TR 89-08-06.
-///
-/// Beware: this benchmark is written in a grotesque style where
-/// the constraint model is built by side-effects from constructors.
-/// I've kept it this way to avoid deviating too much from the original
-/// implementation.
-
-import 'package:benchmark_harness/benchmark_harness.dart';
-
-/// algorithm, as described in:
-///
-/// "The DeltaBlue Algorithm: An Incremental Constraint Hierarchy Solver"
-/// Bjorn N. Freeman-Benson and John Maloney
-/// January 1990 Communications of the ACM,
-/// also available as University of Washington TR 89-08-06.
-///
-/// Beware: this benchmark is written in a grotesque style where
-/// the constraint model is built by side-effects from constructors.
-/// I've kept it this way to avoid deviating too much from the original
-/// implementation.
-
-void main() {
- const DeltaBlue().report();
-}
-
-/// Benchmark class required to report results.
-class DeltaBlue extends BenchmarkBase {
- const DeltaBlue() : super('DeltaBlue');
-
- @override
- void run() {
- chainTest(100);
- projectionTest(100);
- }
-}
-
-/// Strengths are used to measure the relative importance of constraints.
-/// New strengths may be inserted in the strength hierarchy without
-/// disrupting current constraints. Strengths cannot be created outside
-/// this class, so == can be used for value comparison.
-class Strength {
- final int value;
- final String name;
-
- const Strength(this.value, this.name);
-
- Strength nextWeaker() => const <Strength>[
- WEAKEST,
- WEAK_DEFAULT,
- NORMAL,
- STRONG_DEFAULT,
- PREFERRED,
- STRONG_REFERRED
- ][value];
-
- static bool stronger(Strength s1, Strength s2) {
- return s1.value < s2.value;
- }
-
- static bool weaker(Strength s1, Strength s2) {
- return s1.value > s2.value;
- }
-
- static Strength weakest(Strength s1, Strength s2) {
- return weaker(s1, s2) ? s1 : s2;
- }
-
- static Strength strongest(Strength s1, Strength s2) {
- return stronger(s1, s2) ? s1 : s2;
- }
-}
-
-// Compile time computed constants.
-const REQUIRED = Strength(0, 'required');
-const STRONG_REFERRED = Strength(1, 'strongPreferred');
-const PREFERRED = Strength(2, 'preferred');
-const STRONG_DEFAULT = Strength(3, 'strongDefault');
-const NORMAL = Strength(4, 'normal');
-const WEAK_DEFAULT = Strength(5, 'weakDefault');
-const WEAKEST = Strength(6, 'weakest');
-
-abstract class Constraint {
- final Strength strength;
-
- const Constraint(this.strength);
-
- bool isSatisfied();
-
- void markUnsatisfied();
-
- void addToGraph();
-
- void removeFromGraph();
-
- void chooseMethod(int mark);
-
- void markInputs(int mark);
-
- bool inputsKnown(int mark);
-
- Variable output();
-
- void execute();
-
- void recalculate();
-
- /// Activate this constraint and attempt to satisfy it.
- void addConstraint() {
- addToGraph();
- planner.incrementalAdd(this);
- }
-
- /// Attempt to find a way to enforce this constraint. If successful,
- /// record the solution, perhaps modifying the current dataflow
- /// graph. Answer the constraint that this constraint overrides, if
- /// there is one, or nil, if there isn't.
- /// Assume: I am not already satisfied.
- Constraint satisfy(int mark) {
- chooseMethod(mark);
- if (!isSatisfied()) {
- if (strength == REQUIRED) {
- print('Could not satisfy a required constraint!');
- }
- return null;
- }
- markInputs(mark);
- var out = output();
- var overridden = out.determinedBy;
- if (overridden != null) overridden.markUnsatisfied();
- out.determinedBy = this;
- if (!planner.addPropagate(this, mark)) print('Cycle encountered');
- out.mark = mark;
- return overridden;
- }
-
- void destroyConstraint() {
- if (isSatisfied()) planner.incrementalRemove(this);
- removeFromGraph();
- }
-
- /// Normal constraints are not input constraints. An input constraint
- /// is one that depends on external state, such as the mouse, the
- /// keybord, a clock, or some arbitraty piece of imperative code.
- bool isInput() => false;
-}
-
-/// Abstract superclass for constraints having a single possible output variable.
-abstract class UnaryConstraint extends Constraint {
- final Variable myOutput;
- bool satisfied = false;
-
- UnaryConstraint(this.myOutput, Strength strength) : super(strength) {
- addConstraint();
- }
-
- /// Adds this constraint to the constraint graph
- @override
- void addToGraph() {
- myOutput.addConstraint(this);
- satisfied = false;
- }
-
- /// Decides if this constraint can be satisfied and records that decision.
- @override
- void chooseMethod(int mark) {
- satisfied = (myOutput.mark != mark) &&
- Strength.stronger(strength, myOutput.walkStrength);
- }
-
- /// Returns true if this constraint is satisfied in the current solution.
- @override
- bool isSatisfied() => satisfied;
-
- @override
- void markInputs(int mark) {
- // has no inputs.
- }
-
- /// Returns the current output variable.
- @override
- Variable output() => myOutput;
-
- /// Calculate the walkabout strength, the stay flag, and, if it is
- /// 'stay', the value for the current output of this constraint. Assume
- /// this constraint is satisfied.
- @override
- void recalculate() {
- myOutput.walkStrength = strength;
- myOutput.stay = !isInput();
- if (myOutput.stay) execute(); // Stay optimization.
- }
-
- /// Records that this constraint is unsatisfied.
- @override
- void markUnsatisfied() {
- satisfied = false;
- }
-
- @override
- bool inputsKnown(int mark) => true;
-
- @override
- void removeFromGraph() {
- if (myOutput != null) myOutput.removeConstraint(this);
- satisfied = false;
- }
-}
-
-/// Variables that should, with some level of preference, stay the same.
-/// Planners may exploit the fact that instances, if satisfied, will not
-/// change their output during plan execution. This is called "stay
-/// optimization".
-class StayConstraint extends UnaryConstraint {
- StayConstraint(Variable v, Strength str) : super(v, str);
-
- @override
- void execute() {
- // Stay constraints do nothing.
- }
-}
-
-/// A unary input constraint used to mark a variable that the client
-/// wishes to change.
-class EditConstraint extends UnaryConstraint {
- EditConstraint(Variable v, Strength str) : super(v, str);
-
- /// Edits indicate that a variable is to be changed by imperative code.
- @override
- bool isInput() => true;
-
- @override
- void execute() {
- // Edit constraints do nothing.
- }
-}
-
-// Directions.
-const int NONE = 1;
-const int FORWARD = 2;
-const int BACKWARD = 0;
-
-/// Abstract superclass for constraints having two possible output
-/// variables.
-abstract class BinaryConstraint extends Constraint {
- Variable v1;
- Variable v2;
- int direction = NONE;
-
- BinaryConstraint(this.v1, this.v2, Strength strength) : super(strength) {
- addConstraint();
- }
-
- /// Decides if this constraint can be satisfied and which way it
- /// should flow based on the relative strength of the variables related,
- /// and record that decision.
- @override
- void chooseMethod(int mark) {
- if (v1.mark == mark) {
- direction =
- (v2.mark != mark && Strength.stronger(strength, v2.walkStrength))
- ? FORWARD
- : NONE;
- }
- if (v2.mark == mark) {
- direction =
- (v1.mark != mark && Strength.stronger(strength, v1.walkStrength))
- ? BACKWARD
- : NONE;
- }
- if (Strength.weaker(v1.walkStrength, v2.walkStrength)) {
- direction =
- Strength.stronger(strength, v1.walkStrength) ? BACKWARD : NONE;
- } else {
- direction =
- Strength.stronger(strength, v2.walkStrength) ? FORWARD : BACKWARD;
- }
- }
-
- /// Add this constraint to the constraint graph.
- @override
- void addToGraph() {
- v1.addConstraint(this);
- v2.addConstraint(this);
- direction = NONE;
- }
-
- /// Answer true if this constraint is satisfied in the current solution.
- @override
- bool isSatisfied() => direction != NONE;
-
- /// Mark the input variable with the given mark.
- @override
- void markInputs(int mark) {
- input().mark = mark;
- }
-
- /// Returns the current input variable
- Variable input() => direction == FORWARD ? v1 : v2;
-
- /// Returns the current output variable.
- @override
- Variable output() => direction == FORWARD ? v2 : v1;
-
- /// Calculate the walkabout strength, the stay flag, and, if it is
- /// 'stay', the value for the current output of this
- /// constraint. Assume this constraint is satisfied.
- @override
- void recalculate() {
- var ihn = input(), out = output();
- out.walkStrength = Strength.weakest(strength, ihn.walkStrength);
- out.stay = ihn.stay;
- if (out.stay) execute();
- }
-
- /// Record the fact that this constraint is unsatisfied.
- @override
- void markUnsatisfied() {
- direction = NONE;
- }
-
- @override
- bool inputsKnown(int mark) {
- var i = input();
- return i.mark == mark || i.stay || i.determinedBy == null;
- }
-
- @override
- void removeFromGraph() {
- if (v1 != null) v1.removeConstraint(this);
- if (v2 != null) v2.removeConstraint(this);
- direction = NONE;
- }
-}
-
-/// Relates two variables by the linear scaling relationship: "v2 =
-/// (v1 * scale) + offset". Either v1 or v2 may be changed to maintain
-/// this relationship but the scale factor and offset are considered
-/// read-only.
-
-class ScaleConstraint extends BinaryConstraint {
- final Variable scale;
- final Variable offset;
-
- ScaleConstraint(
- Variable src, this.scale, this.offset, Variable dest, Strength strength)
- : super(src, dest, strength);
-
- /// Adds this constraint to the constraint graph.
- @override
- void addToGraph() {
- super.addToGraph();
- scale.addConstraint(this);
- offset.addConstraint(this);
- }
-
- @override
- void removeFromGraph() {
- super.removeFromGraph();
- if (scale != null) scale.removeConstraint(this);
- if (offset != null) offset.removeConstraint(this);
- }
-
- @override
- void markInputs(int mark) {
- super.markInputs(mark);
- scale.mark = offset.mark = mark;
- }
-
- /// Enforce this constraint. Assume that it is satisfied.
- @override
- void execute() {
- if (direction == FORWARD) {
- v2.value = v1.value * scale.value + offset.value;
- } else {
- v1.value = (v2.value - offset.value) ~/ scale.value;
- }
- }
-
- /// Calculate the walkabout strength, the stay flag, and, if it is
- /// 'stay', the value for the current output of this constraint. Assume
- /// this constraint is satisfied.
- @override
- void recalculate() {
- var ihn = input(), out = output();
- out.walkStrength = Strength.weakest(strength, ihn.walkStrength);
- out.stay = ihn.stay && scale.stay && offset.stay;
- if (out.stay) execute();
- }
-}
-
-/// Constrains two variables to have the same value.
-class EqualityConstraint extends BinaryConstraint {
- EqualityConstraint(Variable v1, Variable v2, Strength strength)
- : super(v1, v2, strength);
-
- /// Enforce this constraint. Assume that it is satisfied.
- @override
- void execute() {
- output().value = input().value;
- }
-}
-
-/// A constrained variable. In addition to its value, it maintain the
-/// structure of the constraint graph, the current dataflow graph, and
-/// various parameters of interest to the DeltaBlue incremental
-/// constraint solver.
-class Variable {
- List<Constraint> constraints = <Constraint>[];
- Constraint determinedBy;
- int mark = 0;
- Strength walkStrength = WEAKEST;
- bool stay = true;
- int value;
- final String name;
-
- Variable(this.name, this.value);
-
- /// Add the given constraint to the set of all constraints that refer
- /// this variable.
- void addConstraint(Constraint c) {
- constraints.add(c);
- }
-
- /// Removes all traces of c from this variable.
- void removeConstraint(Constraint c) {
- constraints.removeWhere((e) => c == e);
- if (determinedBy == c) determinedBy = null;
- }
-}
-
-class Planner {
- int currentMark = 0;
-
- /// Attempt to satisfy the given constraint and, if successful,
- /// incrementally update the dataflow graph. Details: If satifying
- /// the constraint is successful, it may override a weaker constraint
- /// on its output. The algorithm attempts to resatisfy that
- /// constraint using some other method. This process is repeated
- /// until either a) it reaches a variable that was not previously
- /// determined by any constraint or b) it reaches a constraint that
- /// is too weak to be satisfied using any of its methods. The
- /// variables of constraints that have been processed are marked with
- /// a unique mark value so that we know where we've been. This allows
- /// the algorithm to avoid getting into an infinite loop even if the
- /// constraint graph has an inadvertent cycle.
- void incrementalAdd(Constraint c) {
- var mark = newMark();
- for (var overridden = c.satisfy(mark);
- overridden != null;
- overridden = overridden.satisfy(mark)) {
- // NOOP
- }
- }
-
- /// Entry point for retracting a constraint. Remove the given
- /// constraint and incrementally update the dataflow graph.
- /// Details: Retracting the given constraint may allow some currently
- /// unsatisfiable downstream constraint to be satisfied. We therefore collect
- /// a list of unsatisfied downstream constraints and attempt to
- /// satisfy each one in turn. This list is traversed by constraint
- /// strength, strongest first, as a heuristic for avoiding
- /// unnecessarily adding and then overriding weak constraints.
- /// Assume: [c] is satisfied.
- void incrementalRemove(Constraint c) {
- var out = c.output();
- c.markUnsatisfied();
- c.removeFromGraph();
- var unsatisfied = removePropagateFrom(out);
- var strength = REQUIRED;
- do {
- for (var i = 0; i < unsatisfied.length; i++) {
- var u = unsatisfied[i];
- if (u.strength == strength) incrementalAdd(u);
- }
- strength = strength.nextWeaker();
- } while (strength != WEAKEST);
- }
-
- /// Select a previously unused mark value.
- int newMark() => ++currentMark;
-
- /// Extract a plan for resatisfaction starting from the given source
- /// constraints, usually a set of input constraints. This method
- /// assumes that stay optimization is desired; the plan will contain
- /// only constraints whose output variables are not stay. Constraints
- /// that do no computation, such as stay and edit constraints, are
- /// not included in the plan.
- /// Details: The outputs of a constraint are marked when it is added
- /// to the plan under construction. A constraint may be appended to
- /// the plan when all its input variables are known. A variable is
- /// known if either a) the variable is marked (indicating that has
- /// been computed by a constraint appearing earlier in the plan), b)
- /// the variable is 'stay' (i.e. it is a constant at plan execution
- /// time), or c) the variable is not determined by any
- /// constraint. The last provision is for past states of history
- /// variables, which are not stay but which are also not computed by
- /// any constraint.
- /// Assume: [sources] are all satisfied.
- Plan makePlan(List<Constraint> sources) {
- var mark = newMark();
- var plan = Plan();
- var todo = sources;
- while (todo.isNotEmpty) {
- var c = todo.removeLast();
- if (c.output().mark != mark && c.inputsKnown(mark)) {
- plan.addConstraint(c);
- c.output().mark = mark;
- addConstraintsConsumingTo(c.output(), todo);
- }
- }
- return plan;
- }
-
- /// Extract a plan for resatisfying starting from the output of the
- /// given [constraints], usually a set of input constraints.
- Plan extractPlanFromConstraints(List<Constraint> constraints) {
- var sources = <Constraint>[];
- for (var i = 0; i < constraints.length; i++) {
- var c = constraints[i];
- // if not in plan already and eligible for inclusion.
- if (c.isInput() && c.isSatisfied()) sources.add(c);
- }
- return makePlan(sources);
- }
-
- /// Recompute the walkabout strengths and stay flags of all variables
- /// downstream of the given constraint and recompute the actual
- /// values of all variables whose stay flag is true. If a cycle is
- /// detected, remove the given constraint and answer
- /// false. Otherwise, answer true.
- /// Details: Cycles are detected when a marked variable is
- /// encountered downstream of the given constraint. The sender is
- /// assumed to have marked the inputs of the given constraint with
- /// the given mark. Thus, encountering a marked node downstream of
- /// the output constraint means that there is a path from the
- /// constraint's output to one of its inputs.
- bool addPropagate(Constraint c, int mark) {
- var todo = <Constraint>[c];
- while (todo.isNotEmpty) {
- var d = todo.removeLast();
- if (d.output().mark == mark) {
- incrementalRemove(c);
- return false;
- }
- d.recalculate();
- addConstraintsConsumingTo(d.output(), todo);
- }
- return true;
- }
-
- /// Update the walkabout strengths and stay flags of all variables
- /// downstream of the given constraint. Answer a collection of
- /// unsatisfied constraints sorted in order of decreasing strength.
- List<Constraint> removePropagateFrom(Variable out) {
- out.determinedBy = null;
- out.walkStrength = WEAKEST;
- out.stay = true;
- var unsatisfied = <Constraint>[];
- var todo = <Variable>[out];
- while (todo.isNotEmpty) {
- var v = todo.removeLast();
- for (var i = 0; i < v.constraints.length; i++) {
- var c = v.constraints[i];
- if (!c.isSatisfied()) unsatisfied.add(c);
- }
- var determining = v.determinedBy;
- for (var i = 0; i < v.constraints.length; i++) {
- var next = v.constraints[i];
- if (next != determining && next.isSatisfied()) {
- next.recalculate();
- todo.add(next.output());
- }
- }
- }
- return unsatisfied;
- }
-
- void addConstraintsConsumingTo(Variable v, List<Constraint> coll) {
- var determining = v.determinedBy;
- for (var i = 0; i < v.constraints.length; i++) {
- var c = v.constraints[i];
- if (c != determining && c.isSatisfied()) coll.add(c);
- }
- }
-}
-
-/// A Plan is an ordered list of constraints to be executed in sequence
-/// to resatisfy all currently satisfiable constraints in the face of
-/// one or more changing inputs.
-class Plan {
- List<Constraint> list = <Constraint>[];
-
- void addConstraint(Constraint c) {
- list.add(c);
- }
-
- int size() => list.length;
-
- void execute() {
- for (var i = 0; i < list.length; i++) {
- list[i].execute();
- }
- }
-}
-
-/// This is the standard DeltaBlue benchmark. A long chain of equality
-/// constraints is constructed with a stay constraint on one end. An
-/// edit constraint is then added to the opposite end and the time is
-/// measured for adding and removing this constraint, and extracting
-/// and executing a constraint satisfaction plan. There are two cases.
-/// In case 1, the added constraint is stronger than the stay
-/// constraint and values must propagate down the entire length of the
-/// chain. In case 2, the added constraint is weaker than the stay
-/// constraint so it cannot be accomodated. The cost in this case is,
-/// of course, very low. Typical situations lie somewhere between these
-/// two extremes.
-void chainTest(int n) {
- planner = Planner();
- Variable prev, first, last;
- // Build chain of n equality constraints.
- for (var i = 0; i <= n; i++) {
- var v = Variable('v', 0);
- if (prev != null) EqualityConstraint(prev, v, REQUIRED);
- if (i == 0) first = v;
- if (i == n) last = v;
- prev = v;
- }
- StayConstraint(last, STRONG_DEFAULT);
- var edit = EditConstraint(first, PREFERRED);
- var plan = planner.extractPlanFromConstraints(<Constraint>[edit]);
- for (var i = 0; i < 100; i++) {
- first.value = i;
- plan.execute();
- if (last.value != i) {
- print('Chain test failed.\n{last.value)\n{i}');
- }
- }
-}
-
-/// This test constructs a two sets of variables related to each
-/// other by a simple linear transformation (scale and offset). The
-/// time is measured to change a variable on either side of the
-/// mapping and to change the scale and offset factors.
-void projectionTest(int n) {
- planner = Planner();
- var scale = Variable('scale', 10);
- var offset = Variable('offset', 1000);
- Variable src, dst;
-
- var dests = <Variable>[];
- for (var i = 0; i < n; i++) {
- src = Variable('src', i);
- dst = Variable('dst', i);
- dests.add(dst);
- StayConstraint(src, NORMAL);
- ScaleConstraint(src, scale, offset, dst, REQUIRED);
- }
- change(src, 17);
- if (dst.value != 1170) print('Projection 1 failed');
- change(dst, 1050);
- if (src.value != 5) print('Projection 2 failed');
- change(scale, 5);
- for (var i = 0; i < n - 1; i++) {
- if (dests[i].value != i * 5 + 1000) print('Projection 3 failed');
- }
- change(offset, 2000);
- for (var i = 0; i < n - 1; i++) {
- if (dests[i].value != i * 5 + 2000) print('Projection 4 failed');
- }
-}
-
-void change(Variable v, int newValue) {
- var edit = EditConstraint(v, PREFERRED);
- var plan = planner.extractPlanFromConstraints(<EditConstraint>[edit]);
- for (var i = 0; i < 10; i++) {
- v.value = newValue;
- plan.execute();
- }
- edit.destroyConstraint();
-}
-
-Planner planner;
diff --git a/example/FluidMotion/dart/FluidMotion.dart b/example/FluidMotion/dart/FluidMotion.dart
deleted file mode 100644
index 1b167e3..0000000
--- a/example/FluidMotion/dart/FluidMotion.dart
+++ /dev/null
@@ -1,511 +0,0 @@
-// @dart=2.8
-import 'dart:html';
-
-/// Copyright 2013 the V8 project authors. All rights reserved.
-/// Copyright 2009 Oliver Hunt <http://nerget.com>
-///
-/// Permission is hereby granted, free of charge, to any person
-/// obtaining a copy of this software and associated documentation
-/// files (the 'Software'), to deal in the Software without
-/// restriction, including without limitation the rights to use,
-/// copy, modify, merge, publish, distribute, sublicense, and/or sell
-/// copies of the Software, and to permit persons to whom the
-/// Software is furnished to do so, subject to the following
-/// conditions:
-///
-/// The above copyright notice and this permission notice shall be
-/// included in all copies or substantial portions of the Software.
-///
-/// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
-/// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-/// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-/// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-/// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-/// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-/// OTHER DEALINGS IN THE SOFTWARE.
-
-// Ported from the v8 benchmark suite by Google 2013.
-// Uses Float64List for data.
-
-import 'dart:math';
-import 'dart:typed_data';
-
-import 'package:benchmark_harness/benchmark_harness.dart';
-
-/// Copyright 2009 Oliver Hunt <http://nerget.com>
-///
-/// Permission is hereby granted, free of charge, to any person
-/// obtaining a copy of this software and associated documentation
-/// files (the 'Software'), to deal in the Software without
-/// restriction, including without limitation the rights to use,
-/// copy, modify, merge, publish, distribute, sublicense, and/or sell
-/// copies of the Software, and to permit persons to whom the
-/// Software is furnished to do so, subject to the following
-/// conditions:
-///
-/// The above copyright notice and this permission notice shall be
-/// included in all copies or substantial portions of the Software.
-///
-/// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
-/// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-/// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-/// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-/// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-/// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-/// OTHER DEALINGS IN THE SOFTWARE.
-// Ported from the v8 benchmark suite by Google 2013.
-// Uses Float64List for data.
-
-/// Copyright 2009 Oliver Hunt <http://nerget.com>
-///
-/// Permission is hereby granted, free of charge, to any person
-/// obtaining a copy of this software and associated documentation
-/// files (the 'Software'), to deal in the Software without
-/// restriction, including without limitation the rights to use,
-/// copy, modify, merge, publish, distribute, sublicense, and/or sell
-/// copies of the Software, and to permit persons to whom the
-/// Software is furnished to do so, subject to the following
-/// conditions:
-///
-/// The above copyright notice and this permission notice shall be
-/// included in all copies or substantial portions of the Software.
-///
-/// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
-/// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-/// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-/// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-/// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-/// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-/// OTHER DEALINGS IN THE SOFTWARE.
-// Ported from the v8 benchmark suite by Google 2013.
-// Uses Float64List for data.
-
-void main() {
- const FluidMotion().report();
-}
-
-class FluidMotion extends BenchmarkBase {
- static FluidField solver;
- static int framesTillAddingPoints = 0;
- static int framesBetweenAddingPoints = 5;
-
- const FluidMotion() : super('FluidMotion');
-
- static void setupFluidMotion() {
- framesTillAddingPoints = 0;
- framesBetweenAddingPoints = 5;
- solver = FluidField.create(null, 128, 128, 20);
- solver.setDisplayFunction((a) {});
- solver.setUICallback(prepareFrame);
- }
-
- static void runFluidMotion() {
- setupFluidMotion();
- for (var i = 0; i < 10; i++) {
- solver.update();
- }
- solver.validate(758.9012130174812, -352.56376676179076, -357.3690235879736);
- }
-
- static void main() {
- runFluidMotion();
- }
-
- static void addPoints(Field field) {
- var n = 64;
- for (var i = 1; i <= n; i++) {
- field.setVelocity(i, i, n.toDouble(), n.toDouble());
- field.setDensity(i, i, 5.0);
- field.setVelocity(i, n - i, -n.toDouble(), -n.toDouble());
- field.setDensity(i, n - i, 20.0);
- field.setVelocity(128 - i, n + i, -n.toDouble(), -n.toDouble());
- field.setDensity(128 - i, n + i, 30.0);
- }
- }
-
- static void prepareFrame(Field field) {
- if (framesTillAddingPoints == 0) {
- addPoints(field);
- framesTillAddingPoints = framesBetweenAddingPoints;
- framesBetweenAddingPoints++;
- } else {
- framesTillAddingPoints--;
- }
- }
-
- // Overrides of BenchmarkBase.
-
- @override
- void warmup() {
- runFluidMotion();
- }
-
- @override
- void exercise() {
- runFluidMotion();
- }
-}
-
-// Code from Oliver Hunt (http://nerget.com/fluidSim/pressure.js) starts here.
-
-class FluidField {
- final CanvasElement canvas;
- final int iterations;
- final double dt = 0.1;
- final int size;
- Float64List dens, dens_prev;
- Float64List u, u_prev;
- Float64List v, v_prev;
- final int width, height;
- final int rowSize;
- void Function(Field) displayFunc;
-
- static FluidField _lastCreated;
-
- static bool approxEquals(double a, double b) => (a - b).abs() < 0.000001;
-
- void validate(double expectedDens, double expectedU, double expectedV) {
- var sumDens = 0.0;
- var sumU = 0.0;
- var sumV = 0.0;
- for (var i = 0; i < dens.length; i++) {
- sumDens += dens[i];
- sumU += u[i];
- sumV += v[i];
- }
-
- if (!approxEquals(sumDens, expectedDens) ||
- !approxEquals(sumU, expectedU) ||
- !approxEquals(sumV, expectedV)) {
- throw 'Incorrect result';
- }
- }
-
- // Allocates a new FluidField or return previously allocated field if the
- // size is too large.
- factory FluidField.create(
- CanvasElement canvas, int hRes, int wRes, int iterations) {
- final res = wRes * hRes;
- if ((res > 0) && (res < 1000000)) {
- _lastCreated = FluidField(canvas, hRes, wRes, iterations);
- }
- _lastCreated ??= FluidField(canvas, 64, 64, iterations);
- assert((canvas == _lastCreated.canvas) &&
- (iterations == _lastCreated.iterations));
- return _lastCreated;
- }
-
- FluidField(this.canvas, this.height, this.width, this.iterations)
- : rowSize = width + 2,
- size = (width + 2) * (height + 2) {
- reset();
- }
-
- void reset() {
- // All Float64List elements are initialized to 0.0.
- dens = Float64List(size);
- dens_prev = Float64List(size);
- u = Float64List(size);
- u_prev = Float64List(size);
- v = Float64List(size);
- v_prev = Float64List(size);
- }
-
- void addFields(Float64List x, Float64List s, double dt) {
- for (var i = 0; i < size; i++) {
- x[i] += dt * s[i];
- }
- }
-
- void set_bnd(int b, Float64List x) {
- if (b == 1) {
- var i = 1;
- for (; i <= width; i++) {
- x[i] = x[i + rowSize];
- x[i + (height + 1) * rowSize] = x[i + height * rowSize];
- }
-
- for (var j = 1; j <= height; j++) {
- x[j * rowSize] = x[1 + j * rowSize];
- x[(width + 1) + j * rowSize] = -1 * x[width + j * rowSize];
- }
- } else if (b == 2) {
- for (var i = 1; i <= width; i++) {
- x[i] = -1 * x[i + rowSize];
- x[i + (height + 1) * rowSize] = -1 * x[i + height * rowSize];
- }
-
- for (var j = 1; j <= height; j++) {
- x[j * rowSize] = x[1 + j * rowSize];
- x[(width + 1) + j * rowSize] = x[width + j * rowSize];
- }
- } else {
- for (var i = 1; i <= width; i++) {
- x[i] = x[i + rowSize];
- x[i + (height + 1) * rowSize] = x[i + height * rowSize];
- }
-
- for (var j = 1; j <= height; j++) {
- x[j * rowSize] = x[1 + j * rowSize];
- x[(width + 1) + j * rowSize] = x[width + j * rowSize];
- }
- }
- var maxEdge = (height + 1) * rowSize;
- x[0] = 0.5 * (x[1] + x[rowSize]);
- x[maxEdge] = 0.5 * (x[1 + maxEdge] + x[height * rowSize]);
- x[(width + 1)] = 0.5 * (x[width] + x[(width + 1) + rowSize]);
- x[(width + 1) + maxEdge] =
- 0.5 * (x[width + maxEdge] + x[(width + 1) + height * rowSize]);
- }
-
- void lin_solve(int b, Float64List x, Float64List x0, int a, int c) {
- if (a == 0 && c == 1) {
- for (var j = 1; j <= height; j++) {
- var currentRow = j * rowSize;
- ++currentRow;
- for (var i = 0; i < width; i++) {
- x[currentRow] = x0[currentRow];
- ++currentRow;
- }
- }
- set_bnd(b, x);
- } else {
- var invC = 1 / c;
- for (var k = 0; k < iterations; k++) {
- for (var j = 1; j <= height; j++) {
- var lastRow = (j - 1) * rowSize;
- var currentRow = j * rowSize;
- var nextRow = (j + 1) * rowSize;
- var lastX = x[currentRow];
- ++currentRow;
- for (var i = 1; i <= width; i++) {
- lastX = x[currentRow] = (x0[currentRow] +
- a *
- (lastX +
- x[++currentRow] +
- x[++lastRow] +
- x[++nextRow])) *
- invC;
- }
- }
- set_bnd(b, x);
- }
- }
- }
-
- void diffuse(int b, Float64List x, Float64List x0, double dt) {
- var a = 0;
- lin_solve(b, x, x0, a, 1 + 4 * a);
- }
-
- void lin_solve2(Float64List x, Float64List x0, Float64List y, Float64List y0,
- int a, int c) {
- if (a == 0 && c == 1) {
- for (var j = 1; j <= height; j++) {
- var currentRow = j * rowSize;
- ++currentRow;
- for (var i = 0; i < width; i++) {
- x[currentRow] = x0[currentRow];
- y[currentRow] = y0[currentRow];
- ++currentRow;
- }
- }
- set_bnd(1, x);
- set_bnd(2, y);
- } else {
- var invC = 1 / c;
- for (var k = 0; k < iterations; k++) {
- for (var j = 1; j <= height; j++) {
- var lastRow = (j - 1) * rowSize;
- var currentRow = j * rowSize;
- var nextRow = (j + 1) * rowSize;
- var lastX = x[currentRow];
- var lastY = y[currentRow];
- ++currentRow;
- for (var i = 1; i <= width; i++) {
- lastX = x[currentRow] = (x0[currentRow] +
- a * (lastX + x[currentRow] + x[lastRow] + x[nextRow])) *
- invC;
- lastY = y[currentRow] = (y0[currentRow] +
- a *
- (lastY +
- y[++currentRow] +
- y[++lastRow] +
- y[++nextRow])) *
- invC;
- }
- }
- set_bnd(1, x);
- set_bnd(2, y);
- }
- }
- }
-
- void diffuse2(
- Float64List x, Float64List x0, Float64List y, Float64List y0, double dt) {
- var a = 0;
- lin_solve2(x, x0, y, y0, a, 1 + 4 * a);
- }
-
- void advect(int b, Float64List d, Float64List d0, Float64List u,
- Float64List v, double dt) {
- var Wdt0 = dt * width;
- var Hdt0 = dt * height;
- var Wp5 = width + 0.5;
- var Hp5 = height + 0.5;
- for (var j = 1; j <= height; j++) {
- var pos = j * rowSize;
- for (var i = 1; i <= width; i++) {
- var x = i - Wdt0 * u[++pos];
- var y = j - Hdt0 * v[pos];
- if (x < 0.5) {
- x = 0.5;
- } else if (x > Wp5) {
- x = Wp5;
- }
- var i0 = x.toInt();
- var i1 = i0 + 1;
- if (y < 0.5) {
- y = 0.5;
- } else if (y > Hp5) {
- y = Hp5;
- }
- var j0 = y.toInt();
- var j1 = j0 + 1;
- var s1 = x - i0;
- var s0 = 1 - s1;
- var t1 = y - j0;
- var t0 = 1 - t1;
- var row1 = j0 * rowSize;
- var row2 = j1 * rowSize;
- d[pos] = s0 * (t0 * d0[i0 + row1] + t1 * d0[i0 + row2]) +
- s1 * (t0 * d0[i1 + row1] + t1 * d0[i1 + row2]);
- }
- }
- set_bnd(b, d);
- }
-
- void project(Float64List u, Float64List v, Float64List p, Float64List div) {
- var h = -0.5 / sqrt(width * height);
- for (var j = 1; j <= height; j++) {
- var row = j * rowSize;
- var previousRow = (j - 1) * rowSize;
- var prevValue = row - 1;
- var currentRow = row;
- var nextValue = row + 1;
- var nextRow = (j + 1) * rowSize;
- for (var i = 1; i <= width; i++) {
- div[++currentRow] = h *
- (u[++nextValue] - u[++prevValue] + v[++nextRow] - v[++previousRow]);
- p[currentRow] = 0.0;
- }
- }
- set_bnd(0, div);
- set_bnd(0, p);
-
- lin_solve(0, p, div, 1, 4);
- var wScale = 0.5 * width;
- var hScale = 0.5 * height;
- for (var j = 1; j <= height; j++) {
- var prevPos = j * rowSize - 1;
- var currentPos = j * rowSize;
- var nextPos = j * rowSize + 1;
- var prevRow = (j - 1) * rowSize;
- var nextRow = (j + 1) * rowSize;
-
- for (var i = 1; i <= width; i++) {
- u[++currentPos] -= wScale * (p[++nextPos] - p[++prevPos]);
- v[currentPos] -= hScale * (p[++nextRow] - p[++prevRow]);
- }
- }
- set_bnd(1, u);
- set_bnd(2, v);
- }
-
- void dens_step(
- Float64List x, Float64List x0, Float64List u, Float64List v, double dt) {
- addFields(x, x0, dt);
- diffuse(0, x0, x, dt);
- advect(0, x, x0, u, v, dt);
- }
-
- void vel_step(
- Float64List u, Float64List v, Float64List u0, Float64List v0, double dt) {
- addFields(u, u0, dt);
- addFields(v, v0, dt);
- var temp = u0;
- u0 = u;
- u = temp;
- temp = v0;
- v0 = v;
- v = temp;
- diffuse2(u, u0, v, v0, dt);
- project(u, v, u0, v0);
- temp = u0;
- u0 = u;
- u = temp;
- temp = v0;
- v0 = v;
- v = temp;
- advect(1, u, u0, u0, v0, dt);
- advect(2, v, v0, u0, v0, dt);
- project(u, v, u0, v0);
- }
-
- void Function(Field) uiCallback;
-
- void setDisplayFunction(void Function(Field) func) {
- displayFunc = func;
- }
-
- void setUICallback(void Function(Field) callback) {
- uiCallback = callback;
- }
-
- void queryUI(Float64List d, Float64List u, Float64List v) {
- for (var i = 0; i < size; i++) {
- u[i] = v[i] = d[i] = 0.0;
- }
- uiCallback(Field(d, u, v, rowSize));
- }
-
- void update() {
- queryUI(dens_prev, u_prev, v_prev);
- vel_step(u, v, u_prev, v_prev, dt);
- dens_step(dens, dens_prev, u, v, dt);
- displayFunc(Field(dens, u, v, rowSize));
- }
-}
-
-// Difference from JS version: Field takes an argument rowSize, but this
-// used for display purpose only.
-class Field {
- final Float64List dens, u, v;
- final int rowSize;
-
- Field(this.dens, this.u, this.v, this.rowSize);
-
- void setDensity(int x, int y, double d) {
- dens[(x + 1) + (y + 1) * rowSize] = d;
- }
-
- double getDensity(int x, int y) {
- return dens[(x + 1) + (y + 1) * rowSize]; // rowSize from FluidField?
- }
-
- void setVelocity(int x, int y, double xv, double yv) {
- u[(x + 1) + (y + 1) * rowSize] = xv;
- v[(x + 1) + (y + 1) * rowSize] = yv;
- }
-
- double getXVelocity(int x, int y) {
- return u[(x + 1) + (y + 1) * rowSize];
- }
-
- double getYVelocity(int x, int y) {
- return v[(x + 1) + (y + 1) * rowSize];
- }
-}
diff --git a/example/FluidMotion/js/FluidMotion.js b/example/FluidMotion/js/FluidMotion.js
deleted file mode 100644
index 326b4e1..0000000
--- a/example/FluidMotion/js/FluidMotion.js
+++ /dev/null
@@ -1,413 +0,0 @@
-/**
- * Copyright 2012 the V8 project authors. All rights reserved.
- * Copyright 2009 Oliver Hunt <http://nerget.com>
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use,
- * copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
-
-// Addapted by Google 2013.
-
-var solver = null;
-
-var framesTillAddingPoints = 0;
-var framesBetweenAddingPoints = 5;
-
-function runFluidMotion()
-{
- setupFluidMotion();
- for (var i = 0; i < 10; i++) {
- solver.update();
- }
- solver.validate(758.9012130174812, -352.56376676179076, -357.3690235879736);
-}
-
-function setupFluidMotion()
-{
- framesTillAddingPoints = 0;
- framesBetweenAddingPoints = 5;
- solver = new FluidField(null);
- solver.setResolution(128, 128);
- solver.setIterations(20);
- solver.setDisplayFunction(function(){});
- solver.setUICallback(prepareFrame);
-}
-
-function tearDownFluidMotion()
-{
- solver = null;
-}
-
-function addPoints(field) {
- var n = 64;
- for (var i = 1; i <= n; i++) {
- field.setVelocity(i, i, n, n);
- field.setDensity(i, i, 5);
- field.setVelocity(i, n - i, -n, -n);
- field.setDensity(i, n - i, 20);
- field.setVelocity(128 - i, n + i, -n, -n);
- field.setDensity(128 - i, n + i, 30);
- }
-}
-
-function prepareFrame(field)
-{
- if (framesTillAddingPoints == 0) {
- addPoints(field);
- framesTillAddingPoints = framesBetweenAddingPoints;
- framesBetweenAddingPoints++;
- } else {
- framesTillAddingPoints--;
- }
-}
-
-// Code from Oliver Hunt (http://nerget.com/fluidSim/pressure.js) starts here.
-function FluidField(canvas) {
-
- function approxEquals(a, b) {
- return Math.abs(a - b) < 0.000001;
- }
-
- function validate(expectedDens, expectedU, expectedV) {
- var sumDens = 0.0;
- var sumU = 0.0;
- var sumV = 0.0;
- for (var i = 0; i < dens.length; i++) {
- sumDens += dens[i];
- sumU += u[i];
- sumV += v[i];
- }
-
- if (!approxEquals(sumDens, expectedDens) ||
- !approxEquals(sumU, expectedU) ||
- !approxEquals(sumV, expectedV)) {
- throw "Incorrect result";
- }
- }
- this.validate = validate;
-
- function addFields(x, s, dt)
- {
- for (var i=0; i<size ; i++ ) x[i] += dt*s[i];
- }
-
- function set_bnd(b, x)
- {
- if (b===1) {
- for (var i = 1; i <= width; i++) {
- x[i] = x[i + rowSize];
- x[i + (height+1) *rowSize] = x[i + height * rowSize];
- }
-
- for (var j = 1; j <= height; j++) {
- x[j * rowSize] = -x[1 + j * rowSize];
- x[(width + 1) + j * rowSize] = -x[width + j * rowSize];
- }
- } else if (b === 2) {
- for (var i = 1; i <= width; i++) {
- x[i] = -x[i + rowSize];
- x[i + (height + 1) * rowSize] = -x[i + height * rowSize];
- }
-
- for (var j = 1; j <= height; j++) {
- x[j * rowSize] = x[1 + j * rowSize];
- x[(width + 1) + j * rowSize] = x[width + j * rowSize];
- }
- } else {
- for (var i = 1; i <= width; i++) {
- x[i] = x[i + rowSize];
- x[i + (height + 1) * rowSize] = x[i + height * rowSize];
- }
-
- for (var j = 1; j <= height; j++) {
- x[j * rowSize] = x[1 + j * rowSize];
- x[(width + 1) + j * rowSize] = x[width + j * rowSize];
- }
- }
- var maxEdge = (height + 1) * rowSize;
- x[0] = 0.5 * (x[1] + x[rowSize]);
- x[maxEdge] = 0.5 * (x[1 + maxEdge] + x[height * rowSize]);
- x[(width+1)] = 0.5 * (x[width] + x[(width + 1) + rowSize]);
- x[(width+1)+maxEdge] = 0.5 * (x[width + maxEdge] + x[(width + 1) + height * rowSize]);
- }
-
- function lin_solve(b, x, x0, a, c)
- {
- if (a === 0 && c === 1) {
- for (var j=1 ; j<=height; j++) {
- var currentRow = j * rowSize;
- ++currentRow;
- for (var i = 0; i < width; i++) {
- x[currentRow] = x0[currentRow];
- ++currentRow;
- }
- }
- set_bnd(b, x);
- } else {
- var invC = 1 / c;
- for (var k=0 ; k<iterations; k++) {
- for (var j=1 ; j<=height; j++) {
- var lastRow = (j - 1) * rowSize;
- var currentRow = j * rowSize;
- var nextRow = (j + 1) * rowSize;
- var lastX = x[currentRow];
- ++currentRow;
- for (var i=1; i<=width; i++)
- lastX = x[currentRow] = (x0[currentRow] + a*(lastX+x[++currentRow]+x[++lastRow]+x[++nextRow])) * invC;
- }
- set_bnd(b, x);
- }
- }
- }
-
- function diffuse(b, x, x0, dt)
- {
- var a = 0;
- lin_solve(b, x, x0, a, 1 + 4*a);
- }
-
- function lin_solve2(x, x0, y, y0, a, c)
- {
- if (a === 0 && c === 1) {
- for (var j=1 ; j <= height; j++) {
- var currentRow = j * rowSize;
- ++currentRow;
- for (var i = 0; i < width; i++) {
- x[currentRow] = x0[currentRow];
- y[currentRow] = y0[currentRow];
- ++currentRow;
- }
- }
- set_bnd(1, x);
- set_bnd(2, y);
- } else {
- var invC = 1/c;
- for (var k=0 ; k<iterations; k++) {
- for (var j=1 ; j <= height; j++) {
- var lastRow = (j - 1) * rowSize;
- var currentRow = j * rowSize;
- var nextRow = (j + 1) * rowSize;
- var lastX = x[currentRow];
- var lastY = y[currentRow];
- ++currentRow;
- for (var i = 1; i <= width; i++) {
- lastX = x[currentRow] = (x0[currentRow] + a * (lastX + x[currentRow] + x[lastRow] + x[nextRow])) * invC;
- lastY = y[currentRow] = (y0[currentRow] + a * (lastY + y[++currentRow] + y[++lastRow] + y[++nextRow])) * invC;
- }
- }
- set_bnd(1, x);
- set_bnd(2, y);
- }
- }
- }
-
- function diffuse2(x, x0, y, y0, dt)
- {
- var a = 0;
- lin_solve2(x, x0, y, y0, a, 1 + 4 * a);
- }
-
- function advect(b, d, d0, u, v, dt)
- {
- var Wdt0 = dt * width;
- var Hdt0 = dt * height;
- var Wp5 = width + 0.5;
- var Hp5 = height + 0.5;
- for (var j = 1; j<= height; j++) {
- var pos = j * rowSize;
- for (var i = 1; i <= width; i++) {
- var x = i - Wdt0 * u[++pos];
- var y = j - Hdt0 * v[pos];
- if (x < 0.5)
- x = 0.5;
- else if (x > Wp5)
- x = Wp5;
- var i0 = x | 0;
- var i1 = i0 + 1;
- if (y < 0.5)
- y = 0.5;
- else if (y > Hp5)
- y = Hp5;
- var j0 = y | 0;
- var j1 = j0 + 1;
- var s1 = x - i0;
- var s0 = 1 - s1;
- var t1 = y - j0;
- var t0 = 1 - t1;
- var row1 = j0 * rowSize;
- var row2 = j1 * rowSize;
- d[pos] = s0 * (t0 * d0[i0 + row1] + t1 * d0[i0 + row2]) + s1 * (t0 * d0[i1 + row1] + t1 * d0[i1 + row2]);
- }
- }
- set_bnd(b, d);
- }
-
- function project(u, v, p, div)
- {
- var h = -0.5 / Math.sqrt(width * height);
- for (var j = 1 ; j <= height; j++ ) {
- var row = j * rowSize;
- var previousRow = (j - 1) * rowSize;
- var prevValue = row - 1;
- var currentRow = row;
- var nextValue = row + 1;
- var nextRow = (j + 1) * rowSize;
- for (var i = 1; i <= width; i++ ) {
- div[++currentRow] = h * (u[++nextValue] - u[++prevValue] + v[++nextRow] - v[++previousRow]);
- p[currentRow] = 0;
- }
- }
- set_bnd(0, div);
- set_bnd(0, p);
-
- lin_solve(0, p, div, 1, 4 );
- var wScale = 0.5 * width;
- var hScale = 0.5 * height;
- for (var j = 1; j<= height; j++ ) {
- var prevPos = j * rowSize - 1;
- var currentPos = j * rowSize;
- var nextPos = j * rowSize + 1;
- var prevRow = (j - 1) * rowSize;
- var currentRow = j * rowSize;
- var nextRow = (j + 1) * rowSize;
-
- for (var i = 1; i<= width; i++) {
- u[++currentPos] -= wScale * (p[++nextPos] - p[++prevPos]);
- v[currentPos] -= hScale * (p[++nextRow] - p[++prevRow]);
- }
- }
- set_bnd(1, u);
- set_bnd(2, v);
- }
-
- function dens_step(x, x0, u, v, dt)
- {
- addFields(x, x0, dt);
- diffuse(0, x0, x, dt );
- advect(0, x, x0, u, v, dt );
- }
-
- function vel_step(u, v, u0, v0, dt)
- {
- addFields(u, u0, dt );
- addFields(v, v0, dt );
- var temp = u0; u0 = u; u = temp;
- var temp = v0; v0 = v; v = temp;
- diffuse2(u,u0,v,v0, dt);
- project(u, v, u0, v0);
- var temp = u0; u0 = u; u = temp;
- var temp = v0; v0 = v; v = temp;
- advect(1, u, u0, u0, v0, dt);
- advect(2, v, v0, u0, v0, dt);
- project(u, v, u0, v0 );
- }
- var uiCallback = function(d,u,v) {};
-
- function Field(dens, u, v) {
- // Just exposing the fields here rather than using accessors is a measurable win during display (maybe 5%)
- // but makes the code ugly.
- this.setDensity = function(x, y, d) {
- dens[(x + 1) + (y + 1) * rowSize] = d;
- }
- this.getDensity = function(x, y) {
- return dens[(x + 1) + (y + 1) * rowSize];
- }
- this.setVelocity = function(x, y, xv, yv) {
- u[(x + 1) + (y + 1) * rowSize] = xv;
- v[(x + 1) + (y + 1) * rowSize] = yv;
- }
- this.getXVelocity = function(x, y) {
- return u[(x + 1) + (y + 1) * rowSize];
- }
- this.getYVelocity = function(x, y) {
- return v[(x + 1) + (y + 1) * rowSize];
- }
- this.width = function() { return width; }
- this.height = function() { return height; }
- }
- function queryUI(d, u, v)
- {
- for (var i = 0; i < size; i++)
- u[i] = v[i] = d[i] = 0.0;
- uiCallback(new Field(d, u, v));
- }
-
- this.update = function () {
- queryUI(dens_prev, u_prev, v_prev);
- vel_step(u, v, u_prev, v_prev, dt);
- dens_step(dens, dens_prev, u, v, dt);
- displayFunc(new Field(dens, u, v));
- }
- this.setDisplayFunction = function(func) {
- displayFunc = func;
- }
-
- this.iterations = function() { return iterations; }
- this.setIterations = function(iters) {
- if (iters > 0 && iters <= 100)
- iterations = iters;
- }
- this.setUICallback = function(callback) {
- uiCallback = callback;
- }
- var iterations = 10;
- var visc = 0.5;
- var dt = 0.1;
- var dens;
- var dens_prev;
- var u;
- var u_prev;
- var v;
- var v_prev;
- var width;
- var height;
- var rowSize;
- var size;
- var displayFunc;
- function reset()
- {
- rowSize = width + 2;
- size = (width+2)*(height+2);
- dens = new Float64Array(size);
- dens_prev = new Float64Array(size);
- u = new Float64Array(size);
- u_prev = new Float64Array(size);
- v = new Float64Array(size);
- v_prev = new Float64Array(size);
- for (var i = 0; i < size; i++)
- dens_prev[i] = u_prev[i] = v_prev[i] = dens[i] = u[i] = v[i] = 0;
- }
- this.reset = reset;
- this.setResolution = function (hRes, wRes)
- {
- var res = wRes * hRes;
- if (res > 0 && res < 1000000 && (wRes != width || hRes != height)) {
- width = wRes;
- height = hRes;
- reset();
- return true;
- }
- return false;
- }
- this.setResolution(64, 64);
-}
-
-Benchmark.report("FluidMotion", runFluidMotion, runFluidMotion);
diff --git a/example/Richards.dart b/example/Richards.dart
deleted file mode 100644
index 4b5f2ea..0000000
--- a/example/Richards.dart
+++ /dev/null
@@ -1,449 +0,0 @@
-// @dart=2.8
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Ported by the Dart team to Dart.
-
-// This is a Dart implementation of the Richards benchmark from:
-//
-// http://www.cl.cam.ac.uk/~mr10/Bench.html
-//
-// The benchmark was originally implemented in BCPL by
-// Martin Richards.
-
-import 'package:benchmark_harness/benchmark_harness.dart';
-
-void main() {
- const Richards().report();
-}
-
-/// Richards imulates the task dispatcher of an operating system.
-class Richards extends BenchmarkBase {
- const Richards() : super('Richards');
-
- @override
- void run() {
- var scheduler = Scheduler();
- scheduler.addIdleTask(ID_IDLE, 0, null, COUNT);
-
- var queue = Packet(null, ID_WORKER, KIND_WORK);
- queue = Packet(queue, ID_WORKER, KIND_WORK);
- scheduler.addWorkerTask(ID_WORKER, 1000, queue);
-
- queue = Packet(null, ID_DEVICE_A, KIND_DEVICE);
- queue = Packet(queue, ID_DEVICE_A, KIND_DEVICE);
- queue = Packet(queue, ID_DEVICE_A, KIND_DEVICE);
- scheduler.addHandlerTask(ID_HANDLER_A, 2000, queue);
-
- queue = Packet(null, ID_DEVICE_B, KIND_DEVICE);
- queue = Packet(queue, ID_DEVICE_B, KIND_DEVICE);
- queue = Packet(queue, ID_DEVICE_B, KIND_DEVICE);
- scheduler.addHandlerTask(ID_HANDLER_B, 3000, queue);
-
- scheduler.addDeviceTask(ID_DEVICE_A, 4000, null);
-
- scheduler.addDeviceTask(ID_DEVICE_B, 5000, null);
-
- scheduler.schedule();
-
- if (scheduler.queueCount != EXPECTED_QUEUE_COUNT ||
- scheduler.holdCount != EXPECTED_HOLD_COUNT) {
- print('Error during execution: queueCount = ${scheduler.queueCount}'
- ', holdCount = ${scheduler.holdCount}.');
- }
- if (EXPECTED_QUEUE_COUNT != scheduler.queueCount) {
- throw 'bad scheduler queue-count';
- }
- if (EXPECTED_HOLD_COUNT != scheduler.holdCount) {
- throw 'bad scheduler hold-count';
- }
- }
-
- static const int DATA_SIZE = 4;
- static const int COUNT = 1000;
-
- /// These two constants specify how many times a packet is queued and
- /// how many times a task is put on hold in a correct run of richards.
- /// They don't have any meaning a such but are characteristic of a
- /// correct run so if the actual queue or hold count is different from
- /// the expected there must be a bug in the implementation.
- static const int EXPECTED_QUEUE_COUNT = 2322;
- static const int EXPECTED_HOLD_COUNT = 928;
-
- static const int ID_IDLE = 0;
- static const int ID_WORKER = 1;
- static const int ID_HANDLER_A = 2;
- static const int ID_HANDLER_B = 3;
- static const int ID_DEVICE_A = 4;
- static const int ID_DEVICE_B = 5;
- static const int NUMBER_OF_IDS = 6;
-
- static const int KIND_DEVICE = 0;
- static const int KIND_WORK = 1;
-}
-
-/// A scheduler can be used to schedule a set of tasks based on their relative
-/// priorities. Scheduling is done by maintaining a list of task control blocks
-/// which holds tasks and the data queue they are processing.
-class Scheduler {
- int queueCount = 0;
- int holdCount = 0;
- TaskControlBlock currentTcb;
- int currentId;
- TaskControlBlock list;
- List<TaskControlBlock> blocks =
- // ignore: deprecated_member_use
- List<TaskControlBlock>(Richards.NUMBER_OF_IDS);
-
- /// Add an idle task to this scheduler.
- void addIdleTask(int id, int priority, Packet queue, int count) {
- addRunningTask(id, priority, queue, IdleTask(this, 1, count));
- }
-
- /// Add a work task to this scheduler.
- void addWorkerTask(int id, int priority, Packet queue) {
- addTask(id, priority, queue, WorkerTask(this, Richards.ID_HANDLER_A, 0));
- }
-
- /// Add a handler task to this scheduler.
- void addHandlerTask(int id, int priority, Packet queue) {
- addTask(id, priority, queue, HandlerTask(this));
- }
-
- /// Add a handler task to this scheduler.
- void addDeviceTask(int id, int priority, Packet queue) {
- addTask(id, priority, queue, DeviceTask(this));
- }
-
- /// Add the specified task and mark it as running.
- void addRunningTask(int id, int priority, Packet queue, Task task) {
- addTask(id, priority, queue, task);
- currentTcb.setRunning();
- }
-
- /// Add the specified task to this scheduler.
- void addTask(int id, int priority, Packet queue, Task task) {
- currentTcb = TaskControlBlock(list, id, priority, queue, task);
- list = currentTcb;
- blocks[id] = currentTcb;
- }
-
- /// Execute the tasks managed by this scheduler.
- void schedule() {
- currentTcb = list;
- while (currentTcb != null) {
- if (currentTcb.isHeldOrSuspended()) {
- currentTcb = currentTcb.link;
- } else {
- currentId = currentTcb.id;
- currentTcb = currentTcb.run();
- }
- }
- }
-
- /// Release a task that is currently blocked and return the next block to run.
- TaskControlBlock release(int id) {
- var tcb = blocks[id];
- if (tcb == null) return tcb;
- tcb.markAsNotHeld();
- if (tcb.priority > currentTcb.priority) return tcb;
- return currentTcb;
- }
-
- /// Block the currently executing task and return the next task control block
- /// to run. The blocked task will not be made runnable until it is explicitly
- /// released, even if new work is added to it.
- TaskControlBlock holdCurrent() {
- holdCount++;
- currentTcb.markAsHeld();
- return currentTcb.link;
- }
-
- /// Suspend the currently executing task and return the next task
- /// control block to run.
- /// If new work is added to the suspended task it will be made runnable.
- TaskControlBlock suspendCurrent() {
- currentTcb.markAsSuspended();
- return currentTcb;
- }
-
- /// Add the specified packet to the end of the worklist used by the task
- /// associated with the packet and make the task runnable if it is currently
- /// suspended.
- TaskControlBlock queue(Packet packet) {
- var t = blocks[packet.id];
- if (t == null) return t;
- queueCount++;
- packet.link = null;
- packet.id = currentId;
- return t.checkPriorityAdd(currentTcb, packet);
- }
-}
-
-/// A task control block manages a task and the queue of work packages associated
-/// with it.
-class TaskControlBlock {
- TaskControlBlock link;
- int id; // The id of this block.
- int priority; // The priority of this block.
- Packet queue; // The queue of packages to be processed by the task.
- Task task;
- int state;
-
- TaskControlBlock(this.link, this.id, this.priority, this.queue, this.task) {
- state = queue == null ? STATE_SUSPENDED : STATE_SUSPENDED_RUNNABLE;
- }
-
- /// The task is running and is currently scheduled.
- static const int STATE_RUNNING = 0;
-
- /// The task has packets left to process.
- static const int STATE_RUNNABLE = 1;
-
- /// The task is not currently running. The task is not blocked as such and may
- /// be started by the scheduler.
- static const int STATE_SUSPENDED = 2;
-
- /// The task is blocked and cannot be run until it is explicitly released.
- static const int STATE_HELD = 4;
-
- static const int STATE_SUSPENDED_RUNNABLE = STATE_SUSPENDED | STATE_RUNNABLE;
- static const int STATE_NOT_HELD = ~STATE_HELD;
-
- void setRunning() {
- state = STATE_RUNNING;
- }
-
- void markAsNotHeld() {
- state = state & STATE_NOT_HELD;
- }
-
- void markAsHeld() {
- state = state | STATE_HELD;
- }
-
- bool isHeldOrSuspended() {
- return (state & STATE_HELD) != 0 || (state == STATE_SUSPENDED);
- }
-
- void markAsSuspended() {
- state = state | STATE_SUSPENDED;
- }
-
- void markAsRunnable() {
- state = state | STATE_RUNNABLE;
- }
-
- /// Runs this task, if it is ready to be run, and returns the next task to run.
- TaskControlBlock run() {
- Packet packet;
- if (state == STATE_SUSPENDED_RUNNABLE) {
- packet = queue;
- queue = packet.link;
- state = queue == null ? STATE_RUNNING : STATE_RUNNABLE;
- } else {
- packet = null;
- }
- return task.run(packet);
- }
-
- /// Adds a packet to the worklist of this block's task, marks this as
- /// runnable if necessary, and returns the next runnable object to run
- /// (the one with the highest priority).
- TaskControlBlock checkPriorityAdd(TaskControlBlock task, Packet packet) {
- if (queue == null) {
- queue = packet;
- markAsRunnable();
- if (priority > task.priority) return this;
- } else {
- queue = packet.addTo(queue);
- }
- return task;
- }
-
- @override
- String toString() => 'tcb { $task@$state }';
-}
-
-/// Abstract task that manipulates work packets.
-abstract class Task {
- Scheduler scheduler; // The scheduler that manages this task.
-
- Task(this.scheduler);
-
- TaskControlBlock run(Packet packet);
-}
-
-/// An idle task doesn't do any work itself but cycles control between the two
-/// device tasks.
-class IdleTask extends Task {
- int v1; // A seed value that controls how the device tasks are scheduled.
- int count; // The number of times this task should be scheduled.
-
- IdleTask(Scheduler scheduler, this.v1, this.count) : super(scheduler);
-
- @override
- TaskControlBlock run(Packet packet) {
- count--;
- if (count == 0) return scheduler.holdCurrent();
- if ((v1 & 1) == 0) {
- v1 = v1 >> 1;
- return scheduler.release(Richards.ID_DEVICE_A);
- }
- v1 = (v1 >> 1) ^ 0xD008;
- return scheduler.release(Richards.ID_DEVICE_B);
- }
-
- @override
- String toString() => 'IdleTask';
-}
-
-/// A task that suspends itself after each time it has been run to simulate
-/// waiting for data from an external device.
-class DeviceTask extends Task {
- Packet v1;
-
- DeviceTask(Scheduler scheduler) : super(scheduler);
-
- @override
- TaskControlBlock run(Packet packet) {
- if (packet == null) {
- if (v1 == null) return scheduler.suspendCurrent();
- var v = v1;
- v1 = null;
- return scheduler.queue(v);
- }
- v1 = packet;
- return scheduler.holdCurrent();
- }
-
- @override
- String toString() => 'DeviceTask';
-}
-
-/// A task that manipulates work packets.
-class WorkerTask extends Task {
- int v1; // A seed used to specify how work packets are manipulated.
- int v2; // Another seed used to specify how work packets are manipulated.
-
- WorkerTask(Scheduler scheduler, this.v1, this.v2) : super(scheduler);
-
- @override
- TaskControlBlock run(Packet packet) {
- if (packet == null) {
- return scheduler.suspendCurrent();
- }
- if (v1 == Richards.ID_HANDLER_A) {
- v1 = Richards.ID_HANDLER_B;
- } else {
- v1 = Richards.ID_HANDLER_A;
- }
- packet.id = v1;
- packet.a1 = 0;
- for (var i = 0; i < Richards.DATA_SIZE; i++) {
- v2++;
- if (v2 > 26) v2 = 1;
- packet.a2[i] = v2;
- }
- return scheduler.queue(packet);
- }
-
- @override
- String toString() => 'WorkerTask';
-}
-
-/// A task that manipulates work packets and then suspends itself.
-class HandlerTask extends Task {
- Packet v1;
- Packet v2;
-
- HandlerTask(Scheduler scheduler) : super(scheduler);
-
- @override
- TaskControlBlock run(Packet packet) {
- if (packet != null) {
- if (packet.kind == Richards.KIND_WORK) {
- v1 = packet.addTo(v1);
- } else {
- v2 = packet.addTo(v2);
- }
- }
- if (v1 != null) {
- var count = v1.a1;
- Packet v;
- if (count < Richards.DATA_SIZE) {
- if (v2 != null) {
- v = v2;
- v2 = v2.link;
- v.a1 = v1.a2[count];
- v1.a1 = count + 1;
- return scheduler.queue(v);
- }
- } else {
- v = v1;
- v1 = v1.link;
- return scheduler.queue(v);
- }
- }
- return scheduler.suspendCurrent();
- }
-
- @override
- String toString() => 'HandlerTask';
-}
-
-/// A simple package of data that is manipulated by the tasks. The exact layout
-/// of the payload data carried by a packet is not importaint, and neither is the
-/// nature of the work performed on packets by the tasks.
-/// Besides carrying data, packets form linked lists and are hence used both as
-/// data and worklists.
-class Packet {
- Packet link; // The tail of the linked list of packets.
- int id; // An ID for this packet.
- int kind; // The type of this packet.
- int a1 = 0;
-
- // ignore: deprecated_member_use
- List<int> a2 = List(Richards.DATA_SIZE);
-
- Packet(this.link, this.id, this.kind);
-
- /// Add this packet to the end of a worklist, and return the worklist.
- Packet addTo(Packet queue) {
- link = null;
- if (queue == null) return this;
- Packet peek, next = queue;
- while ((peek = next.link) != null) {
- next = peek;
- }
- next.link = this;
- return queue;
- }
-
- @override
- String toString() => 'Packet';
-}
diff --git a/example/Template.dart b/example/Template.dart
index 879732d..43db1cd 100644
--- a/example/Template.dart
+++ b/example/Template.dart
@@ -1,5 +1,7 @@
// @dart=2.8
-// Copyright 2012 Google Inc. All Rights Reserved.
+// Copyright (c) 2021, 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 BenchmarkBase class.
import 'package:benchmark_harness/benchmark_harness.dart';
diff --git a/example/Tracer/dart/Tracer.dart b/example/Tracer/dart/Tracer.dart
deleted file mode 100644
index d3c02b2..0000000
--- a/example/Tracer/dart/Tracer.dart
+++ /dev/null
@@ -1,44 +0,0 @@
-// @dart=2.8
-// The ray tracer code in this file is written by Adam Burmister. It
-// is available in its original form from:
-//
-// http://labs.flog.co.nz/raytracer/
-//
-// Ported from the v8 benchmark suite by Google 2012.
-
-library ray_trace;
-
-import 'dart:html';
-import 'dart:math';
-
-import 'package:benchmark_harness/benchmark_harness.dart';
-
-part 'color.dart';
-part 'engine.dart';
-part 'materials.dart';
-part 'scene.dart';
-part 'shapes.dart';
-part 'vector.dart';
-part 'renderscene.dart';
-
-// Variable used to hold a number that can be used to verify that
-// the scene was ray traced correctly.
-int checkNumber;
-
-class TracerBenchmark extends BenchmarkBase {
- const TracerBenchmark() : super('Tracer');
-
- @override
- void warmup() {
- renderScene(null);
- }
-
- @override
- void exercise() {
- renderScene(null);
- }
-}
-
-void main() {
- const TracerBenchmark().report();
-}
diff --git a/example/Tracer/dart/app.dart b/example/Tracer/dart/app.dart
deleted file mode 100644
index 7c6c359..0000000
--- a/example/Tracer/dart/app.dart
+++ /dev/null
@@ -1,32 +0,0 @@
-// @dart=2.8
-library ray_trace;
-
-import 'dart:html';
-import 'dart:math';
-
-part 'color.dart';
-part 'engine.dart';
-part 'materials.dart';
-part 'scene.dart';
-part 'shapes.dart';
-part 'vector.dart';
-part 'renderscene.dart';
-
-// used to check if raytrace was correct (used by benchmarks)
-int checkNumber;
-
-void main() {
- var button = querySelector('#render');
- var canvas = querySelector('#canvas') as CanvasElement;
- var time = querySelector('#time');
- button.onClick.listen((e) {
- canvas.width =
- int.parse((querySelector('#imageWidth') as InputElement).value);
- canvas.height =
- int.parse((querySelector('#imageHeight') as InputElement).value);
- var sw = Stopwatch()..start();
- renderScene(e);
- sw.stop();
- time.text = sw.elapsedMilliseconds.toString();
- });
-}
diff --git a/example/Tracer/dart/color.dart b/example/Tracer/dart/color.dart
deleted file mode 100644
index 5892ce8..0000000
--- a/example/Tracer/dart/color.dart
+++ /dev/null
@@ -1,63 +0,0 @@
-// @dart=2.8
-// The ray tracer code in this file is written by Adam Burmister. It
-// is available in its original form from:
-//
-// http://labs.flog.co.nz/raytracer/
-//
-// Ported from the v8 benchmark suite by Google 2012.
-part of ray_trace;
-
-class Color {
- double red;
- double green;
- double blue;
-
- Color(this.red, this.green, this.blue);
-
- void limit() {
- red = (red > 0.0) ? ((red > 1.0) ? 1.0 : red) : 0.0;
- green = (green > 0.0) ? ((green > 1.0) ? 1.0 : green) : 0.0;
- blue = (blue > 0.0) ? ((blue > 1.0) ? 1.0 : blue) : 0.0;
- }
-
- Color operator +(Color c2) {
- return Color(red + c2.red, green + c2.green, blue + c2.blue);
- }
-
- Color addScalar(double s) {
- var result = Color(red + s, green + s, blue + s);
- result.limit();
- return result;
- }
-
- Color operator *(Color c2) {
- var result = Color(red * c2.red, green * c2.green, blue * c2.blue);
- return result;
- }
-
- Color multiplyScalar(double f) {
- var result = Color(red * f, green * f, blue * f);
- return result;
- }
-
- Color blend(Color c2, double w) {
- var result = multiplyScalar(1.0 - w) + c2.multiplyScalar(w);
- return result;
- }
-
- int brightness() {
- var r = (red * 255).toInt();
- var g = (green * 255).toInt();
- var b = (blue * 255).toInt();
- return (r * 77 + g * 150 + b * 29) >> 8;
- }
-
- @override
- String toString() {
- var r = (red * 255).toInt();
- var g = (green * 255).toInt();
- var b = (blue * 255).toInt();
-
- return 'rgb($r,$g,$b)';
- }
-}
diff --git a/example/Tracer/dart/engine.dart b/example/Tracer/dart/engine.dart
deleted file mode 100644
index d0e3cd2..0000000
--- a/example/Tracer/dart/engine.dart
+++ /dev/null
@@ -1,201 +0,0 @@
-// @dart=2.8
-// The ray tracer code in this file is written by Adam Burmister. It
-// is available in its original form from:
-//
-// http://labs.flog.co.nz/raytracer/
-//
-// Ported from the v8 benchmark suite by Google 2012.
-part of ray_trace;
-
-class IntersectionInfo {
- bool isHit = false;
- int hitCount = 0;
- BaseShape shape;
- Vector position;
- Vector normal;
- Color color;
- double distance;
-
- IntersectionInfo() {
- color = Color(0.0, 0.0, 0.0);
- }
-
- @override
- String toString() => 'Intersection [$position]';
-}
-
-class Engine {
- int canvasWidth;
- int canvasHeight;
- int pixelWidth, pixelHeight;
- bool renderDiffuse, renderShadows, renderHighlights, renderReflections;
- int rayDepth;
- CanvasRenderingContext2D canvas;
-
- Engine(
- {canvasWidth = 100,
- this.canvasHeight = 100,
- this.pixelWidth = 2,
- this.pixelHeight = 2,
- this.renderDiffuse = false,
- this.renderShadows = false,
- this.renderHighlights = false,
- this.renderReflections = false,
- this.rayDepth = 2}) {
- canvasHeight = canvasHeight ~/ pixelHeight;
- canvasWidth = canvasWidth ~/ pixelWidth;
- }
-
- void setPixel(int x, int y, Color color) {
- int pxW, pxH;
- pxW = pixelWidth;
- pxH = pixelHeight;
-
- if (canvas != null) {
- canvas.fillStyle = color.toString();
- canvas.fillRect(x * pxW, y * pxH, pxW, pxH);
- } else {
- if (x == y) {
- checkNumber += color.brightness();
- }
- }
- }
-
- // 'canvas' can be null if raytracer runs as benchmark
- void renderScene(Scene scene, CanvasElement canvas) {
- checkNumber = 0;
- /* Get canvas */
- this.canvas = canvas?.context2D;
-
- var canvasHeight = this.canvasHeight;
- var canvasWidth = this.canvasWidth;
-
- for (var y = 0; y < canvasHeight; y++) {
- for (var x = 0; x < canvasWidth; x++) {
- var yp = y * 1.0 / canvasHeight * 2 - 1;
- var xp = x * 1.0 / canvasWidth * 2 - 1;
-
- var ray = scene.camera.getRay(xp, yp);
- setPixel(x, y, getPixelColor(ray, scene));
- }
- }
- if ((canvas == null) && (checkNumber != 2321)) {
- // Used for benchmarking.
- throw 'Scene rendered incorrectly';
- }
- }
-
- Color getPixelColor(Ray ray, Scene scene) {
- var info = testIntersection(ray, scene, null);
- if (info.isHit) {
- var color = rayTrace(info, ray, scene, 0);
- return color;
- }
- return scene.background.color;
- }
-
- IntersectionInfo testIntersection(Ray ray, Scene scene, BaseShape exclude) {
- var hits = 0;
- var best = IntersectionInfo();
- best.distance = 2000;
-
- for (var i = 0; i < scene.shapes.length; i++) {
- var shape = scene.shapes[i];
-
- if (shape != exclude) {
- var info = shape.intersect(ray);
- if (info.isHit &&
- (info.distance >= 0) &&
- (info.distance < best.distance)) {
- best = info;
- hits++;
- }
- }
- }
- best.hitCount = hits;
- return best;
- }
-
- Ray getReflectionRay(Vector P, Vector N, Vector V) {
- var c1 = -N.dot(V);
- var R1 = N.multiplyScalar(2 * c1) + V;
- return Ray(P, R1);
- }
-
- Color rayTrace(IntersectionInfo info, Ray ray, Scene scene, int depth) {
- // Calc ambient
- var color = info.color.multiplyScalar(scene.background.ambience);
- var shininess = pow(10, info.shape.material.gloss + 1);
-
- for (var i = 0; i < scene.lights.length; i++) {
- var light = scene.lights[i];
-
- // Calc diffuse lighting
- var v = (light.position - info.position).normalize();
-
- if (renderDiffuse) {
- var L = v.dot(info.normal);
- if (L > 0.0) {
- color = color + info.color * light.color.multiplyScalar(L);
- }
- }
-
- // The greater the depth the more accurate the colours, but
- // this is exponentially (!) expensive
- if (depth <= rayDepth) {
- // calculate reflection ray
- if (renderReflections && info.shape.material.reflection > 0) {
- var reflectionRay =
- getReflectionRay(info.position, info.normal, ray.direction);
- var refl = testIntersection(reflectionRay, scene, info.shape);
-
- if (refl.isHit && refl.distance > 0) {
- refl.color = rayTrace(refl, reflectionRay, scene, depth + 1);
- } else {
- refl.color = scene.background.color;
- }
-
- color = color.blend(refl.color, info.shape.material.reflection);
- }
- // Refraction
- /* TODO */
- }
- /* Render shadows and highlights */
-
- var shadowInfo = IntersectionInfo();
-
- if (renderShadows) {
- var shadowRay = Ray(info.position, v);
-
- shadowInfo = testIntersection(shadowRay, scene, info.shape);
- if (shadowInfo.isHit &&
- shadowInfo.shape !=
- info.shape /*&& shadowInfo.shape.type != 'PLANE'*/) {
- var vA = color.multiplyScalar(0.5);
- var dB = 0.5 * pow(shadowInfo.shape.material.transparency, 0.5);
- color = vA.addScalar(dB);
- }
- }
- // Phong specular highlights
- if (renderHighlights &&
- !shadowInfo.isHit &&
- (info.shape.material.gloss > 0)) {
- var Lv = (info.shape.position - light.position).normalize();
-
- var E = (scene.camera.position - info.shape.position).normalize();
-
- var H = (E - Lv).normalize();
-
- var glossWeight = pow(max(info.normal.dot(H), 0), shininess).toDouble();
- color = light.color.multiplyScalar(glossWeight) + color;
- }
- }
- color.limit();
- return color;
- }
-
- @override
- String toString() {
- return 'Engine [canvasWidth: $canvasWidth, canvasHeight: $canvasHeight]';
- }
-}
diff --git a/example/Tracer/dart/index.html b/example/Tracer/dart/index.html
deleted file mode 100644
index dba6329..0000000
--- a/example/Tracer/dart/index.html
+++ /dev/null
@@ -1,38 +0,0 @@
-<!DOCTYPE html>
-
-<html>
- <head>
- <title>index</title>
- </head>
-
- <body>
- <canvas id="canvas" width="100" height="100" style="border:1px solid black"></canvas>
-
- <div>
- Width: <input type="text" id="imageWidth" value="500">
- </div>
- <div>
- Height: <input type="text" id="imageHeight" value="500">
- </div>
- <div>
- Pixel Size: <input type="text" id="pixelSize" value="1,1">
- </div>
- <div>
- Diffuse: <input type="checkbox" id="renderDiffuse" checked>
- </div>
- <div>
- Shadows: <input type="checkbox" id="renderShadows" checked>
- </div>
- <div>
- Highlights: <input type="checkbox" id="renderHighlights" checked>
- </div>
- <div>
- Reflections: <input type="checkbox" id="renderReflections" checked>
- </div>
- <button id="render">Render</button>
- <div>
- Time (ms): <span id="time"></span>
- </div>
- <script defer src="app.dart.js"></script>
- </body>
-</html>
diff --git a/example/Tracer/dart/materials.dart b/example/Tracer/dart/materials.dart
deleted file mode 100644
index de2e0dc..0000000
--- a/example/Tracer/dart/materials.dart
+++ /dev/null
@@ -1,63 +0,0 @@
-// @dart=2.8
-// The ray tracer code in this file is written by Adam Burmister. It
-// is available in its original form from:
-//
-// http://labs.flog.co.nz/raytracer/
-//
-// Ported from the v8 benchmark suite by Google 2012.
-part of ray_trace;
-
-abstract class Materials {
- final double gloss; // [0...infinity] 0 = matt
- final double transparency; // 0=opaque
- final double reflection; // [0...infinity] 0 = no reflection
- var refraction = 0.50;
- var hasTexture = false;
-
- Materials(this.reflection, this.transparency, this.gloss);
-
- Color getColor(double u, double v);
-
- double wrapUp(double t) {
- t = t % 2.0;
- if (t < -1) t += 2.0;
- if (t >= 1) t -= 2.0;
- return t;
- }
-}
-
-class Chessboard extends Materials {
- Color colorEven, colorOdd;
- double density;
-
- Chessboard(this.colorEven, this.colorOdd, double reflection,
- double transparency, double gloss, this.density)
- : super(reflection, transparency, gloss) {
- hasTexture = true;
- }
-
- @override
- Color getColor(double u, double v) {
- var t = wrapUp(u * density) * wrapUp(v * density);
-
- if (t < 0.0) {
- return colorEven;
- } else {
- return colorOdd;
- }
- }
-}
-
-class Solid extends Materials {
- Color color;
-
- Solid(this.color, double reflection, double refraction, double transparency,
- double gloss)
- : super(reflection, transparency, gloss) {
- hasTexture = false;
- this.refraction = refraction;
- }
-
- @override
- Color getColor(num u, num v) => color;
-}
diff --git a/example/Tracer/dart/readme.md b/example/Tracer/dart/readme.md
deleted file mode 100644
index dc3b17d..0000000
--- a/example/Tracer/dart/readme.md
+++ /dev/null
@@ -1,4 +0,0 @@
-To run:
-
- 1) `pub run build_runner serve example` from the root
- 2) Navigate to http://localhost:8080/Tracer/dart/
diff --git a/example/Tracer/dart/renderscene.dart b/example/Tracer/dart/renderscene.dart
deleted file mode 100644
index 4a25738..0000000
--- a/example/Tracer/dart/renderscene.dart
+++ /dev/null
@@ -1,91 +0,0 @@
-// @dart=2.8
-// The ray tracer code in this file is written by Adam Burmister. It
-// is available in its original form from:
-//
-// http://labs.flog.co.nz/raytracer/
-//
-// Ported from the v8 benchmark suite by Google 2012.
-part of ray_trace;
-
-class Light {
- final Vector position;
- final Color color;
- final double intensity;
-
- Light(this.position, this.color, [this.intensity = 10.0]);
-}
-
-// 'event' null means that we are benchmarking
-void renderScene(event) {
- var scene = Scene();
- scene.camera = Camera(
- Vector(0.0, 0.0, -15.0), Vector(-0.2, 0.0, 5.0), Vector(0.0, 1.0, 0.0));
- scene.background = Background(Color(0.5, 0.5, 0.5), 0.4);
-
- var sphere = Sphere(Vector(-1.5, 1.5, 2.0), 1.5,
- Solid(Color(0.0, 0.5, 0.5), 0.3, 0.0, 0.0, 2.0));
-
- var sphere1 = Sphere(Vector(1.0, 0.25, 1.0), 0.5,
- Solid(Color(0.9, 0.9, 0.9), 0.1, 0.0, 0.0, 1.5));
-
- var plane = Plane(
- Vector(0.1, 0.9, -0.5).normalize(),
- 1.2,
- Chessboard(
- Color(1.0, 1.0, 1.0), Color(0.0, 0.0, 0.0), 0.2, 0.0, 1.0, 0.7));
-
- scene.shapes.add(plane);
- scene.shapes.add(sphere);
- scene.shapes.add(sphere1);
-
- var light = Light(Vector(5.0, 10.0, -1.0), Color(0.8, 0.8, 0.8));
-
- var light1 = Light(Vector(-3.0, 5.0, -15.0), Color(0.8, 0.8, 0.8), 100.0);
-
- scene.lights.add(light);
- scene.lights.add(light1);
-
- int imageWidth, imageHeight, pixelSize;
- bool renderDiffuse, renderShadows, renderHighlights, renderReflections;
- CanvasElement canvas;
- if (event == null) {
- imageWidth = 100;
- imageHeight = 100;
- pixelSize = 5;
- renderDiffuse = true;
- renderShadows = true;
- renderHighlights = true;
- renderReflections = true;
- canvas = null;
- } else {
- imageWidth =
- int.parse((querySelector('#imageWidth') as InputElement).value);
- imageHeight =
- int.parse((querySelector('#imageHeight') as InputElement).value);
- pixelSize = int.parse(
- (querySelector('#pixelSize') as InputElement).value.split(',')[0]);
- renderDiffuse =
- (querySelector('#renderDiffuse') as CheckboxInputElement).checked;
- renderShadows =
- (querySelector('#renderShadows') as CheckboxInputElement).checked;
- renderHighlights =
- (querySelector('#renderHighlights') as CheckboxInputElement).checked;
- renderReflections =
- (querySelector('#renderReflections') as CheckboxInputElement).checked;
- canvas = querySelector('#canvas') as CanvasElement;
- }
- var rayDepth = 2;
-
- var raytracer = Engine(
- canvasWidth: imageWidth,
- canvasHeight: imageHeight,
- pixelWidth: pixelSize,
- pixelHeight: pixelSize,
- renderDiffuse: renderDiffuse,
- renderShadows: renderShadows,
- renderReflections: renderReflections,
- renderHighlights: renderHighlights,
- rayDepth: rayDepth);
-
- raytracer.renderScene(scene, canvas);
-}
diff --git a/example/Tracer/dart/scene.dart b/example/Tracer/dart/scene.dart
deleted file mode 100644
index 9465ac9..0000000
--- a/example/Tracer/dart/scene.dart
+++ /dev/null
@@ -1,67 +0,0 @@
-// @dart=2.8
-// The ray tracer code in this file is written by Adam Burmister. It
-// is available in its original form from:
-//
-// http://labs.flog.co.nz/raytracer/
-//
-// Ported from the v8 benchmark suite by Google 2012.
-part of ray_trace;
-
-class Ray {
- final Vector position;
- final Vector direction;
-
- Ray(this.position, this.direction);
-
- @override
- String toString() {
- return 'Ray [$position, $direction]';
- }
-}
-
-class Camera {
- final Vector position;
- final Vector lookAt;
- final Vector up;
- Vector equator, screen;
-
- Camera(this.position, this.lookAt, this.up) {
- equator = lookAt.normalize().cross(up);
- screen = position + lookAt;
- }
-
- Ray getRay(double vx, double vy) {
- var pos = screen - (equator.multiplyScalar(vx) - up.multiplyScalar(vy));
- pos.y = pos.y * -1.0;
- var dir = pos - position;
- var ray = Ray(pos, dir.normalize());
- return ray;
- }
-
- @override
- String toString() {
- return 'Camera []';
- }
-}
-
-class Background {
- final Color color;
- final double ambience;
-
- Background(this.color, this.ambience);
-}
-
-class Scene {
- Camera camera;
- List<BaseShape> shapes;
- List<Light> lights;
- Background background;
-
- Scene() {
- camera = Camera(
- Vector(0.0, 0.0, -0.5), Vector(0.0, 0.0, 1.0), Vector(0.0, 1.0, 0.0));
- shapes = [];
- lights = [];
- background = Background(Color(0.0, 0.0, 0.5), 0.2);
- }
-}
diff --git a/example/Tracer/dart/shapes.dart b/example/Tracer/dart/shapes.dart
deleted file mode 100644
index c7d1ff6..0000000
--- a/example/Tracer/dart/shapes.dart
+++ /dev/null
@@ -1,99 +0,0 @@
-// @dart=2.8
-// The ray tracer code in this file is written by Adam Burmister. It
-// is available in its original form from:
-//
-// http://labs.flog.co.nz/raytracer/
-//
-// Ported from the v8 benchmark suite by Google 2012.
-part of ray_trace;
-
-abstract class BaseShape {
- final Vector position;
- final Materials material;
-
- BaseShape(this.position, this.material);
-
- IntersectionInfo intersect(Ray ray);
-
- @override
- String toString() {
- return 'BaseShape';
- }
-}
-
-class Plane extends BaseShape {
- final double d;
-
- Plane(Vector pos, this.d, Materials material) : super(pos, material);
-
- @override
- IntersectionInfo intersect(Ray ray) {
- var info = IntersectionInfo();
-
- var Vd = position.dot(ray.direction);
- if (Vd == 0) return info; // no intersection
-
- var t = -(position.dot(ray.position) + d) / Vd;
- if (t <= 0) return info;
-
- info.shape = this;
- info.isHit = true;
- info.position = ray.position + ray.direction.multiplyScalar(t);
- info.normal = position;
- info.distance = t;
-
- if (material.hasTexture) {
- var vU = Vector(position.y, position.z, -position.x);
- var vV = vU.cross(position);
- var u = info.position.dot(vU);
- var v = info.position.dot(vV);
- info.color = material.getColor(u, v);
- } else {
- info.color = material.getColor(0, 0);
- }
-
- return info;
- }
-
- @override
- String toString() {
- return 'Plane [$position, d=$d]';
- }
-}
-
-class Sphere extends BaseShape {
- double radius;
-
- Sphere(Vector pos, this.radius, Materials material) : super(pos, material);
-
- @override
- IntersectionInfo intersect(Ray ray) {
- var info = IntersectionInfo();
- info.shape = this;
-
- var dst = ray.position - position;
-
- var B = dst.dot(ray.direction);
- var C = dst.dot(dst) - (radius * radius);
- var D = (B * B) - C;
-
- if (D > 0) {
- // intersection!
- info.isHit = true;
- info.distance = (-B) - sqrt(D);
- info.position =
- ray.position + ray.direction.multiplyScalar(info.distance);
- info.normal = (info.position - position).normalize();
-
- info.color = material.getColor(0, 0);
- } else {
- info.isHit = false;
- }
- return info;
- }
-
- @override
- String toString() {
- return 'Sphere [position=$position, radius=$radius]';
- }
-}
diff --git a/example/Tracer/dart/vector.dart b/example/Tracer/dart/vector.dart
deleted file mode 100644
index d8d7ad6..0000000
--- a/example/Tracer/dart/vector.dart
+++ /dev/null
@@ -1,57 +0,0 @@
-// @dart=2.8
-// The ray tracer code in this file is written by Adam Burmister. It
-// is available in its original form from:
-//
-// http://labs.flog.co.nz/raytracer/
-//
-// Ported from the v8 benchmark suite by Google 2012.
-part of ray_trace;
-
-class Vector {
- double x, y, z;
- Vector(this.x, this.y, this.z);
-
- void copy(Vector v) {
- x = v.x;
- y = v.y;
- z = v.z;
- }
-
- Vector normalize() {
- var m = magnitude();
- return Vector(x / m, y / m, z / m);
- }
-
- double magnitude() {
- return sqrt((x * x) + (y * y) + (z * z));
- }
-
- Vector cross(Vector w) {
- return Vector(-z * w.y + y * w.z, z * w.x - x * w.z, -y * w.x + x * w.y);
- }
-
- double dot(Vector w) {
- return x * w.x + y * w.y + z * w.z;
- }
-
- Vector operator +(Vector w) {
- return Vector(w.x + x, w.y + y, w.z + z);
- }
-
- Vector operator -(Vector w) {
- return Vector(x - w.x, y - w.y, z - w.z);
- }
-
- Vector operator *(Vector w) {
- return Vector(x * w.x, y * w.y, z * w.z);
- }
-
- Vector multiplyScalar(double w) {
- return Vector(x * w, y * w, z * w);
- }
-
- @override
- String toString() {
- return 'Vector [$x, $y ,$z ]';
- }
-}
diff --git a/example/Tracer/js/Tracer.js b/example/Tracer/js/Tracer.js
deleted file mode 100644
index 52744e5..0000000
--- a/example/Tracer/js/Tracer.js
+++ /dev/null
@@ -1,749 +0,0 @@
-// The ray tracer code in this file is written by Adam Burmister. It
-// is available in its original form from:
-//
-// http://labs.flog.nz.co/raytracer/
-//
-// It has been modified slightly by Google to work as a standalone
-// benchmark, but the all the computational code remains
-// untouched. This file also contains a copy of parts of the Prototype
-// JavaScript framework which is used by the ray tracer.
-
-"use strict";
-var scope = this;
-
-// Variable used to hold a number that can be used to verify that
-// the scene was ray traced correctly.
-var checkNumber;
-
-// ------------------------------------------------------------------------
-// ------------------------------------------------------------------------
-
-// The following is a copy of parts of the Prototype JavaScript library:
-
-// Prototype JavaScript framework, version 1.5.0
-// (c) 2005-2007 Sam Stephenson
-//
-// Prototype is freely distributable under the terms of an MIT-style license.
-// For details, see the Prototype web site: http://prototype.conio.net/
-
-Object.extend = function(destination, source) {
- Object.keys(source).forEach(function(p) {
- destination[p] = source[p];
- })
- return destination;
-};
-
-
-// ------------------------------------------------------------------------
-// ------------------------------------------------------------------------
-
-// The rest of this file is the actual ray tracer written by Adam
-// Burmister. It's a concatenation of the following files:
-//
-// flog/color.js
-// flog/light.js
-// flog/vector.js
-// flog/ray.js
-// flog/scene.js
-// flog/material/basematerial.js
-// flog/material/solid.js
-// flog/material/chessboard.js
-// flog/shape/baseshape.js
-// flog/shape/sphere.js
-// flog/shape/plane.js
-// flog/intersectioninfo.js
-// flog/camera.js
-// flog/background.js
-// flog/engine.js
-
-/* Fake a Flog.* namespace */
-if(typeof(scope.Flog) == 'undefined') {
- var Flog = scope.Flog = { RayTracer: { Shape: {}, Material: {} } };
-}
-
-var Color =
-Flog.RayTracer.Color = function(r, g, b) {
- this.red = r;
- this.green = g;
- this.blue = b;
-};
-Color.prototype = {
- add: function(c){
- return new Color(
- this.red + c.red,
- this.green + c.green,
- this.blue + c.blue
- );
- },
-
- addScalar: function(s){
- var result = new Color(
- this.red + s,
- this.green + s,
- this.blue + s);
- result.limit();
- return result;
- },
-
- subtract: function(c1, c2){
- return new Color(
- c1.red - c2.red,
- c1.green - c2.green,
- c1.blue - c2.blue
- );
- },
-
- multiply: function(c) {
- return new Color(
- this.red * c.red,
- this.green * c.green,
- this.blue * c.blue
- );
- },
-
- multiplyScalar: function(f) {
- return new Color(
- this.red * f,
- this.green * f,
- this.blue * f
- );
- },
-
- divideFactor: function(c1, f) {
- return new Color(
- c1.red / f,
- c1.green / f,
- c1.blue / f
- );
- },
-
- limit: function() {
- this.red = (this.red > 0.0) ?
- ( (this.red > 1.0) ? 1.0 : this.red ) : 0.0;
- this.green = (this.green > 0.0) ?
- ( (this.green > 1.0) ? 1.0 : this.green ) : 0.0;
- this.blue = (this.blue > 0.0) ?
- ( (this.blue > 1.0) ? 1.0 : this.blue ) : 0.0;
- },
-
- distance : function(color) {
- return Math.abs(this.red - color.red) +
- Math.abs(this.green - color.green) +
- Math.abs(this.blue - color.blue);
- },
-
- blend: function(c, w){
- return this.multiplyScalar(1-w).add(c.multiplyScalar(w));
- },
-
- brightness : function() {
- var r = Math.floor(this.red*255);
- var g = Math.floor(this.green*255);
- var b = Math.floor(this.blue*255);
- return (r * 77 + g * 150 + b * 29) >> 8;
- },
-
- toString : function () {
- var r = Math.floor(this.red*255);
- var g = Math.floor(this.green*255);
- var b = Math.floor(this.blue*255);
- return "rgb("+ r +","+ g +","+ b +")";
- }
-};
-
-var Light =
-Flog.RayTracer.Light = function (pos, color, intensity) {
- this.position = pos;
- this.color = color;
- this.intensity = (intensity ? intensity : 10.0);
-};
-Light.prototype = {
- toString : function () {
- var pos = this.position;
- return 'Light [' + pos.x + ','
- + pos.y + ','
- + pos.z + ']';
- }
-};
-
-var Vector =
-Flog.RayTracer.Vector = function (x, y, z) {
- this.x = x;
- this.y = y;
- this.z = z;
-};
-Vector.prototype = {
- copy: function(v){
- this.x = v.x;
- this.y = v.y;
- this.z = v.z;
- },
-
- normalize : function() {
- var m = this.magnitude();
- return new Vector(
- this.x / m,
- this.y / m,
- this.z / m
- );
- },
-
- magnitude : function() {
- return Math.sqrt(this.x*this.x + this.y*this.y + this.z*this.z);
- },
-
- cross : function(w) {
- return new Vector(
- -this.z * w.y + this.y * w.z,
- this.z * w.x - this.x * w.z,
- -this.y * w.x + this.x * w.y);
- },
-
- dot : function(w) {
- return this.x * w.x + this.y * w.y + this.z * w.z;
- },
-
- add: function(w) {
- return new Vector(w.x + this.x,
- w.y + this.y,
- w.z + this.z);
- },
-
- subtract: function(w) {
- return new Vector(this.x - w.x,
- this.y - w.y,
- this.z - w.z);
- },
-
- multiplyScalar: function(w) {
- return new Vector(this.x * w,
- this.y * w,
- this.z * w);
- },
-
- toString : function () {
- return 'Vector [' + this.x + ',' + this.y + ',' + this.z + ']';
- }
-};
-
-var Ray =
-Flog.RayTracer.Ray = function(pos, dir) {
- this.position = pos;
- this.direction = dir;
-};
-Ray.prototype = {
- toString : function () {
- return 'Ray [' + this.position + ',' + this.direction + ']';
- }
-};
-
-var Scene =
-Flog.RayTracer.Scene = function() {
- this.camera = new Camera(
- new Vector(0,0,-5),
- new Vector(0,0,1),
- new Vector(0,1,0)
- );
- this.shapes = [];
- this.lights = [];
- this.background = new Background(new Color(0,0,0.5), 0.2);
-};
-
-var BaseMaterial =
-Flog.RayTracer.Material.BaseMaterial = function(reflection,
- transparency,
- glass) {
- this.gloss = glass;
- this.transparency = transparency;
- this.reflection = reflection;
- this.refraction = 0.50;
- this.hasTexture = false;
-};
-BaseMaterial.prototype = {
- wrapUp: function(t){
- t = t % 2.0;
- if(t < -1) t += 2.0;
- if(t >= 1) t -= 2.0;
- return t;
- },
-
- toString : function () {
- return 'Material [gloss=' + this.gloss + ', transparency=' + this.transparency + ', hasTexture=' + this.hasTexture +']';
- }
-}
-
-var Solid =
-Flog.RayTracer.Material.Solid = function(color, reflection, refraction, transparency, gloss) {
- this.color = color;
- this.reflection = reflection;
- this.transparency = transparency;
- this.gloss = gloss;
- this.hasTexture = false;
-};
-Solid.prototype = Object.create(BaseMaterial.prototype, {
- getColor: {
- value: function() { return this.color; },
- },
- toString: {
- value: function() {
- return 'SolidMaterial [gloss=' + this.gloss +
- ', transparency=' + this.transparency +
- ', hasTexture=' + this.hasTexture +']';
- }
- }
-});
-
-var Chessboard =
-Flog.RayTracer.Material.Chessboard = function(
- colorEven,
- colorOdd,
- reflection,
- transparency,
- gloss,
- density) {
- this.colorEven = colorEven;
- this.colorOdd = colorOdd;
- this.reflection = reflection;
- this.transparency = transparency;
- this.gloss = gloss;
- this.density = density;
- this.hasTexture = true;
-};
-
-Chessboard.prototype = Object.create(BaseMaterial.prototype, {
- getColor: {
- value: function(u, v){
- var t = this.wrapUp(u * this.density) * this.wrapUp(v * this.density);
- if(t < 0.0) {
- return this.colorEven;
- } else {
- return this.colorOdd;
- }
- }
- },
- toString: {
- value: function(){
- return 'ChessMaterial [gloss=' + this.gloss +
- ', transparency=' + this.transparency +
- ', hasTexture=' + this.hasTexture +']';
- }
- }
-});
-
-
-var Sphere =
-Flog.RayTracer.Shape.Sphere = function(pos, radius, material) {
- this.radius = radius;
- this.position = pos;
- this.material = material;
-};
-Sphere.prototype = {
-
- _foundIntersection: function(B, D, info, ray) {
- info.isHit = true;
- info.distance = (-B) - Math.sqrt(D);
- info.position =
- ray.position.add(ray.direction.multiplyScalar(info.distance));
- info.normal = info.position.subtract(this.position).normalize();
- info.color = this.material.getColor(0,0);
- },
-
- intersect: function(ray){
- var info = new IntersectionInfo();
- info.shape = this;
- info.isHit = false;
-
- var dst = ray.position.subtract(this.position);
- var B = dst.dot(ray.direction);
- var C = dst.dot(dst) - (this.radius * this.radius);
- var D = (B * B) - C;
-
- if(D > 0) { // intersection!
- this._foundIntersection(B, D, info, ray);
- }
- return info;
- },
-
- toString : function () {
- return 'Sphere [position=' + this.position +
- ', radius=' + this.radius + ']';
- }
-}
-
-var Plane =
-Plane = function(pos, d, material) {
- this.position = pos;
- this.d = d;
- this.material = material;
-};
-Plane.prototype = {
- _hasTexture: function() {
-
- },
- intersect: function(ray){
- var info = new IntersectionInfo();
- var pos = this.position;
- var mat = this.material;
-
- var Vd = pos.dot(ray.direction);
- if(Vd == 0) return info; // no intersection
-
- var t = -(pos.dot(ray.position) + this.d) / Vd;
- if(t <= 0) { return info; }
-
- info.shape = this;
- info.isHit = true;
- info.position = ray.position.add(ray.direction.multiplyScalar(t));
- info.normal = pos;
- info.distance = t;
-
- if(mat.hasTexture){
- var vU = new Vector(pos.y, pos.z, -pos.x);
- var vV = vU.cross(pos);
- var u = info.position.dot(vU);
- var v = info.position.dot(vV);
- info.color = mat.getColor(u,v);
- } else {
- info.color = mat.getColor(0,0);
- }
- return info;
- },
-
- toString : function () {
- return 'Plane [' + this.position + ', d=' + this.d + ']';
- }
-}
-
-var IntersectionInfo =
-Flog.RayTracer.IntersectionInfo = function(shape) {
- this.color = new Color(0,0,0);
- this.isHit = false;
- this.hitCount = 0;
- this.shape = null;
- this.position = null;
- this.normal = null;
- this.color = null;
- this.distance = null;
-};
-IntersectionInfo.prototype = {
- toString : function () {
- return 'Intersection [' + this.position + ']';
- }
-}
-
-var Camera =
-Flog.RayTracer.Camera = function(pos, lookAt, up) {
- this.position = pos;
- this.lookAt = lookAt;
- this.up = up;
- this.equator = lookAt.normalize().cross(this.up);
- this.screen = this.position.add(this.lookAt);
-};
-Camera.prototype = {
- getRay: function(vx, vy){
- var pos = this.screen.subtract(
- this.equator.multiplyScalar(vx).subtract(this.up.multiplyScalar(vy))
- );
- pos.y = pos.y * -1;
- var dir = pos.subtract(this.position);
- return new Ray(pos, dir.normalize());
- },
-
- toString : function () { return 'Ray []'; }
-}
-
-var Background =
-Flog.RayTracer.Background = function(color, ambience) {
- this.color = color;
- this.ambience = ambience;
-};
-
-var Engine =
-Flog.RayTracer.Engine = function(options){
- this.options = Object.extend({
- canvasHeight: 100,
- canvasWidth: 100,
- pixelWidth: 2,
- pixelHeight: 2,
- renderDiffuse: false,
- renderShadows: false,
- renderHighlights: false,
- renderReflections: false,
- rayDepth: 2
- }, options || {});
-
- this.options.canvasHeight /= this.options.pixelHeight;
- this.options.canvasWidth /= this.options.pixelWidth;
- this.canvas = null;
- /* TODO: dynamically include other scripts */
-};
-Engine.prototype = {
- setPixel: function(x, y, color){
- var pxW, pxH;
- pxW = this.options.pixelWidth;
- pxH = this.options.pixelHeight;
-
- if (this.canvas) {
- this.canvas.fillStyle = color.toString();
- this.canvas.fillRect (x * pxW, y * pxH, pxW, pxH);
- } else {
- if (x === y) {
- checkNumber += color.brightness();
- }
- // print(x * pxW, y * pxH, pxW, pxH);
- }
- },
-
- renderScene: function(scene, canvas){
- checkNumber = 0;
- /* Get canvas */
- if (canvas) {
- this.canvas = canvas.getContext("2d");
- } else {
- this.canvas = null;
- }
-
- var canvasHeight = this.options.canvasHeight;
- var canvasWidth = this.options.canvasWidth;
-
- for(var y=0; y < canvasHeight; y++){
- for(var x=0; x < canvasWidth; x++){
- var yp = y * 1.0 / canvasHeight * 2 - 1;
-
- var xp = x * 1.0 / canvasWidth * 2 - 1;
- var ray = scene.camera.getRay(xp, yp);
- var color = this.getPixelColor(ray, scene);
- this.setPixel(x, y, color);
- }
- }
- if (canvas == null && checkNumber !== 2321) {
- throw new Error("Scene rendered incorrectly");
- }
- },
-
- getPixelColor: function(ray, scene){
- var info = this.testIntersection(ray, scene, null);
- if(info.isHit){
- return this.rayTrace(info, ray, scene, 0);
- }
- return scene.background.color;
- },
-
- // FIXME(slightlyoff): HOT!
- testIntersection: function(ray, scene, exclude){
- var hits = 0;
- var best = new IntersectionInfo();
- best.distance = 2000;
- var info;
- var distance = 0|0;
-
- var shapesLength = scene.shapes.length;
- for(var i = 0; i < shapesLength; i++){
- if(scene.shapes[i] !== exclude){
- info = scene.shapes[i].intersect(ray);
- distance = info.distance;
- if(info.isHit && distance >= 0 && distance < best.distance) {
- best = info;
- hits++;
- }
- }
- }
- best.hitCount = hits;
- return best;
- },
-
- getReflectionRay: function(P,N,V){
- var c1 = -N.dot(V);
- var R1 = N.multiplyScalar(2*c1).add(V);
- return new Ray(P, R1);
- },
-
- rayTrace: function(info, ray, scene, depth) {
- // Calc ambient
- var color = info.color.multiplyScalar(scene.background.ambience);
- var oldColor = color;
- var shininess = Math.pow(10, info.shape.material.gloss + 1);
-
- for(var i=0; i<scene.lights.length; i++) {
- var light = scene.lights[i];
-
- // Calc diffuse lighting
- var v = light.position.subtract(info.position).normalize();
-
- if(this.options.renderDiffuse){
- var L = v.dot(info.normal);
- if(L > 0){
- color = color.add(
- info.color.multiply(
- light.color.multiplyScalar(L)
- )
- );
- }
- }
-
- // The greater the depth the more accurate the colours, but
- // this is exponentially (!) expensive
- if(depth <= this.options.rayDepth){
- // calculate reflection ray
- if(this.options.renderReflections &&
- info.shape.material.reflection > 0) {
-
- var reflectionRay = this.getReflectionRay(
- info.position, info.normal, ray.direction);
- var refl = this.testIntersection(reflectionRay, scene, info.shape);
-
- if (refl.isHit && refl.distance > 0){
- refl.color = this.rayTrace(refl, reflectionRay, scene, depth + 1);
- } else {
- refl.color = scene.background.color;
- }
-
- color = color.blend(
- refl.color, info.shape.material.reflection
- );
- }
- // Refraction
- /* TODO */
- }
-
- /* Render shadows and highlights */
- var shadowInfo = new IntersectionInfo();
-
- if(this.options.renderShadows) {
- var shadowRay = new Ray(info.position, v);
-
- shadowInfo = this.testIntersection(shadowRay, scene,
- info.shape);
- if(shadowInfo.isHit && shadowInfo.shape != info.shape
- /*&& shadowInfo.shape.type != 'PLANE'*/) {
- var vA = color.multiplyScalar(0.5);
- var dB = (0.5 * Math.pow(shadowInfo.shape.material.transparency, 0.5));
- color = vA.addScalar(dB);
- }
- }
-
- // Phong specular highlights
- if(this.options.renderHighlights && !shadowInfo.isHit && info.shape.material.gloss > 0) {
- var Lv = info.shape.position.subtract(light.position)
- .normalize();
- var E = scene.camera.position.subtract(info.shape.position)
- .normalize();
- var H = E.subtract(Lv).normalize();
- var glossWeight =
- Math.pow(Math.max(info.normal.dot(H), 0), shininess);
- color = light.color.multiplyScalar(glossWeight).add(color);
- }
- }
- color.limit();
- return color;
- }
-};
-
-// 'event' null means that we are benchmarking
-var renderScene =
-scope.renderScene = function(event){
- var scene = new Scene();
-
- scene.camera = new Camera(
- new Vector(0, 0, -15),
- new Vector(-0.2, 0, 5),
- new Vector(0, 1, 0)
- );
-
- scene.background = new Background(new Color(0.5, 0.5, 0.5), 0.4 );
-
- var sphere = new Sphere(
- new Vector(-1.5, 1.5, 2),
- 1.5,
- new Solid(
- new Color(0,0.5,0.5),
- 0.3,
- 0.0,
- 0.0,
- 2.0
- )
- );
-
- var sphere1 = new Sphere(
- new Vector(1, 0.25, 1),
- 0.5,
- new Solid(
- new Color(0.9,0.9,0.9),
- 0.1,
- 0.0,
- 0.0,
- 1.5
- )
- );
-
- var plane = new Plane(
- new Vector(0.1, 0.9, -0.5).normalize(),
- 1.2,
- new Chessboard(
- new Color(1,1,1),
- new Color(0,0,0),
- 0.2,
- 0.0,
- 1.0,
- 0.7
- )
- );
-
- scene.shapes.push(plane);
- scene.shapes.push(sphere);
- scene.shapes.push(sphere1);
-
- var light = new Light(
- new Vector(5, 10, -1),
- new Color(0.8, 0.8, 0.8)
- );
-
- var light1 = new Light(
- new Vector(-3, 5, -15),
- new Color(0.8, 0.8, 0.8),
- 100
- );
-
- scene.lights.push(light);
- scene.lights.push(light1);
-
- var imageWidth, imageHeight, pixelSize;
- var renderDiffuse, renderShadows, renderHighlights, renderReflections;
- var canvas;
-
- if (typeof(event) == 'undefined' || event == null) {
- imageWidth = 100;
- imageHeight = 100;
- pixelSize = "5,5".split(',');
- renderDiffuse = true;
- renderShadows = true;
- renderHighlights = true;
- renderReflections = true;
- canvas = null;
- } else {
- imageWidth = parseInt(document.getElementById('imageWidth').value);
- imageHeight = parseInt(document.getElementById('imageHeight').value);
- pixelSize = document.getElementById('pixelSize').value.split(',');
- renderDiffuse = document.getElementById('renderDiffuse').checked;
- renderShadows = document.getElementById('renderShadows').checked;
- renderHighlights = document.getElementById('renderHighlights').checked;
- renderReflections = document.getElementById('renderReflections').checked;
- canvas = document.getElementById("canvas");
- }
-
- var rayDepth = 2;//$F('rayDepth');
-
- var raytracer = new Engine({
- canvasWidth: imageWidth,
- canvasHeight: imageHeight,
- pixelWidth: parseInt(pixelSize[0]),
- pixelHeight: parseInt(pixelSize[1]),
- "renderDiffuse": renderDiffuse,
- "renderHighlights": renderHighlights,
- "renderShadows": renderShadows,
- "renderReflections": renderReflections,
- "rayDepth": rayDepth
- });
-
- raytracer.renderScene(scene, canvas, 0);
-};
diff --git a/example/Tracer/js/app.js b/example/Tracer/js/app.js
deleted file mode 100644
index 52cabec..0000000
--- a/example/Tracer/js/app.js
+++ /dev/null
@@ -1,17 +0,0 @@
-(function() {
-
- var button = document.getElementById('render');
- var canvas = document.getElementById('canvas');
- var time = document.getElementById('time');
-
- var run = function(e) {
- canvas.width = parseInt(document.getElementById('imageWidth').value);
- canvas.height = parseInt(document.getElementById('imageHeight').value);
- canvas.getContext("2d").clearRect(0,0,canvas.width,canvas.height)
- var start = performance.now();
- renderScene(e);
- var stop = performance.now();
- time.innerHTML = Number(stop - start).toFixed(2).toString();
- };
- button.addEventListener('click', run);
-})();
diff --git a/example/Tracer/js/bench.js b/example/Tracer/js/bench.js
deleted file mode 100644
index dda992c..0000000
--- a/example/Tracer/js/bench.js
+++ /dev/null
@@ -1,31 +0,0 @@
-var Benchmark = {
- measureFor: function(f, timeMinimum) {
- "use asm";
- var elapsed = 0;
- var iterations = 0;
- var start = +(performance.now());
- while (elapsed < timeMinimum) {
- iterations++;
- f();
- elapsed = +(+(performance.now()) - start);
- }
- return 1000 * elapsed / iterations;
- },
-
- measure: function(warmup, exercise) {
- if (!exercise) {
- exercise = function() {
- for (var i = 0; i < 10; i++) {
- warmup();
- }
- };
- }
- this.measureFor(warmup, 100);
- return this.measureFor(exercise, 2000);
- },
-
- report: function(name, warmup, exercise) {
- var score = this.measure(warmup, exercise);
- print(name + "(RunTime): " + Number(score).toFixed(2) + " us.");
- }
-};
diff --git a/example/Tracer/js/benchmark_tracer.js b/example/Tracer/js/benchmark_tracer.js
deleted file mode 100644
index 3aac5b5..0000000
--- a/example/Tracer/js/benchmark_tracer.js
+++ /dev/null
@@ -1 +0,0 @@
-Benchmark.report("Tracer", renderScene, renderScene);
\ No newline at end of file
diff --git a/example/Tracer/js/index.html b/example/Tracer/js/index.html
deleted file mode 100644
index 3b6fe8d..0000000
--- a/example/Tracer/js/index.html
+++ /dev/null
@@ -1,39 +0,0 @@
-<!DOCTYPE html>
-
-<html>
- <head>
- <title>index</title>
- </head>
-
- <body>
- <canvas id="canvas" width="100" height="100" style="border:1px solid black"></canvas>
-
- <div>
- Width: <input type="text" id="imageWidth" value="500">
- </div>
- <div>
- Height: <input type="text" id="imageHeight" value="500">
- </div>
- <div>
- Pixel Size: <input type="text" id="pixelSize" value="1,1">
- </div>
- <div>
- Diffuse: <input type="checkbox" id="renderDiffuse" checked>
- </div>
- <div>
- Shadows: <input type="checkbox" id="renderShadows" checked>
- </div>
- <div>
- Highlights: <input type="checkbox" id="renderHighlights" checked>
- </div>
- <div>
- Reflections: <input type="checkbox" id="renderReflections" checked>
- </div>
- <button id="render">Render</button>
- <div>
- Time (ms): <span id="time"></span>
- </div>
- <script src="Tracer.js"></script>
- <script src="app.js"></script>
- </body>
-</html>
diff --git a/example/Tracer/js/run.sh b/example/Tracer/js/run.sh
deleted file mode 100755
index 567a3c5..0000000
--- a/example/Tracer/js/run.sh
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/bin/sh
-
-# d8 is a tool included with V8:
-# https://code.google.com/p/v8/
-
-d8 bench.js Tracer.js benchmark_tracer.js
diff --git a/lib/benchmark_harness.dart b/lib/benchmark_harness.dart
index 5cea7bf..46153a0 100644
--- a/lib/benchmark_harness.dart
+++ b/lib/benchmark_harness.dart
@@ -1,3 +1,7 @@
+// Copyright (c) 2021, 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.
+
library benchmark_harness;
part 'src/benchmark_base.dart';
diff --git a/lib/src/benchmark_base.dart b/lib/src/benchmark_base.dart
index 2165828..f416ebf 100644
--- a/lib/src/benchmark_base.dart
+++ b/lib/src/benchmark_base.dart
@@ -1,4 +1,6 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
+// Copyright (c) 2012, 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.
part of benchmark_harness;
diff --git a/lib/src/score_emitter.dart b/lib/src/score_emitter.dart
index 0e807d7..e88749d 100644
--- a/lib/src/score_emitter.dart
+++ b/lib/src/score_emitter.dart
@@ -1,3 +1,7 @@
+// Copyright (c) 2012, 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.
+
part of benchmark_harness;
abstract class ScoreEmitter {
diff --git a/test/benchmark_harness_test.dart b/test/benchmark_harness_test.dart
index 836d812..bc85579 100644
--- a/test/benchmark_harness_test.dart
+++ b/test/benchmark_harness_test.dart
@@ -1,6 +1,6 @@
-// Copyright (c) 2014, Google Inc. 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.
+// Copyright (c) 2021, 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.
library benchmark_harness_test;
diff --git a/test/result_emitter_test.dart b/test/result_emitter_test.dart
index 540175b..b5165a6 100644
--- a/test/result_emitter_test.dart
+++ b/test/result_emitter_test.dart
@@ -1,3 +1,7 @@
+// Copyright (c) 2021, 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.
+
library result_emitter_test;
import 'package:benchmark_harness/benchmark_harness.dart';