Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
da885781
Commit
da885781
authored
Mar 21, 2016
by
Ian Hickson
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #2806 from Hixie/cassowary
Refactor cassowary so it uses imports rather than parts.
parents
2f44055c
552896af
Changes
19
Show whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
468 additions
and
425 deletions
+468
-425
autolayout.dart
examples/layers/rendering/autolayout.dart
+1
-2
autolayout.dart
examples/layers/widgets/autolayout.dart
+1
-2
cassowary.dart
packages/cassowary/lib/cassowary.dart
+18
-17
equation_member.dart
packages/cassowary/lib/equation_member.dart
+0
-27
result.dart
packages/cassowary/lib/result.dart
+0
-29
row.dart
packages/cassowary/lib/row.dart
+0
-80
constant_member.dart
packages/cassowary/lib/src/constant_member.dart
+28
-0
constraint.dart
packages/cassowary/lib/src/constraint.dart
+12
-6
equation_member.dart
packages/cassowary/lib/src/equation_member.dart
+29
-0
expression.dart
packages/cassowary/lib/src/expression.dart
+64
-53
param.dart
packages/cassowary/lib/src/param.dart
+34
-5
parser_exception.dart
packages/cassowary/lib/src/parser_exception.dart
+8
-5
priority.dart
packages/cassowary/lib/src/priority.dart
+41
-0
result.dart
packages/cassowary/lib/src/result.dart
+40
-0
solver.dart
packages/cassowary/lib/src/solver.dart
+183
-112
term.dart
packages/cassowary/lib/src/term.dart
+9
-6
symbol.dart
packages/cassowary/lib/symbol.dart
+0
-37
utils.dart
packages/cassowary/lib/utils.dart
+0
-16
variable.dart
packages/cassowary/lib/variable.dart
+0
-28
No files found.
examples/layers/rendering/autolayout.dart
View file @
da885781
...
@@ -27,8 +27,7 @@ class _MyAutoLayoutDelegate extends AutoLayoutDelegate {
...
@@ -27,8 +27,7 @@ class _MyAutoLayoutDelegate extends AutoLayoutDelegate {
// The widths of the first and the third boxes should be equal
// The widths of the first and the third boxes should be equal
p1
.
width
.
equals
(
p3
.
width
),
p1
.
width
.
equals
(
p3
.
width
),
// The width of the second box should be twice as much as that of the first
// The width of the first box should be twice as much as that of the second
// and third
p1
.
width
.
equals
(
p2
.
width
*
al
.
cm
(
2.0
)),
p1
.
width
.
equals
(
p2
.
width
*
al
.
cm
(
2.0
)),
// The height of the three boxes should be equal to that of the container
// The height of the three boxes should be equal to that of the container
...
...
examples/layers/widgets/autolayout.dart
View file @
da885781
...
@@ -26,8 +26,7 @@ class _MyAutoLayoutDelegate extends AutoLayoutDelegate {
...
@@ -26,8 +26,7 @@ class _MyAutoLayoutDelegate extends AutoLayoutDelegate {
// The widths of the first and the third boxes should be equal
// The widths of the first and the third boxes should be equal
p1
.
width
.
equals
(
p3
.
width
),
p1
.
width
.
equals
(
p3
.
width
),
// The width of the second box should be twice as much as that of the first
// The width of the first box should be twice as much as that of the second
// and third
p1
.
width
.
equals
(
p2
.
width
*
al
.
cm
(
2.0
)),
p1
.
width
.
equals
(
p2
.
width
*
al
.
cm
(
2.0
)),
// The height of the three boxes should be equal to that of the container
// The height of the three boxes should be equal to that of the container
...
...
packages/cassowary/lib/cassowary.dart
View file @
da885781
...
@@ -3,22 +3,23 @@
...
@@ -3,22 +3,23 @@
// found in the LICENSE file.
// found in the LICENSE file.
/// An implementation of the Cassowary constraint solving algorithm in Dart.
/// An implementation of the Cassowary constraint solving algorithm in Dart.
///
/// This is used by the [RenderAutoLayout] render object in the rendering
/// library and by the [AutoLayout] widget in the widget library.
///
/// See also:
///
/// * <https://en.wikipedia.org/wiki/Cassowary_(software)>
/// * <https://constraints.cs.washington.edu/solvers/cassowary-tochi.pdf>
library
cassowary
;
library
cassowary
;
import
'dart:collection'
;
export
'src/constraint.dart'
;
import
'dart:math'
;
export
'src/expression.dart'
;
export
'src/term.dart'
;
part
'constraint.dart'
;
export
'src/equation_member.dart'
;
part
'expression.dart'
;
export
'src/constant_member.dart'
;
part
'term.dart'
;
export
'src/solver.dart'
;
part
'variable.dart'
;
export
'src/result.dart'
;
part
'equation_member.dart'
;
export
'src/parser_exception.dart'
;
part
'constant_member.dart'
;
export
'src/param.dart'
;
part
'solver.dart'
;
export
'src/priority.dart'
;
part
'symbol.dart'
;
part
'row.dart'
;
part
'utils.dart'
;
part
'result.dart'
;
part
'parser_exception.dart'
;
part
'param.dart'
;
part
'priority.dart'
;
packages/cassowary/lib/equation_member.dart
deleted
100644 → 0
View file @
2f44055c
// 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
;
abstract
class
_EquationMember
{
Expression
asExpression
();
bool
get
isConstant
;
double
get
value
;
Constraint
operator
>=(
_EquationMember
m
)
=>
asExpression
()
>=
m
;
Constraint
operator
<=(
_EquationMember
m
)
=>
asExpression
()
<=
m
;
Constraint
equals
(
_EquationMember
m
)
=>
asExpression
().
equals
(
m
);
Expression
operator
+(
_EquationMember
m
)
=>
asExpression
()
+
m
;
Expression
operator
-(
_EquationMember
m
)
=>
asExpression
()
-
m
;
Expression
operator
*(
_EquationMember
m
)
=>
asExpression
()
*
m
;
Expression
operator
/(
_EquationMember
m
)
=>
asExpression
()
/
m
;
}
packages/cassowary/lib/result.dart
deleted
100644 → 0
View file @
2f44055c
// 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
Result
{
final
String
message
;
final
bool
error
;
const
Result
(
this
.
message
,
{
bool
isError:
true
})
:
error
=
isError
;
static
final
Result
success
=
const
Result
(
"Success"
,
isError:
false
);
static
final
Result
unimplemented
=
const
Result
(
"Unimplemented"
);
static
final
Result
duplicateConstraint
=
const
Result
(
"Duplicate Constraint"
);
static
final
Result
unsatisfiableConstraint
=
const
Result
(
"Unsatisfiable Constraint"
);
static
final
Result
unknownConstraint
=
const
Result
(
"Unknown Constraint"
);
static
final
Result
duplicateEditVariable
=
const
Result
(
"Duplicate Edit Variable"
);
static
final
Result
badRequiredStrength
=
const
Result
(
"Bad Required Strength"
);
static
final
Result
unknownEditVariable
=
const
Result
(
"Unknown Edit Variable"
);
static
final
Result
internalSolverError
=
const
Result
(
"Internal Solver Error"
);
}
packages/cassowary/lib/row.dart
deleted
100644 → 0
View file @
2f44055c
// 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
;
double
constant
=
0.0
;
_Row
(
this
.
constant
)
:
this
.
cells
=
new
Map
<
_Symbol
,
double
>();
_Row
.
fromRow
(
_Row
row
)
:
this
.
cells
=
new
Map
<
_Symbol
,
double
>.
from
(
row
.
cells
),
this
.
constant
=
row
.
constant
;
double
add
(
double
value
)
=>
constant
+=
value
;
void
insertSymbol
(
_Symbol
symbol
,
[
double
coefficient
=
1.0
])
{
double
val
=
cells
[
symbol
]
??
0.0
;
if
(
_nearZero
(
val
+
coefficient
))
{
cells
.
remove
(
symbol
);
}
else
{
cells
[
symbol
]
=
val
+
coefficient
;
}
}
void
insertRow
(
_Row
other
,
[
double
coefficient
=
1.0
])
{
constant
+=
other
.
constant
*
coefficient
;
other
.
cells
.
forEach
((
_Symbol
s
,
double
v
)
=>
insertSymbol
(
s
,
v
*
coefficient
));
}
void
removeSymbol
(
_Symbol
symbol
)
{
cells
.
remove
(
symbol
);
}
void
reverseSign
()
{
constant
=
-
constant
;
cells
.
forEach
((
_Symbol
s
,
double
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
((
_Symbol
s
,
double
v
)
=>
cells
[
s
]
=
v
*
coefficient
);
}
void
solveForSymbols
(
_Symbol
lhs
,
_Symbol
rhs
)
{
insertSymbol
(
lhs
,
-
1.0
);
solveForSymbol
(
rhs
);
}
double
coefficientForSymbol
(
_Symbol
symbol
)
=>
cells
[
symbol
]
??
0.0
;
void
substitute
(
_Symbol
symbol
,
_Row
row
)
{
double
coefficient
=
cells
[
symbol
];
if
(
coefficient
==
null
)
{
return
;
}
cells
.
remove
(
symbol
);
insertRow
(
row
,
coefficient
);
}
@override
String
toString
()
{
StringBuffer
buffer
=
new
StringBuffer
();
buffer
.
write
(
constant
);
cells
.
forEach
((
_Symbol
symbol
,
double
value
)
{
buffer
.
write
(
" + "
+
value
.
toString
()
+
" * "
+
symbol
.
toString
());
});
return
buffer
.
toString
();
}
}
packages/cassowary/lib/constant_member.dart
→
packages/cassowary/lib/
src/
constant_member.dart
View file @
da885781
...
@@ -2,21 +2,27 @@
...
@@ -2,21 +2,27 @@
// Use of this source code is governed by a BSD-style license that can be
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// found in the LICENSE file.
part of
cassowary
;
import
'expression.dart'
;
import
'equation_member.dart'
;
class
ConstantMember
extends
_EquationMember
{
class
ConstantMember
extends
EquationMember
{
/// Creates a [ConstantMember] object.
///
/// The [cm] convenience method may be a more convenient way to create a
/// [ConstantMember] object.
ConstantMember
(
this
.
value
);
ConstantMember
(
this
.
value
);
@override
@override
final
double
value
;
Expression
asExpression
()
=>
new
Expression
([],
this
.
value
)
;
@override
@override
bool
get
isConstant
=>
tr
ue
;
final
double
val
ue
;
@override
@override
Expression
asExpression
()
=>
new
Expression
([],
this
.
value
)
;
bool
get
isConstant
=>
true
;
}
}
ConstantMember
cm
(
double
value
)
{
/// Creates a [ConstantMember].
return
new
ConstantMember
(
value
);
///
}
/// This is a convenience method to make cassowary expressions less verbose.
ConstantMember
cm
(
double
value
)
=>
new
ConstantMember
(
value
);
packages/cassowary/lib/constraint.dart
→
packages/cassowary/lib/
src/
constraint.dart
View file @
da885781
...
@@ -2,16 +2,23 @@
...
@@ -2,16 +2,23 @@
// Use of this source code is governed by a BSD-style license that can be
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// found in the LICENSE file.
part of
cassowary
;
import
'priority.dart'
;
import
'expression.dart'
;
enum
Relation
{
equalTo
,
lessThanOrEqualTo
,
greaterThanOrEqualTo
,
}
enum
Relation
{
equalTo
,
lessThanOrEqualTo
,
greaterThanOrEqualTo
,
}
class
Constraint
{
class
Constraint
{
Constraint
(
this
.
expression
,
this
.
relation
);
final
Relation
relation
;
final
Relation
relation
;
final
Expression
expression
;
final
Expression
expression
;
double
priority
=
Priority
.
required
;
Constraint
(
this
.
expression
,
this
.
relation
)
;
double
priority
=
Priority
.
required
;
Constraint
operator
|(
double
p
)
=>
this
..
priority
=
p
;
Constraint
operator
|(
double
p
)
=>
this
..
priority
=
p
;
...
@@ -34,9 +41,8 @@ class Constraint {
...
@@ -34,9 +41,8 @@ class Constraint {
buffer
.
write
(
' | priority =
$priority
'
);
buffer
.
write
(
' | priority =
$priority
'
);
if
(
priority
==
Priority
.
required
)
{
if
(
priority
==
Priority
.
required
)
buffer
.
write
(
' (required)'
);
buffer
.
write
(
' (required)'
);
}
return
buffer
.
toString
();
return
buffer
.
toString
();
}
}
...
...
packages/cassowary/lib/src/equation_member.dart
0 → 100644
View file @
da885781
// 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.
import
'expression.dart'
;
import
'constraint.dart'
;
/// Base class for the various parts of cassowary equations.
abstract
class
EquationMember
{
Expression
asExpression
();
bool
get
isConstant
;
double
get
value
;
Constraint
operator
>=(
EquationMember
m
)
=>
asExpression
()
>=
m
;
Constraint
operator
<=(
EquationMember
m
)
=>
asExpression
()
<=
m
;
Constraint
equals
(
EquationMember
m
)
=>
asExpression
().
equals
(
m
);
Expression
operator
+(
EquationMember
m
)
=>
asExpression
()
+
m
;
Expression
operator
-(
EquationMember
m
)
=>
asExpression
()
-
m
;
Expression
operator
*(
EquationMember
m
)
=>
asExpression
()
*
m
;
Expression
operator
/(
EquationMember
m
)
=>
asExpression
()
/
m
;
}
packages/cassowary/lib/expression.dart
→
packages/cassowary/lib/
src/
expression.dart
View file @
da885781
...
@@ -2,10 +2,22 @@
...
@@ -2,10 +2,22 @@
// Use of this source code is governed by a BSD-style license that can be
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// found in the LICENSE file.
part of
cassowary
;
import
'constant_member.dart'
;
import
'constraint.dart'
;
import
'equation_member.dart'
;
import
'param.dart'
;
import
'parser_exception.dart'
;
import
'term.dart'
;
class
_Multiplication
{
const
_Multiplication
(
this
.
multiplier
,
this
.
multiplicand
);
final
Expression
multiplier
;
final
double
multiplicand
;
}
class
Expression
extends
_
EquationMember
{
class
Expression
extends
EquationMember
{
Expression
(
this
.
terms
,
this
.
constant
);
Expression
(
this
.
terms
,
this
.
constant
);
Expression
.
fromExpression
(
Expression
expr
)
Expression
.
fromExpression
(
Expression
expr
)
:
this
.
terms
=
new
List
<
Term
>.
from
(
expr
.
terms
),
:
this
.
terms
=
new
List
<
Term
>.
from
(
expr
.
terms
),
this
.
constant
=
expr
.
constant
;
this
.
constant
=
expr
.
constant
;
...
@@ -14,6 +26,9 @@ class Expression extends _EquationMember {
...
@@ -14,6 +26,9 @@ class Expression extends _EquationMember {
final
double
constant
;
final
double
constant
;
@override
Expression
asExpression
()
=>
this
;
@override
@override
bool
get
isConstant
=>
terms
.
length
==
0
;
bool
get
isConstant
=>
terms
.
length
==
0
;
...
@@ -21,9 +36,21 @@ class Expression extends _EquationMember {
...
@@ -21,9 +36,21 @@ class Expression extends _EquationMember {
double
get
value
=>
terms
.
fold
(
constant
,
(
double
value
,
Term
term
)
=>
value
+
term
.
value
);
double
get
value
=>
terms
.
fold
(
constant
,
(
double
value
,
Term
term
)
=>
value
+
term
.
value
);
@override
@override
Expression
asExpression
()
=>
this
;
Constraint
operator
>=(
EquationMember
value
)
{
return
_createConstraint
(
value
,
Relation
.
greaterThanOrEqualTo
);
}
@override
Constraint
operator
<=(
EquationMember
value
)
{
return
_createConstraint
(
value
,
Relation
.
lessThanOrEqualTo
);
}
Constraint
_createConstraint
(
_EquationMember
/* rhs */
value
,
Relation
relation
)
{
@override
Constraint
equals
(
EquationMember
value
)
{
return
_createConstraint
(
value
,
Relation
.
equalTo
);
}
Constraint
_createConstraint
(
EquationMember
/* rhs */
value
,
Relation
relation
)
{
if
(
value
is
ConstantMember
)
{
if
(
value
is
ConstantMember
)
{
return
new
Constraint
(
return
new
Constraint
(
new
Expression
(
new
List
<
Term
>.
from
(
terms
),
constant
-
value
.
value
),
new
Expression
(
new
List
<
Term
>.
from
(
terms
),
constant
-
value
.
value
),
...
@@ -60,22 +87,7 @@ class Expression extends _EquationMember {
...
@@ -60,22 +87,7 @@ class Expression extends _EquationMember {
}
}
@override
@override
Constraint
operator
>=(
_EquationMember
value
)
{
Expression
operator
+(
EquationMember
m
)
{
return
_createConstraint
(
value
,
Relation
.
greaterThanOrEqualTo
);
}
@override
Constraint
operator
<=(
_EquationMember
value
)
{
return
_createConstraint
(
value
,
Relation
.
lessThanOrEqualTo
);
}
@override
Constraint
equals
(
_EquationMember
value
)
{
return
_createConstraint
(
value
,
Relation
.
equalTo
);
}
@override
Expression
operator
+(
_EquationMember
m
)
{
if
(
m
is
ConstantMember
)
if
(
m
is
ConstantMember
)
return
new
Expression
(
new
List
<
Term
>.
from
(
terms
),
constant
+
m
.
value
);
return
new
Expression
(
new
List
<
Term
>.
from
(
terms
),
constant
+
m
.
value
);
...
@@ -100,7 +112,7 @@ class Expression extends _EquationMember {
...
@@ -100,7 +112,7 @@ class Expression extends _EquationMember {
}
}
@override
@override
Expression
operator
-(
_
EquationMember
m
)
{
Expression
operator
-(
EquationMember
m
)
{
if
(
m
is
ConstantMember
)
if
(
m
is
ConstantMember
)
return
new
Expression
(
new
List
<
Term
>.
from
(
terms
),
constant
-
m
.
value
);
return
new
Expression
(
new
List
<
Term
>.
from
(
terms
),
constant
-
m
.
value
);
...
@@ -126,49 +138,22 @@ class Expression extends _EquationMember {
...
@@ -126,49 +138,22 @@ class Expression extends _EquationMember {
return
null
;
return
null
;
}
}
_EquationMember
_applyMultiplicand
(
double
m
)
{
List
<
Term
>
newTerms
=
terms
.
fold
(
new
List
<
Term
>(),
(
List
<
Term
>
list
,
Term
term
)
{
return
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
<
Expression
,
double
>(
m
.
asExpression
(),
this
.
value
);
if
(
m
.
isConstant
)
return
new
_Pair
<
Expression
,
double
>(
this
.
asExpression
(),
m
.
value
);
assert
(
false
);
return
null
;
}
@override
@override
_EquationMember
operator
*(
_
EquationMember
m
)
{
EquationMember
operator
*(
EquationMember
m
)
{
_
Pair
<
Expression
,
double
>
args
=
_findMulitplierAndMultiplicand
(
m
);
_
Multiplication
args
=
_findMulitplierAndMultiplicand
(
m
);
if
(
args
==
null
)
{
if
(
args
==
null
)
{
throw
new
ParserException
(
throw
new
ParserException
(
'Could not find constant multiplicand or multiplier'
,
'Could not find constant multiplicand or multiplier'
,
<
_
EquationMember
>[
this
,
m
]
<
EquationMember
>[
this
,
m
]
);
);
}
}
return
args
.
first
.
_applyMultiplicand
(
args
.
seco
nd
);
return
args
.
multiplier
.
_applyMultiplicand
(
args
.
multiplica
nd
);
}
}
@override
@override
_EquationMember
operator
/(
_
EquationMember
m
)
{
EquationMember
operator
/(
EquationMember
m
)
{
if
(!
m
.
isConstant
)
{
if
(!
m
.
isConstant
)
{
throw
new
ParserException
(
throw
new
ParserException
(
'The divisor was not a constant expression'
,
[
this
,
m
]);
'The divisor was not a constant expression'
,
[
this
,
m
]);
...
@@ -178,6 +163,32 @@ class Expression extends _EquationMember {
...
@@ -178,6 +163,32 @@ class Expression extends _EquationMember {
return
this
.
_applyMultiplicand
(
1.0
/
m
.
value
);
return
this
.
_applyMultiplicand
(
1.0
/
m
.
value
);
}
}
_Multiplication
_findMulitplierAndMultiplicand
(
EquationMember
m
)
{
// At least one 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
_Multiplication
(
m
.
asExpression
(),
this
.
value
);
if
(
m
.
isConstant
)
return
new
_Multiplication
(
this
.
asExpression
(),
m
.
value
);
assert
(
false
);
return
null
;
}
EquationMember
_applyMultiplicand
(
double
m
)
{
List
<
Term
>
newTerms
=
terms
.
fold
(
new
List
<
Term
>(),
(
List
<
Term
>
list
,
Term
term
)
{
return
list
..
add
(
new
Term
(
term
.
variable
,
term
.
coefficient
*
m
));
}
);
return
new
Expression
(
newTerms
,
constant
*
m
);
}
@override
@override
String
toString
()
{
String
toString
()
{
StringBuffer
buffer
=
new
StringBuffer
();
StringBuffer
buffer
=
new
StringBuffer
();
...
...
packages/cassowary/lib/param.dart
→
packages/cassowary/lib/
src/
param.dart
View file @
da885781
...
@@ -2,12 +2,41 @@
...
@@ -2,12 +2,41 @@
// Use of this source code is governed by a BSD-style license that can be
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// found in the LICENSE file.
part of
cassowary
;
import
'equation_member.dart'
;
import
'expression.dart'
;
import
'term.dart'
;
class
Param
extends
_EquationMember
{
class
Variable
{
static
int
_total
=
0
;
Variable
(
this
.
value
)
:
_tick
=
_total
++;
final
int
_tick
;
double
value
;
String
name
;
Param
get
owner
=>
_owner
;
Param
_owner
;
bool
applyUpdate
(
double
updated
)
{
bool
res
=
updated
!=
value
;
value
=
updated
;
return
res
;
}
String
get
debugName
=>
name
??
'variable
$_tick
'
;
@override
String
toString
()
=>
debugName
;
}
class
Param
extends
EquationMember
{
Param
([
double
value
=
0.0
])
:
variable
=
new
Variable
(
value
)
{
Param
([
double
value
=
0.0
])
:
variable
=
new
Variable
(
value
)
{
variable
.
_owner
=
this
;
variable
.
_owner
=
this
;
}
}
Param
.
withContext
(
dynamic
context
,
[
double
value
=
0.0
])
Param
.
withContext
(
dynamic
context
,
[
double
value
=
0.0
])
:
variable
=
new
Variable
(
value
),
:
variable
=
new
Variable
(
value
),
context
=
context
{
context
=
context
{
...
@@ -18,6 +47,9 @@ class Param extends _EquationMember {
...
@@ -18,6 +47,9 @@ class Param extends _EquationMember {
dynamic
context
;
dynamic
context
;
@override
Expression
asExpression
()
=>
new
Expression
(<
Term
>[
new
Term
(
variable
,
1.0
)],
0.0
);
@override
@override
bool
get
isConstant
=>
false
;
bool
get
isConstant
=>
false
;
...
@@ -26,7 +58,4 @@ class Param extends _EquationMember {
...
@@ -26,7 +58,4 @@ class Param extends _EquationMember {
String
get
name
=>
variable
.
name
;
String
get
name
=>
variable
.
name
;
void
set
name
(
String
name
)
{
variable
.
name
=
name
;
}
void
set
name
(
String
name
)
{
variable
.
name
=
name
;
}
@override
Expression
asExpression
()
=>
new
Expression
(<
Term
>[
new
Term
(
variable
,
1.0
)],
0.0
);
}
}
packages/cassowary/lib/parser_exception.dart
→
packages/cassowary/lib/
src/
parser_exception.dart
View file @
da885781
...
@@ -2,16 +2,19 @@
...
@@ -2,16 +2,19 @@
// Use of this source code is governed by a BSD-style license that can be
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// found in the LICENSE file.
part of
cassowary
;
import
'equation_member.dart'
;
class
ParserException
implements
Exception
{
class
ParserException
implements
Exception
{
final
String
message
;
List
<
_EquationMember
>
members
;
ParserException
(
this
.
message
,
this
.
members
);
ParserException
(
this
.
message
,
this
.
members
);
final
String
message
;
List
<
EquationMember
>
members
;
@override
@override
String
toString
()
{
String
toString
()
{
if
(
message
==
null
)
return
"Error while parsing constraint or expression"
;
if
(
message
==
null
)
return
"Error: '
$message
' while trying to parse constraint or expression"
;
return
'Error while parsing constraint or expression'
;
return
'Error: "
$message
" while trying to parse constraint or expression'
;
}
}
}
}
packages/cassowary/lib/priority.dart
→
packages/cassowary/lib/
src/
priority.dart
View file @
da885781
...
@@ -2,14 +2,35 @@
...
@@ -2,14 +2,35 @@
// Use of this source code is governed by a BSD-style license that can be
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// found in the LICENSE file.
part of
cassowary
;
import
'dart:math'
;
/// Utility functions for managing cassowary priorities.
///
/// Priorities in cassowary expressions are internally expressed as a number
/// between 0 and 1,000,000,000. These numbers can be created by using the
/// [Priority.create] static method.
class
Priority
{
class
Priority
{
/// The priority level that, by convention, is the highest allowed priority level (1,000,000,000).
static
final
double
required
=
create
(
1
e3
,
1
e3
,
1
e3
);
static
final
double
required
=
create
(
1
e3
,
1
e3
,
1
e3
);
/// A priority level that is below the [required] level but still near it (1,000,000).
static
final
double
strong
=
create
(
1.0
,
0.0
,
0.0
);
static
final
double
strong
=
create
(
1.0
,
0.0
,
0.0
);
/// A priority level logarithmically in the middle of [strong] and [weak] (1,000).
static
final
double
medium
=
create
(
0.0
,
1.0
,
0.0
);
static
final
double
medium
=
create
(
0.0
,
1.0
,
0.0
);
/// A priority level that, by convention, is the lowest allowed priority level (1).
static
final
double
weak
=
create
(
0.0
,
0.0
,
1.0
);
static
final
double
weak
=
create
(
0.0
,
0.0
,
1.0
);
/// Computes a priority level by combining three numbers in the range 0..1000.
///
/// The first number is a multiple of [strong].
///
/// The second number is a multiple of [medium].
///
/// The third number is a multiple of [weak].
///
/// By convention, at least one of these numbers should be equal to or greater than 1.
static
double
create
(
double
a
,
double
b
,
double
c
)
{
static
double
create
(
double
a
,
double
b
,
double
c
)
{
double
result
=
0.0
;
double
result
=
0.0
;
result
+=
max
(
0.0
,
min
(
1
e3
,
a
))
*
1
e6
;
result
+=
max
(
0.0
,
min
(
1
e3
,
a
))
*
1
e6
;
...
@@ -17,8 +38,4 @@ class Priority {
...
@@ -17,8 +38,4 @@ class Priority {
result
+=
max
(
0.0
,
min
(
1
e3
,
c
));
result
+=
max
(
0.0
,
min
(
1
e3
,
c
));
return
result
;
return
result
;
}
}
static
double
clamp
(
double
value
)
{
return
max
(
0.0
,
min
(
required
,
value
));
}
}
}
packages/cassowary/lib/src/result.dart
0 → 100644
View file @
da885781
// 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.
import
'solver.dart'
;
/// Return values used by methods on the cassowary [Solver].
class
Result
{
const
Result
.
_
(
this
.
message
,
{
bool
isError:
true
})
:
error
=
isError
;
/// The human-readable string associated with this result.
///
/// This message is typically brief and intended for developers to help debug
/// erroneous expressions.
final
String
message
;
/// Whether this [Result] represents an error (true) or not (false).
final
bool
error
;
static
const
Result
success
=
const
Result
.
_
(
'Success'
,
isError:
false
);
static
const
Result
duplicateConstraint
=
const
Result
.
_
(
'Duplicate constraint'
);
static
const
Result
unsatisfiableConstraint
=
const
Result
.
_
(
'Unsatisfiable constraint'
);
static
const
Result
unknownConstraint
=
const
Result
.
_
(
'Unknown constraint'
);
static
const
Result
duplicateEditVariable
=
const
Result
.
_
(
'Duplicate edit variable'
);
static
const
Result
badRequiredStrength
=
const
Result
.
_
(
'Bad required strength'
);
static
const
Result
unknownEditVariable
=
const
Result
.
_
(
'Unknown edit variable'
);
}
packages/cassowary/lib/solver.dart
→
packages/cassowary/lib/s
rc/s
olver.dart
View file @
da885781
...
@@ -2,7 +2,148 @@
...
@@ -2,7 +2,148 @@
// Use of this source code is governed by a BSD-style license that can be
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// found in the LICENSE file.
part of
cassowary
;
import
'dart:collection'
;
import
'constraint.dart'
;
import
'expression.dart'
;
import
'priority.dart'
;
import
'result.dart'
;
import
'param.dart'
;
import
'term.dart'
;
enum
_SymbolType
{
invalid
,
external
,
slack
,
error
,
dummy
,
}
class
_Symbol
{
const
_Symbol
(
this
.
type
,
this
.
tick
);
final
_SymbolType
type
;
final
int
tick
;
@override
String
toString
()
{
String
typeString
=
'unknown'
;
switch
(
type
)
{
case
_SymbolType
.
invalid
:
typeString
=
'i'
;
break
;
case
_SymbolType
.
external
:
typeString
=
'v'
;
break
;
case
_SymbolType
.
slack
:
typeString
=
's'
;
break
;
case
_SymbolType
.
error
:
typeString
=
'e'
;
break
;
case
_SymbolType
.
dummy
:
typeString
=
'd'
;
break
;
}
return
'
$typeString$tick
'
;
}
}
class
_Tag
{
_Tag
(
this
.
marker
,
this
.
other
);
_Tag
.
fromTag
(
_Tag
tag
)
:
this
.
marker
=
tag
.
marker
,
this
.
other
=
tag
.
other
;
_Symbol
marker
;
_Symbol
other
;
}
class
_EditInfo
{
_Tag
tag
;
Constraint
constraint
;
double
constant
;
}
bool
_isValidNonRequiredPriority
(
double
priority
)
{
return
(
priority
>=
0.0
&&
priority
<
Priority
.
required
);
}
typedef
Result
_SolverBulkUpdate
(
dynamic
item
);
bool
_nearZero
(
double
value
)
{
const
double
epsilon
=
1.0e-8
;
return
value
<
0.0
?
-
value
<
epsilon
:
value
<
epsilon
;
}
class
_Row
{
_Row
(
this
.
constant
)
:
this
.
cells
=
new
Map
<
_Symbol
,
double
>();
_Row
.
fromRow
(
_Row
row
)
:
this
.
cells
=
new
Map
<
_Symbol
,
double
>.
from
(
row
.
cells
),
this
.
constant
=
row
.
constant
;
final
Map
<
_Symbol
,
double
>
cells
;
double
constant
=
0.0
;
double
add
(
double
value
)
=>
constant
+=
value
;
void
insertSymbol
(
_Symbol
symbol
,
[
double
coefficient
=
1.0
])
{
double
val
=
cells
[
symbol
]
??
0.0
;
if
(
_nearZero
(
val
+
coefficient
))
{
cells
.
remove
(
symbol
);
}
else
{
cells
[
symbol
]
=
val
+
coefficient
;
}
}
void
insertRow
(
_Row
other
,
[
double
coefficient
=
1.0
])
{
constant
+=
other
.
constant
*
coefficient
;
other
.
cells
.
forEach
((
_Symbol
s
,
double
v
)
=>
insertSymbol
(
s
,
v
*
coefficient
));
}
void
removeSymbol
(
_Symbol
symbol
)
{
cells
.
remove
(
symbol
);
}
void
reverseSign
()
{
constant
=
-
constant
;
cells
.
forEach
((
_Symbol
s
,
double
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
((
_Symbol
s
,
double
v
)
=>
cells
[
s
]
=
v
*
coefficient
);
}
void
solveForSymbols
(
_Symbol
lhs
,
_Symbol
rhs
)
{
insertSymbol
(
lhs
,
-
1.0
);
solveForSymbol
(
rhs
);
}
double
coefficientForSymbol
(
_Symbol
symbol
)
=>
cells
[
symbol
]
??
0.0
;
void
substitute
(
_Symbol
symbol
,
_Row
row
)
{
double
coefficient
=
cells
[
symbol
];
if
(
coefficient
==
null
)
{
return
;
}
cells
.
remove
(
symbol
);
insertRow
(
row
,
coefficient
);
}
@override
String
toString
()
{
StringBuffer
buffer
=
new
StringBuffer
();
buffer
.
write
(
constant
);
cells
.
forEach
((
_Symbol
symbol
,
double
value
)
{
buffer
.
write
(
" + "
+
value
.
toString
()
+
" * "
+
symbol
.
toString
());
});
return
buffer
.
toString
();
}
}
class
Solver
{
class
Solver
{
final
Map
<
Constraint
,
_Tag
>
_constraints
=
new
Map
<
Constraint
,
_Tag
>();
final
Map
<
Constraint
,
_Tag
>
_constraints
=
new
Map
<
Constraint
,
_Tag
>();
...
@@ -25,9 +166,8 @@ class Solver {
...
@@ -25,9 +166,8 @@ class Solver {
}
}
Result
addConstraint
(
Constraint
constraint
)
{
Result
addConstraint
(
Constraint
constraint
)
{
if
(
_constraints
.
containsKey
(
constraint
))
{
if
(
_constraints
.
containsKey
(
constraint
))
return
Result
.
duplicateConstraint
;
return
Result
.
duplicateConstraint
;
}
_Tag
tag
=
new
_Tag
(
new
_Symbol
(
_SymbolType
.
invalid
,
0
),
_Tag
tag
=
new
_Tag
(
new
_Symbol
(
_SymbolType
.
invalid
,
0
),
new
_Symbol
(
_SymbolType
.
invalid
,
0
));
new
_Symbol
(
_SymbolType
.
invalid
,
0
));
...
@@ -45,9 +185,8 @@ class Solver {
...
@@ -45,9 +185,8 @@ class Solver {
}
}
if
(
subject
.
type
==
_SymbolType
.
invalid
)
{
if
(
subject
.
type
==
_SymbolType
.
invalid
)
{
if
(!
_addWithArtificialVariableOnRow
(
row
))
{
if
(!
_addWithArtificialVariableOnRow
(
row
))
return
Result
.
unsatisfiableConstraint
;
return
Result
.
unsatisfiableConstraint
;
}
}
else
{
}
else
{
row
.
solveForSymbol
(
subject
);
row
.
solveForSymbol
(
subject
);
_substitute
(
subject
,
row
);
_substitute
(
subject
,
row
);
...
@@ -68,9 +207,8 @@ class Solver {
...
@@ -68,9 +207,8 @@ class Solver {
Result
removeConstraint
(
Constraint
constraint
)
{
Result
removeConstraint
(
Constraint
constraint
)
{
_Tag
tag
=
_constraints
[
constraint
];
_Tag
tag
=
_constraints
[
constraint
];
if
(
tag
==
null
)
{
if
(
tag
==
null
)
return
Result
.
unknownConstraint
;
return
Result
.
unknownConstraint
;
}
tag
=
new
_Tag
.
fromTag
(
tag
);
tag
=
new
_Tag
.
fromTag
(
tag
);
_constraints
.
remove
(
constraint
);
_constraints
.
remove
(
constraint
);
...
@@ -81,16 +219,11 @@ class Solver {
...
@@ -81,16 +219,11 @@ class Solver {
if
(
row
!=
null
)
{
if
(
row
!=
null
)
{
_rows
.
remove
(
tag
.
marker
);
_rows
.
remove
(
tag
.
marker
);
}
else
{
}
else
{
_Pair
<
_Symbol
,
_Row
>
rowPair
=
_leavingRowPairForMarkerSymbol
(
tag
.
marker
);
_Symbol
leaving
=
_leavingSymbolForMarkerSymbol
(
tag
.
marker
);
assert
(
leaving
!=
null
);
if
(
rowPair
==
null
)
{
return
Result
.
internalSolverError
;
}
_Symbol
leaving
=
rowPair
.
first
;
row
=
_rows
.
remove
(
leaving
);
row
=
rowPair
.
second
;
assert
(
row
!=
null
);
_Row
removed
=
_rows
.
remove
(
rowPair
.
first
);
assert
(
removed
!=
null
);
row
.
solveForSymbols
(
leaving
,
tag
.
marker
);
row
.
solveForSymbols
(
leaving
,
tag
.
marker
);
_substitute
(
tag
.
marker
,
row
);
_substitute
(
tag
.
marker
,
row
);
}
}
...
@@ -110,21 +243,19 @@ class Solver {
...
@@ -110,21 +243,19 @@ class Solver {
}
}
Result
addEditVariable
(
Variable
variable
,
double
priority
)
{
Result
addEditVariable
(
Variable
variable
,
double
priority
)
{
if
(
_edits
.
containsKey
(
variable
))
{
if
(
_edits
.
containsKey
(
variable
))
return
Result
.
duplicateEditVariable
;
return
Result
.
duplicateEditVariable
;
}
if
(!
_isValidNonRequiredPriority
(
priority
))
{
if
(!
_isValidNonRequiredPriority
(
priority
))
return
Result
.
badRequiredStrength
;
return
Result
.
badRequiredStrength
;
}
Constraint
constraint
=
new
Constraint
(
Constraint
constraint
=
new
Constraint
(
new
Expression
([
new
Term
(
variable
,
1.0
)],
0.0
),
Relation
.
equalTo
);
new
Expression
([
new
Term
(
variable
,
1.0
)],
0.0
),
Relation
.
equalTo
);
constraint
.
priority
=
priority
;
constraint
.
priority
=
priority
;
if
(
addConstraint
(
constraint
)
!=
Result
.
success
)
{
assert
(
addConstraint
(
constraint
)
==
Result
.
success
);
return
Result
.
internalSolverError
;
}
_EditInfo
info
=
new
_EditInfo
();
_EditInfo
info
=
new
_EditInfo
();
info
.
tag
=
_constraints
[
constraint
];
info
.
tag
=
_constraints
[
constraint
];
...
@@ -149,8 +280,7 @@ class Solver {
...
@@ -149,8 +280,7 @@ class Solver {
if
(
info
==
null
)
if
(
info
==
null
)
return
Result
.
unknownEditVariable
;
return
Result
.
unknownEditVariable
;
if
(
removeConstraint
(
info
.
constraint
)
!=
Result
.
success
)
assert
(
removeConstraint
(
info
.
constraint
)
==
Result
.
success
);
return
Result
.
internalSolverError
;
_edits
.
remove
(
variable
);
_edits
.
remove
(
variable
);
return
Result
.
success
;
return
Result
.
success
;
...
@@ -161,9 +291,8 @@ class Solver {
...
@@ -161,9 +291,8 @@ class Solver {
}
}
Result
suggestValueForVariable
(
Variable
variable
,
double
value
)
{
Result
suggestValueForVariable
(
Variable
variable
,
double
value
)
{
if
(!
_edits
.
containsKey
(
variable
))
{
if
(!
_edits
.
containsKey
(
variable
))
return
Result
.
unknownEditVariable
;
return
Result
.
unknownEditVariable
;
}
_suggestValueForEditInfoWithoutDualOptimization
(
_edits
[
variable
],
value
);
_suggestValueForEditInfoWithoutDualOptimization
(
_edits
[
variable
],
value
);
...
@@ -179,8 +308,8 @@ class Solver {
...
@@ -179,8 +308,8 @@ class Solver {
double
updatedValue
=
row
==
null
?
0.0
:
row
.
constant
;
double
updatedValue
=
row
==
null
?
0.0
:
row
.
constant
;
if
(
variable
.
_applyUpdate
(
updatedValue
)
&&
variable
.
_
owner
!=
null
)
{
if
(
variable
.
applyUpdate
(
updatedValue
)
&&
variable
.
owner
!=
null
)
{
dynamic
context
=
variable
.
_
owner
.
context
;
dynamic
context
=
variable
.
owner
.
context
;
if
(
context
!=
null
)
if
(
context
!=
null
)
updates
.
add
(
context
);
updates
.
add
(
context
);
}
}
...
@@ -293,34 +422,30 @@ class Solver {
...
@@ -293,34 +422,30 @@ class Solver {
_Symbol
_chooseSubjectForRow
(
_Row
row
,
_Tag
tag
)
{
_Symbol
_chooseSubjectForRow
(
_Row
row
,
_Tag
tag
)
{
for
(
_Symbol
symbol
in
row
.
cells
.
keys
)
{
for
(
_Symbol
symbol
in
row
.
cells
.
keys
)
{
if
(
symbol
.
type
==
_SymbolType
.
external
)
{
if
(
symbol
.
type
==
_SymbolType
.
external
)
return
symbol
;
return
symbol
;
}
}
}
if
(
tag
.
marker
.
type
==
_SymbolType
.
slack
||
if
(
tag
.
marker
.
type
==
_SymbolType
.
slack
||
tag
.
marker
.
type
==
_SymbolType
.
error
)
{
tag
.
marker
.
type
==
_SymbolType
.
error
)
{
if
(
row
.
coefficientForSymbol
(
tag
.
marker
)
<
0.0
)
{
if
(
row
.
coefficientForSymbol
(
tag
.
marker
)
<
0.0
)
return
tag
.
marker
;
return
tag
.
marker
;
}
}
}
if
(
tag
.
other
.
type
==
_SymbolType
.
slack
||
if
(
tag
.
other
.
type
==
_SymbolType
.
slack
||
tag
.
other
.
type
==
_SymbolType
.
error
)
{
tag
.
other
.
type
==
_SymbolType
.
error
)
{
if
(
row
.
coefficientForSymbol
(
tag
.
other
)
<
0.0
)
{
if
(
row
.
coefficientForSymbol
(
tag
.
other
)
<
0.0
)
return
tag
.
other
;
return
tag
.
other
;
}
}
}
return
new
_Symbol
(
_SymbolType
.
invalid
,
0
);
return
new
_Symbol
(
_SymbolType
.
invalid
,
0
);
}
}
bool
_allDummiesInRow
(
_Row
row
)
{
bool
_allDummiesInRow
(
_Row
row
)
{
for
(
_Symbol
symbol
in
row
.
cells
.
keys
)
{
for
(
_Symbol
symbol
in
row
.
cells
.
keys
)
{
if
(
symbol
.
type
!=
_SymbolType
.
dummy
)
{
if
(
symbol
.
type
!=
_SymbolType
.
dummy
)
return
false
;
return
false
;
}
}
}
return
true
;
return
true
;
}
}
...
@@ -342,23 +467,20 @@ class Solver {
...
@@ -342,23 +467,20 @@ class Solver {
_Row
foundRow
=
_rows
[
artificial
];
_Row
foundRow
=
_rows
[
artificial
];
if
(
foundRow
!=
null
)
{
if
(
foundRow
!=
null
)
{
_rows
.
remove
(
artificial
);
_rows
.
remove
(
artificial
);
if
(
foundRow
.
cells
.
isEmpty
)
{
if
(
foundRow
.
cells
.
isEmpty
)
return
success
;
return
success
;
}
_Symbol
entering
=
_anyPivotableSymbol
(
foundRow
);
_Symbol
entering
=
_anyPivotableSymbol
(
foundRow
);
if
(
entering
.
type
==
_SymbolType
.
invalid
)
{
if
(
entering
.
type
==
_SymbolType
.
invalid
)
return
false
;
return
false
;
}
foundRow
.
solveForSymbols
(
artificial
,
entering
);
foundRow
.
solveForSymbols
(
artificial
,
entering
);
_substitute
(
entering
,
foundRow
);
_substitute
(
entering
,
foundRow
);
_rows
[
entering
]
=
foundRow
;
_rows
[
entering
]
=
foundRow
;
}
}
for
(
_Row
row
in
_rows
.
values
)
{
for
(
_Row
row
in
_rows
.
values
)
row
.
removeSymbol
(
artificial
);
row
.
removeSymbol
(
artificial
);
}
_objective
.
removeSymbol
(
artificial
);
_objective
.
removeSymbol
(
artificial
);
return
success
;
return
success
;
}
}
...
@@ -366,19 +488,13 @@ class Solver {
...
@@ -366,19 +488,13 @@ class Solver {
Result
_optimizeObjectiveRow
(
_Row
objective
)
{
Result
_optimizeObjectiveRow
(
_Row
objective
)
{
while
(
true
)
{
while
(
true
)
{
_Symbol
entering
=
_enteringSymbolForObjectiveRow
(
objective
);
_Symbol
entering
=
_enteringSymbolForObjectiveRow
(
objective
);
if
(
entering
.
type
==
_SymbolType
.
invalid
)
{
if
(
entering
.
type
==
_SymbolType
.
invalid
)
return
Result
.
success
;
return
Result
.
success
;
}
_Pair
<
_Symbol
,
_Row
>
leavingPair
=
_leavingRowForEnteringSymbol
(
entering
);
_Symbol
leaving
=
_leavingSymbolForEnteringSymbol
(
entering
);
assert
(
leaving
!=
null
);
if
(
leavingPair
==
null
)
{
return
Result
.
internalSolverError
;
}
_Symbol
leaving
=
leavingPair
.
first
;
_Row
row
=
_rows
.
remove
(
leaving
);
_Row
row
=
leavingPair
.
second
;
_rows
.
remove
(
leavingPair
.
first
);
row
.
solveForSymbols
(
leaving
,
entering
);
row
.
solveForSymbols
(
leaving
,
entering
);
_substitute
(
entering
,
row
);
_substitute
(
entering
,
row
);
_rows
[
entering
]
=
row
;
_rows
[
entering
]
=
row
;
...
@@ -389,38 +505,28 @@ class Solver {
...
@@ -389,38 +505,28 @@ class Solver {
Map
<
_Symbol
,
double
>
cells
=
objective
.
cells
;
Map
<
_Symbol
,
double
>
cells
=
objective
.
cells
;
for
(
_Symbol
symbol
in
cells
.
keys
)
{
for
(
_Symbol
symbol
in
cells
.
keys
)
{
if
(
symbol
.
type
!=
_SymbolType
.
dummy
&&
cells
[
symbol
]
<
0.0
)
{
if
(
symbol
.
type
!=
_SymbolType
.
dummy
&&
cells
[
symbol
]
<
0.0
)
return
symbol
;
return
symbol
;
}
}
}
return
new
_Symbol
(
_SymbolType
.
invalid
,
0
);
return
new
_Symbol
(
_SymbolType
.
invalid
,
0
);
}
}
_
Pair
<
_Symbol
,
_Row
>
_leavingRow
ForEnteringSymbol
(
_Symbol
entering
)
{
_
Symbol
_leavingSymbol
ForEnteringSymbol
(
_Symbol
entering
)
{
double
ratio
=
double
.
MAX_FINITE
;
double
ratio
=
double
.
MAX_FINITE
;
_Pair
<
_Symbol
,
_Row
>
result
=
new
_Pair
<
_Symbol
,
_Row
>(
null
,
null
);
_Symbol
result
;
_rows
.
forEach
((
_Symbol
symbol
,
_Row
row
)
{
_rows
.
forEach
((
_Symbol
symbol
,
_Row
row
)
{
if
(
symbol
.
type
!=
_SymbolType
.
external
)
{
if
(
symbol
.
type
!=
_SymbolType
.
external
)
{
double
temp
=
row
.
coefficientForSymbol
(
entering
);
double
temp
=
row
.
coefficientForSymbol
(
entering
);
if
(
temp
<
0.0
)
{
if
(
temp
<
0.0
)
{
double
tempRatio
=
-
row
.
constant
/
temp
;
double
tempRatio
=
-
row
.
constant
/
temp
;
if
(
tempRatio
<
ratio
)
{
if
(
tempRatio
<
ratio
)
{
ratio
=
tempRatio
;
ratio
=
tempRatio
;
result
.
first
=
symbol
;
result
=
symbol
;
result
.
second
=
row
;
}
}
}
}
}
}
});
});
if
(
result
.
first
==
null
||
result
.
second
==
null
)
{
return
null
;
}
return
result
;
return
result
;
}
}
...
@@ -431,12 +537,10 @@ class Solver {
...
@@ -431,12 +537,10 @@ class Solver {
_infeasibleRows
.
add
(
first
);
_infeasibleRows
.
add
(
first
);
}
}
});
});
_objective
.
substitute
(
symbol
,
row
);
_objective
.
substitute
(
symbol
,
row
);
if
(
_artificial
!=
null
)
{
if
(
_artificial
!=
null
)
_artificial
.
substitute
(
symbol
,
row
);
_artificial
.
substitute
(
symbol
,
row
);
}
}
}
_Symbol
_anyPivotableSymbol
(
_Row
row
)
{
_Symbol
_anyPivotableSymbol
(
_Row
row
)
{
for
(
_Symbol
symbol
in
row
.
cells
.
keys
)
{
for
(
_Symbol
symbol
in
row
.
cells
.
keys
)
{
...
@@ -466,43 +570,34 @@ class Solver {
...
@@ -466,43 +570,34 @@ class Solver {
}
}
}
}
_
Pair
<
_Symbol
,
_Row
>
_leavingRowPair
ForMarkerSymbol
(
_Symbol
marker
)
{
_
Symbol
_leavingSymbol
ForMarkerSymbol
(
_Symbol
marker
)
{
double
r1
=
double
.
MAX_FINITE
;
double
r1
=
double
.
MAX_FINITE
;
double
r2
=
double
.
MAX_FINITE
;
double
r2
=
double
.
MAX_FINITE
;
_
Pair
<
_Symbol
,
_Row
>
first
,
second
,
third
;
_
Symbol
first
,
second
,
third
;
_rows
.
forEach
((
_Symbol
symbol
,
_Row
row
)
{
_rows
.
forEach
((
_Symbol
symbol
,
_Row
row
)
{
double
c
=
row
.
coefficientForSymbol
(
marker
);
double
c
=
row
.
coefficientForSymbol
(
marker
);
if
(
c
==
0.0
)
if
(
c
==
0.0
)
{
return
;
return
;
}
if
(
symbol
.
type
==
_SymbolType
.
external
)
{
if
(
symbol
.
type
==
_SymbolType
.
external
)
{
third
=
new
_Pair
<
_Symbol
,
_Row
>(
symbol
,
row
)
;
third
=
symbol
;
}
else
if
(
c
<
0.0
)
{
}
else
if
(
c
<
0.0
)
{
double
r
=
-
row
.
constant
/
c
;
double
r
=
-
row
.
constant
/
c
;
if
(
r
<
r1
)
{
if
(
r
<
r1
)
{
r1
=
r
;
r1
=
r
;
first
=
new
_Pair
<
_Symbol
,
_Row
>(
symbol
,
row
)
;
first
=
symbol
;
}
}
}
else
{
}
else
{
double
r
=
row
.
constant
/
c
;
double
r
=
row
.
constant
/
c
;
if
(
r
<
r2
)
{
if
(
r
<
r2
)
{
r2
=
r
;
r2
=
r
;
second
=
new
_Pair
<
_Symbol
,
_Row
>(
symbol
,
row
)
;
second
=
symbol
;
}
}
}
}
});
});
if
(
first
!=
null
)
{
return
first
??
second
??
third
;
return
first
;
}
if
(
second
!=
null
)
{
return
second
;
}
return
third
;
}
}
void
_suggestValueForEditInfoWithoutDualOptimization
(
void
_suggestValueForEditInfoWithoutDualOptimization
(
...
@@ -551,9 +646,7 @@ class Solver {
...
@@ -551,9 +646,7 @@ class Solver {
if
(
row
!=
null
&&
row
.
constant
<
0.0
)
{
if
(
row
!=
null
&&
row
.
constant
<
0.0
)
{
_Symbol
entering
=
_dualEnteringSymbolForRow
(
row
);
_Symbol
entering
=
_dualEnteringSymbolForRow
(
row
);
if
(
entering
.
type
==
_SymbolType
.
invalid
)
{
assert
(
entering
.
type
!=
_SymbolType
.
invalid
);
return
Result
.
internalSolverError
;
}
_rows
.
remove
(
leaving
);
_rows
.
remove
(
leaving
);
...
@@ -630,25 +723,3 @@ class Solver {
...
@@ -630,25 +723,3 @@ class Solver {
return
buffer
.
toString
();
return
buffer
.
toString
();
}
}
}
}
class
_Tag
{
_Symbol
marker
;
_Symbol
other
;
_Tag
(
this
.
marker
,
this
.
other
);
_Tag
.
fromTag
(
_Tag
tag
)
:
this
.
marker
=
tag
.
marker
,
this
.
other
=
tag
.
other
;
}
class
_EditInfo
{
_Tag
tag
;
Constraint
constraint
;
double
constant
;
}
bool
_isValidNonRequiredPriority
(
double
priority
)
{
return
(
priority
>=
0.0
&&
priority
<
Priority
.
required
);
}
typedef
Result
_SolverBulkUpdate
(
dynamic
item
);
packages/cassowary/lib/term.dart
→
packages/cassowary/lib/
src/
term.dart
View file @
da885781
...
@@ -2,23 +2,26 @@
...
@@ -2,23 +2,26 @@
// Use of this source code is governed by a BSD-style license that can be
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// found in the LICENSE file.
part of
cassowary
;
import
'equation_member.dart'
;
import
'expression.dart'
;
import
'param.dart'
;
class
Term
extends
_
EquationMember
{
class
Term
extends
EquationMember
{
Term
(
this
.
variable
,
this
.
coefficient
);
Term
(
this
.
variable
,
this
.
coefficient
);
final
Variable
variable
;
final
Variable
variable
;
final
double
coefficient
;
final
double
coefficient
;
@override
@override
bool
get
isConstant
=>
false
;
Expression
asExpression
()
=>
new
Expression
([
new
Term
(
this
.
variable
,
this
.
coefficient
)],
0.0
);
@override
@override
double
get
value
=>
coefficient
*
variable
.
valu
e
;
bool
get
isConstant
=>
fals
e
;
@override
@override
Expression
asExpression
()
=>
double
get
value
=>
coefficient
*
variable
.
value
;
new
Expression
([
new
Term
(
this
.
variable
,
this
.
coefficient
)],
0.0
);
@override
@override
String
toString
()
{
String
toString
()
{
...
...
packages/cassowary/lib/symbol.dart
deleted
100644 → 0
View file @
2f44055c
// 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
;
enum
_SymbolType
{
invalid
,
external
,
slack
,
error
,
dummy
,
}
class
_Symbol
{
final
_SymbolType
type
;
final
int
tick
;
_Symbol
(
this
.
type
,
this
.
tick
);
@override
String
toString
()
{
String
typeString
=
'unknown'
;
switch
(
type
)
{
case
_SymbolType
.
invalid
:
typeString
=
'i'
;
break
;
case
_SymbolType
.
external
:
typeString
=
'v'
;
break
;
case
_SymbolType
.
slack
:
typeString
=
's'
;
break
;
case
_SymbolType
.
error
:
typeString
=
'e'
;
break
;
case
_SymbolType
.
dummy
:
typeString
=
'd'
;
break
;
}
return
'
$typeString$tick
'
;
}
}
packages/cassowary/lib/utils.dart
deleted
100644 → 0
View file @
2f44055c
// 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
;
}
class
_Pair
<
X
,
Y
>
{
X
first
;
Y
second
;
_Pair
(
this
.
first
,
this
.
second
);
}
packages/cassowary/lib/variable.dart
deleted
100644 → 0
View file @
2f44055c
// 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
Variable
{
double
value
;
String
name
;
Param
_owner
;
final
int
_tick
;
static
int
_total
=
0
;
Variable
(
this
.
value
)
:
_tick
=
_total
++;
bool
_applyUpdate
(
double
updated
)
{
bool
res
=
updated
!=
value
;
value
=
updated
;
return
res
;
}
String
get
debugName
=>
name
??
'variable
$_tick
'
;
@override
String
toString
()
=>
debugName
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment