Skip to content

Commit

Permalink
Fix BALMLayout archiving issues.
Browse files Browse the repository at this point in the history
SharedSolver was archiving too many constraints, partly because of
multiple typos, also because it archived some which were just artifacts
of the layout process. These extra constraints are created when the
layout calls SetRange() on the left/top/right/bottom tabs during layout.

* LinearSpec/ActiveSetSolver had to be adjusted to get access to the
  constraints added by the SetRange() calls.
* BALM::TabBase was adjusted to avoid a segfault during unarchiving,
  caused by an unitialized member.
* ALMFriendLayoutTest was adjusted to include a more obvious custom
  constraint for testing.
  • Loading branch information
yourpalal committed May 2, 2012
1 parent 5f4e71b commit c8b24e3
Show file tree
Hide file tree
Showing 8 changed files with 90 additions and 14 deletions.
7 changes: 7 additions & 0 deletions headers/libs/linprog/LinearSpec.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ class SolverInterface {
virtual ResultType FindMins(const VariableList* variables) = 0;
virtual ResultType FindMaxs(const VariableList* variables) = 0;

virtual void GetRangeConstraints(const Variable* var,
const Constraint** _min,
const Constraint** _max) const = 0;

protected:
LinearSpec* fLinearSpec;
};
Expand Down Expand Up @@ -138,6 +142,9 @@ class LinearSpec : public BReferenceable {

BString ToString() const;

void GetRangeConstraints(const Variable*,
const Constraint** _min,
const Constraint** _max) const;
const ConstraintList& Constraints() const;
const VariableList& UsedVariables() const;
const VariableList& AllVariables() const;
Expand Down
60 changes: 50 additions & 10 deletions src/libs/alm/SharedSolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,12 +217,13 @@ SharedSolver::AllArchived(BMessage* archive) const
for each archived layout:
add it to our archive
add constraints created by areas and column manager to a set
add range constraints on the left/top/right/bottom tabs to the same set
for each constraint in the linear spec:
if it is not in the set above:
archive it
*/
BArchiver archiver(archive);
std::set<Constraint*> autoConstraints;
std::set<const Constraint*> autoConstraints;
for (int32 i = fLayouts.CountItems() - 1; i >= 0; i--) {
BALMLayout* layout = fLayouts.ItemAt(i);
if (!archiver.IsArchived(layout))
Expand All @@ -233,22 +234,35 @@ SharedSolver::AllArchived(BMessage* archive) const

for (int32 j = layout->fRowColumnManager->fRows.CountItems() - 1;
j >= 0; j--) {
Row* row = layout->fRowColumnManager->fRows.ItemAt(i);
Row* row = layout->fRowColumnManager->fRows.ItemAt(j);
autoConstraints.insert(row->fPrefSizeConstraint);
}

for (int32 j = layout->fRowColumnManager->fColumns.CountItems() - 1;
j >= 0; j--) {
Column* column = layout->fRowColumnManager->fColumns.ItemAt(i);
Column* column = layout->fRowColumnManager->fColumns.ItemAt(j);
autoConstraints.insert(column->fPrefSizeConstraint);
}

Variable* corners[] = {layout->fLeft, layout->fTop, layout->fRight,
layout->fBottom};

for (int32 j = 0; j < 4; j++) {
const Constraint* min;
const Constraint* max;
fLinearSpec.GetRangeConstraints(corners[j], &min, &max);
if (min)
autoConstraints.insert(min);
if (max)
autoConstraints.insert(max);
}
}

status_t err = B_OK;
const ConstraintList& constraints = fLinearSpec.Constraints();
for (int32 i = constraints.CountItems() - 1; i >= 0 && err == B_OK; i--) {
Constraint* constraint = constraints.ItemAt(i);
if (autoConstraints.find(constraint) != autoConstraints.end())
if (autoConstraints.find(constraint) == autoConstraints.end())
err = _AddConstraintToArchive(constraint, archive);
}
return err;
Expand Down Expand Up @@ -279,7 +293,7 @@ SharedSolver::AllUnarchived(const BMessage* archive)

void
SharedSolver::_AddConstraintsToSet(Area* area,
std::set<Constraint*>& constraints)
std::set<const Constraint*>& constraints)
{
if (area->fMinContentWidth)
constraints.insert(area->fMinContentWidth);
Expand All @@ -295,8 +309,20 @@ SharedSolver::_AddConstraintsToSet(Area* area,


status_t
SharedSolver::_AddConstraintToArchive(Constraint* constraint, BMessage* archive)
SharedSolver::_AddConstraintToArchive(Constraint* constraint,
BMessage* archive)
{
/* Format:
* int32: summandCount
* { int32 : token
* double: coefficient
* } [summandCount]
* int32: operator
* double: rightSide
* double: penaltyNeg
* double: penaltyPos
*/

// TODO: check Read/Write calls
BArchiver archiver(archive);
BMallocIO buffer;
Expand Down Expand Up @@ -338,6 +364,17 @@ status_t
SharedSolver::_InstantiateConstraint(const void* rawData, ssize_t numBytes,
BUnarchiver& unarchiver)
{
/* Format:
* int32: summandCount
* { int32 : token
* double: coefficient
* } [summandCount]
* int32: operator
* double: rightSide
* double: penaltyNeg
* double: penaltyPos
*/

// TODO: check Read/Write calls
BMemoryIO buffer(rawData, numBytes);
int32 summandCount;
Expand Down Expand Up @@ -376,13 +413,16 @@ SharedSolver::_InstantiateConstraint(const void* rawData, ssize_t numBytes,
double penaltyPos;
buffer.Read(&penaltyPos, sizeof(penaltyPos));

if (err == B_OK) {
fLinearSpec.AddConstraint(summandList, (OperatorType)op, rightSide,
penaltyNeg, penaltyPos);
if (err != B_OK)
return err;

if (fLinearSpec.AddConstraint(summandList, (OperatorType)op, rightSide,
penaltyNeg, penaltyPos) != NULL) {
deleter.Detach();
return B_OK;
}

return err;
return B_NO_MEMORY;
}


Expand Down
2 changes: 1 addition & 1 deletion src/libs/alm/SharedSolver.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ class SharedSolver : BLayoutContextListener, public BReferenceable,


static void _AddConstraintsToSet(Area* area,
std::set<Constraint*>& constraints);
std::set<const Constraint*>& constraints);
static status_t _AddConstraintToArchive(Constraint* constraint,
BMessage* archive);
status_t _InstantiateConstraint(const void* rawData,
Expand Down
3 changes: 2 additions & 1 deletion src/libs/alm/Tab.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ TabBase::TabBase()

TabBase::TabBase(BMessage* archive)
:
BArchivable(BUnarchiver::PrepareArchive(archive))
BArchivable(BUnarchiver::PrepareArchive(archive)),
fLayouts(NULL)
{
BUnarchiver(archive).Finish(B_OK);
}
Expand Down
13 changes: 13 additions & 0 deletions src/libs/linprog/ActiveSetSolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -613,6 +613,19 @@ ActiveSetSolver::FindMins(const VariableList* variables)
}


void
ActiveSetSolver::GetRangeConstraints(const Variable* var,
const Constraint** _min, const Constraint** _max) const
{
int32 variableIndex = var->GlobalIndex();

if (_min)
*_min = fVariableGEConstraints.ItemAt(variableIndex);
if (_max)
*_max = fVariableLEConstraints.ItemAt(variableIndex);
}


void
ActiveSetSolver::_RemoveSoftConstraint(ConstraintList& list)
{
Expand Down
3 changes: 3 additions & 0 deletions src/libs/linprog/ActiveSetSolver.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ class ActiveSetSolver : public QPSolverInterface {
ResultType FindMaxs(const VariableList* variables);
ResultType FindMins(const VariableList* variables);

void GetRangeConstraints(const Variable* var,
const Constraint** _min,
const Constraint** _max) const;
private:
void _RemoveSoftConstraint(ConstraintList& list);
void _AddSoftConstraint(const ConstraintList& list);
Expand Down
12 changes: 12 additions & 0 deletions src/libs/linprog/LinearSpec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,18 @@ LinearSpec::Save(const char* fileName)
}


/**
* Gets the constraints generated by calls to Variable::SetRange()
*
*/
void
LinearSpec::GetRangeConstraints(const Variable* var, const Constraint** _min,
const Constraint** _max) const
{
fSolver->GetRangeConstraints(var, _min, _max);
}


/**
* Gets the constraints.
*
Expand Down
4 changes: 2 additions & 2 deletions src/tests/libs/alm/FriendLayout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ class FriendWindow : public BWindow {
fRight = xTabs[1];

layout1->AreaFor(button2)->SetContentAspectRatio(1.0f);
fLayout2->Solver()->AddConstraint(-1.0f, xTabs[0], 1.0f, xTabs[1],
LinearProgramming::kGE, 20.0f);
fLayout2->Solver()->AddConstraint(-1.0f, layout1->Left(), 1.0f, xTabs[0],
LinearProgramming::kLE, 90.0f);

BButton* archiveButton = new BButton("clone", new BMessage('arcv'));
archiveButton->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED,
Expand Down

0 comments on commit c8b24e3

Please sign in to comment.