Implement row.dart and some other minor utility methods
diff --git a/lib/cassowary.dart b/lib/cassowary.dart index c3cea2d..1666b0d 100644 --- a/lib/cassowary.dart +++ b/lib/cassowary.dart
@@ -12,3 +12,5 @@ part 'constant_member.dart'; part 'solver.dart'; part 'symbol.dart'; +part 'row.dart'; +part 'utils.dart';
diff --git a/lib/row.dart b/lib/row.dart new file mode 100644 index 0000000..8fb6156 --- /dev/null +++ b/lib/row.dart
@@ -0,0 +1,62 @@ +// Copyright (c) 2015 The Chromium Authors. 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 cassowary; + +class Row { + final Map<Symbol, double> _cells = new Map<Symbol, double>(); + double _constant = 0.0; + + double get constant => _constant; + Map<Symbol, double> get cells => _cells; + + double add(double value) => _constant += value; + + void insertSymbol(Symbol symbol, [double coefficient = 1.0]) { + double val = _elvis(_cells[symbol], 0.0) + coefficient; + + if (_nearZero(val)) { + _cells.remove(symbol); + } else { + _cells[symbol] = val + coefficient; + } + } + + void insertRow(Row other, [double coefficient = 1.0]) { + _constant += other.constant * coefficient; + other.cells.forEach((s, v) => insertSymbol(s, v * coefficient)); + } + + void removeSymbol(Symbol symbol) { + _cells.remove(symbol); + } + + void reverseSign() => _cells.forEach((s, v) => _cells[s] = -v); + + void solveForSymbol(Symbol symbol) { + assert(_cells.containsKey(symbol)); + double coefficient = -1.0 / _cells[symbol]; + _cells.remove(symbol); + _constant *= coefficient; + _cells.forEach((s, v) => _cells[s] = v * coefficient); + } + + void solveForSymbols(Symbol lhs, Symbol rhs) { + insertSymbol(lhs, -1.0); + solveForSymbol(rhs); + } + + double coefficientForSymbol(Symbol symbol) => _elvis(_cells[symbol], 0.0); + + void substitute(Symbol symbol, Row row) { + double coefficient = _cells[symbol]; + + if (coefficient == null) { + return; + } + + _cells.remove(symbol); + insertRow(row, coefficient); + } +}
diff --git a/lib/solver.dart b/lib/solver.dart index b2a9f34..3d9c91a 100644 --- a/lib/solver.dart +++ b/lib/solver.dart
@@ -5,6 +5,14 @@ part of cassowary; class Solver { + final Map<Constraint, Tag> _constraints = new Map<Constraint, Tag>(); + final Map<Symbol, Row> _rows = new Map<Symbol, Row>(); + final Map<Variable, Symbol> _vars = new Map<Variable, Symbol>(); + final Map<Variable, EditInfo> _edits = new Map<Variable, EditInfo>(); + final List<Symbol> _infeasibleRows = new List<Symbol>(); + final Row _objective = new Row(); + final Row _artificial = new Row(); + bool addConstraint(Constraint c) { return false; } @@ -37,3 +45,16 @@ Solver operator <<(Constraint c) => this..addConstraint(c); } + +class Tag { + Symbol marker; + Symbol other; + + Tag(this.marker, this.other); +} + +class EditInfo { + Tag tag; + Constraint constraint; + double constant; +}
diff --git a/lib/utils.dart b/lib/utils.dart new file mode 100644 index 0000000..b003269 --- /dev/null +++ b/lib/utils.dart
@@ -0,0 +1,15 @@ +// Copyright (c) 2015 The Chromium Authors. 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 cassowary; + +bool _nearZero(double value) { + const double epsilon = 1.0e-8; + return value < 0.0 ? -value < epsilon : value < epsilon; +} + +// Workaround for the lack of a null coalescing operator. Uses a ternary +// instead. Sadly, due the lack of generic types on functions, we have to use +// dynamic instead. +_elvis(a, b) => a != null ? a : b;