
This reverts commit f41b3411da35929b09009e47cb52474389e42874, reversing changes made to e33d8d96212f3e337a6660f1eb1118bffc945bf5. This was a bad check-in due to my mangling uploading a new version of the branch from a different machine. This reverts https://github.com/flutter/flutter/pull/2639 and will be replaced by https://github.com/flutter/flutter/pull/2640
181 lines
4.8 KiB
Dart
181 lines
4.8 KiB
Dart
// 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 Expression extends _EquationMember {
|
|
Expression(this.terms, this.constant);
|
|
Expression.fromExpression(Expression expr)
|
|
: this.terms = new List<Term>.from(expr.terms),
|
|
this.constant = expr.constant;
|
|
|
|
final List<Term> terms;
|
|
|
|
final double constant;
|
|
|
|
@override
|
|
bool get isConstant => terms.length == 0;
|
|
|
|
@override
|
|
double get value => terms.fold(constant, (value, term) => value + term.value);
|
|
|
|
@override
|
|
Expression asExpression() => this;
|
|
|
|
Constraint _createConstraint(
|
|
_EquationMember /* rhs */ value, Relation relation) {
|
|
if (value is ConstantMember) {
|
|
return new Constraint(
|
|
new Expression(new List.from(terms), constant - value.value),
|
|
relation);
|
|
}
|
|
|
|
if (value is Param) {
|
|
var newTerms = new List<Term>.from(terms)
|
|
..add(new Term(value.variable, -1.0));
|
|
return new Constraint(new Expression(newTerms, constant), relation);
|
|
}
|
|
|
|
if (value is Term) {
|
|
var newTerms = new List<Term>.from(terms)
|
|
..add(new Term(value.variable, -value.coefficient));
|
|
return new Constraint(new Expression(newTerms, constant), relation);
|
|
}
|
|
|
|
if (value is Expression) {
|
|
var newTerms = value.terms.fold(new List<Term>.from(terms),
|
|
(list, t) => list..add(new Term(t.variable, -t.coefficient)));
|
|
return new Constraint(
|
|
new Expression(newTerms, constant - value.constant), relation);
|
|
}
|
|
|
|
assert(false);
|
|
return null;
|
|
}
|
|
|
|
@override
|
|
Constraint operator >=(_EquationMember value) =>
|
|
_createConstraint(value, Relation.greaterThanOrEqualTo);
|
|
|
|
@override
|
|
Constraint operator <=(_EquationMember value) =>
|
|
_createConstraint(value, Relation.lessThanOrEqualTo);
|
|
|
|
@override
|
|
Constraint equals(_EquationMember value) =>
|
|
_createConstraint(value, Relation.equalTo);
|
|
|
|
@override
|
|
Expression operator +(_EquationMember m) {
|
|
if (m is ConstantMember) {
|
|
return new Expression(new List.from(terms), constant + m.value);
|
|
}
|
|
|
|
if (m is Param) {
|
|
return new Expression(
|
|
new List.from(terms)..add(new Term(m.variable, 1.0)), constant);
|
|
}
|
|
|
|
if (m is Term) {
|
|
return new Expression(new List.from(terms)..add(m), constant);
|
|
}
|
|
|
|
if (m is Expression) {
|
|
return new Expression(
|
|
new List.from(terms)..addAll(m.terms), constant + m.constant);
|
|
}
|
|
|
|
assert(false);
|
|
return null;
|
|
}
|
|
|
|
@override
|
|
Expression operator -(_EquationMember m) {
|
|
if (m is ConstantMember) {
|
|
return new Expression(new List.from(terms), constant - m.value);
|
|
}
|
|
|
|
if (m is Param) {
|
|
return new Expression(
|
|
new List.from(terms)..add(new Term(m.variable, -1.0)), constant);
|
|
}
|
|
|
|
if (m is Term) {
|
|
return new Expression(new List.from(terms)
|
|
..add(new Term(m.variable, -m.coefficient)), constant);
|
|
}
|
|
|
|
if (m is Expression) {
|
|
var copiedTerms = new List<Term>.from(terms);
|
|
m.terms.forEach(
|
|
(t) => copiedTerms.add(new Term(t.variable, -t.coefficient)));
|
|
return new Expression(copiedTerms, constant - m.constant);
|
|
}
|
|
|
|
assert(false);
|
|
return null;
|
|
}
|
|
|
|
_EquationMember _applyMultiplicand(double m) {
|
|
var newTerms = terms.fold(new List<Term>(), (list, term) => list
|
|
..add(new Term(term.variable, term.coefficient * m)));
|
|
return new Expression(newTerms, constant * m);
|
|
}
|
|
|
|
_Pair<Expression, double> _findMulitplierAndMultiplicand(_EquationMember m) {
|
|
// At least on of the the two members must be constant for the resulting
|
|
// expression to be linear
|
|
|
|
if (!this.isConstant && !m.isConstant) {
|
|
return null;
|
|
}
|
|
|
|
if (this.isConstant) {
|
|
return new _Pair(m.asExpression(), this.value);
|
|
}
|
|
|
|
if (m.isConstant) {
|
|
return new _Pair(this.asExpression(), m.value);
|
|
}
|
|
|
|
assert(false);
|
|
return null;
|
|
}
|
|
|
|
_EquationMember operator *(_EquationMember m) {
|
|
_Pair<Expression, double> args = _findMulitplierAndMultiplicand(m);
|
|
|
|
if (args == null) {
|
|
throw new ParserException(
|
|
'Could not find constant multiplicand or multiplier', [this, m]);
|
|
return null;
|
|
}
|
|
|
|
return args.first._applyMultiplicand(args.second);
|
|
}
|
|
|
|
_EquationMember operator /(_EquationMember m) {
|
|
if (!m.isConstant) {
|
|
throw new ParserException(
|
|
'The divisor was not a constant expression', [this, m]);
|
|
return null;
|
|
}
|
|
|
|
return this._applyMultiplicand(1.0 / m.value);
|
|
}
|
|
|
|
String toString() {
|
|
StringBuffer buffer = new StringBuffer();
|
|
|
|
terms.forEach((t) => buffer.write('$t'));
|
|
|
|
if (constant != 0.0) {
|
|
buffer.write(constant.sign > 0.0 ? '+' : '-');
|
|
buffer.write(constant.abs());
|
|
}
|
|
|
|
return buffer.toString();
|
|
}
|
|
}
|