From cad0c434c7585bd21548499b2fcdf347c44b8074 Mon Sep 17 00:00:00 2001 From: Clemens Zeidler Date: Mon, 4 Oct 2010 22:27:02 +0000 Subject: [PATCH] Refactor LinearSpec a bit, make it more difficult to leak the objective function. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@38888 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/libs/linprog/LinearSpec.h | 9 ++++++--- src/libs/alm/ALMLayout.cpp | 20 ++++++------------- src/libs/linprog/Constraint.cpp | 20 +++++++++---------- src/libs/linprog/LinearSpec.cpp | 29 ++++++++++++++++++++-------- src/libs/linprog/PenaltyFunction.cpp | 4 ++-- src/tests/libs/alm/Pinwheel.cpp | 9 +++++---- 6 files changed, 50 insertions(+), 41 deletions(-) diff --git a/headers/libs/linprog/LinearSpec.h b/headers/libs/linprog/LinearSpec.h index 1a0d8334ff..2616cd445a 100644 --- a/headers/libs/linprog/LinearSpec.h +++ b/headers/libs/linprog/LinearSpec.h @@ -79,9 +79,12 @@ public: PenaltyFunction* AddPenaltyFunction(Variable* var, BList* xs, BList* gs); - SummandList* ObjFunction(); - void SetObjFunction(SummandList* summands); - void UpdateObjFunction(); + SummandList* ObjectiveFunction(); + //! Caller takes ownership of the Summand's and the SummandList. + SummandList* ReplaceObjectiveFunction( + SummandList* objFunction); + void SetObjectiveFunction(SummandList* objFunction); + void UpdateObjectiveFunction(); ResultType Presolve(); void RemovePresolved(); diff --git a/src/libs/alm/ALMLayout.cpp b/src/libs/alm/ALMLayout.cpp index 400808bf16..d7d3966862 100644 --- a/src/libs/alm/ALMLayout.cpp +++ b/src/libs/alm/ALMLayout.cpp @@ -798,17 +798,13 @@ BALMLayout::_CalculateMinSize() { _UpdateAreaConstraints(); - SummandList* oldObjFunction = fSolver.ObjFunction(); SummandList* newObjFunction = new SummandList(2); newObjFunction->AddItem(new Summand(1.0, fRight)); newObjFunction->AddItem(new Summand(1.0, fBottom)); - fSolver.SetObjFunction(newObjFunction); + SummandList* oldObjFunction = fSolver.ReplaceObjectiveFunction( + newObjFunction); _SolveLayout(); - fSolver.SetObjFunction(oldObjFunction); - fSolver.UpdateObjFunction(); - delete newObjFunction->ItemAt(0); - delete newObjFunction->ItemAt(1); - delete newObjFunction; + fSolver.SetObjectiveFunction(oldObjFunction); if (fSolver.Result() == UNBOUNDED) return kMinSize; @@ -831,17 +827,13 @@ BALMLayout::_CalculateMaxSize() { _UpdateAreaConstraints(); - SummandList* oldObjFunction = fSolver.ObjFunction(); SummandList* newObjFunction = new SummandList(2); newObjFunction->AddItem(new Summand(-1.0, fRight)); newObjFunction->AddItem(new Summand(-1.0, fBottom)); - fSolver.SetObjFunction(newObjFunction); + SummandList* oldObjFunction = fSolver.ReplaceObjectiveFunction( + newObjFunction); _SolveLayout(); - fSolver.SetObjFunction(oldObjFunction); - fSolver.UpdateObjFunction(); - delete newObjFunction->ItemAt(0); - delete newObjFunction->ItemAt(1); - delete newObjFunction; + fSolver.SetObjectiveFunction(oldObjFunction); if (fSolver.Result() == UNBOUNDED) return kMaxSize; diff --git a/src/libs/linprog/Constraint.cpp b/src/libs/linprog/Constraint.cpp index d4c714149c..680ebbfb7b 100644 --- a/src/libs/linprog/Constraint.cpp +++ b/src/libs/linprog/Constraint.cpp @@ -97,7 +97,7 @@ Constraint::UpdateLeftSide() if (!set_rowex(fLS->fLP, this->Index(), i, &coeffs[0], &varIndexes[0])) STRACE(("Error in set_rowex.")); - fLS->UpdateObjFunction(); + fLS->UpdateObjectiveFunction(); fLS->RemovePresolved(); } @@ -266,9 +266,9 @@ Constraint::SetPenaltyNeg(double value) if (fDNegObjSummand == NULL) { fDNegObjSummand = new Summand(value, new Variable(fLS)); - fLS->ObjFunction()->AddItem(fDNegObjSummand); + fLS->ObjectiveFunction()->AddItem(fDNegObjSummand); UpdateLeftSide(); - fLS->UpdateObjFunction(); + fLS->UpdateObjectiveFunction(); return; } @@ -276,7 +276,7 @@ Constraint::SetPenaltyNeg(double value) return; fDNegObjSummand->SetCoeff(value); - fLS->UpdateObjFunction(); + fLS->UpdateObjectiveFunction(); } @@ -308,9 +308,9 @@ Constraint::SetPenaltyPos(double value) if (fDPosObjSummand == NULL) { fDPosObjSummand = new Summand(value, new Variable(fLS)); - fLS->ObjFunction()->AddItem(fDPosObjSummand); + fLS->ObjectiveFunction()->AddItem(fDPosObjSummand); UpdateLeftSide(); - fLS->UpdateObjFunction(); + fLS->UpdateObjectiveFunction(); return; } @@ -318,7 +318,7 @@ Constraint::SetPenaltyPos(double value) return; fDPosObjSummand->SetCoeff(value); - fLS->UpdateObjFunction(); + fLS->UpdateObjectiveFunction(); } @@ -428,13 +428,13 @@ Constraint::Invalidate() fLeftSide = NULL; if (fDNegObjSummand) { - fLS->ObjFunction()->RemoveItem(fDNegObjSummand); + fLS->ObjectiveFunction()->RemoveItem(fDNegObjSummand); delete fDNegObjSummand->Var(); delete fDNegObjSummand; fDNegObjSummand = NULL; } if (fDPosObjSummand) { - fLS->ObjFunction()->RemoveItem(fDPosObjSummand); + fLS->ObjectiveFunction()->RemoveItem(fDPosObjSummand); delete fDPosObjSummand->Var(); delete fDPosObjSummand; fDPosObjSummand = NULL; @@ -528,7 +528,7 @@ Constraint::Constraint(LinearSpec* ls, SummandList* summands, OperatorType op, : LE), rightSide)) STRACE(("Error in add_constraintex.")); - fLS->UpdateObjFunction(); + fLS->UpdateObjectiveFunction(); fLS->Constraints()->AddItem(this); } diff --git a/src/libs/linprog/LinearSpec.cpp b/src/libs/linprog/LinearSpec.cpp index 4f956041a5..83bfacf24a 100644 --- a/src/libs/linprog/LinearSpec.cpp +++ b/src/libs/linprog/LinearSpec.cpp @@ -342,26 +342,39 @@ LinearSpec::AddPenaltyFunction(Variable* var, BList* xs, BList* gs) /** * Gets the objective function. * - * @return BList containing the objective function's summands + * @return SummandList containing the objective function's summands */ SummandList* -LinearSpec::ObjFunction() +LinearSpec::ObjectiveFunction() { return fObjFunction; } +SummandList* +LinearSpec::ReplaceObjectiveFunction(SummandList* objFunction) +{ + SummandList* list = fObjFunction; + fObjFunction = objFunction; + UpdateObjectiveFunction(); + return list; +} + + /** * Sets a new objective function. - * The old objective function summands are NOT deleted. * - * @param summands BList containing the objective function's summands + * @param summands SummandList containing the objective function's summands */ void -LinearSpec::SetObjFunction(SummandList* summands) +LinearSpec::SetObjectiveFunction(SummandList* objFunction) { - fObjFunction = summands; - UpdateObjFunction(); + for (int32 i = 0; i < fObjFunction->CountItems(); i++) + delete (Summand*)fObjFunction->ItemAt(i); + delete fObjFunction; + + fObjFunction = objFunction; + UpdateObjectiveFunction(); } @@ -370,7 +383,7 @@ LinearSpec::SetObjFunction(SummandList* summands) * Must be called whenever the summands of the objective function are changed. */ void -LinearSpec::UpdateObjFunction() +LinearSpec::UpdateObjectiveFunction() { int32 size = fObjFunction->CountItems(); double coeffs[size]; diff --git a/src/libs/linprog/PenaltyFunction.cpp b/src/libs/linprog/PenaltyFunction.cpp index 29c5c32a6d..8047ccc5fa 100644 --- a/src/libs/linprog/PenaltyFunction.cpp +++ b/src/libs/linprog/PenaltyFunction.cpp @@ -45,10 +45,10 @@ PenaltyFunction::PenaltyFunction(LinearSpec* ls, Variable* var, BList* xs, BList *(double*)(xs->ItemAt(i)))); Summand* objSummand = new Summand(*(double*)(gs->ItemAt(i + 1)) - *(double*)(gs->ItemAt(i)), dPos); - ls->ObjFunction()->AddItem(objSummand); + ls->ObjectiveFunction()->AddItem(objSummand); fObjFunctionSummands->AddItem(objSummand); } - ls->UpdateObjFunction(); + ls->UpdateObjectiveFunction(); } diff --git a/src/tests/libs/alm/Pinwheel.cpp b/src/tests/libs/alm/Pinwheel.cpp index 5013edb240..004ccd4076 100644 --- a/src/tests/libs/alm/Pinwheel.cpp +++ b/src/tests/libs/alm/Pinwheel.cpp @@ -28,13 +28,9 @@ public: textView1 = new BTextView("textView1"); textView1->SetText("5"); - button1->SetExplicitMinSize(BSize(0, 0)); button1->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED)); - button2->SetExplicitMinSize(BSize(0, 0)); button2->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED)); - button3->SetExplicitMinSize(BSize(0, 0)); button3->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED)); - button4->SetExplicitMinSize(BSize(0, 0)); button4->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED)); // create a new BALMLayout and use it for this window @@ -76,6 +72,11 @@ public: a1->SetWidthAs(a3); a1->SetHeightAs(a3); */ + + // test size limits + BSize min = layout->MinSize(); + BSize max = layout->MaxSize(); + SetSizeLimits(min.Width(), max.Width(), min.Height(), max.Height()); } private: