Make SharedSolver BArchivable to save extra user constraints.
This commit is contained in:
@@ -21,6 +21,10 @@ namespace LinearProgramming {
|
||||
class Constraint;
|
||||
};
|
||||
|
||||
namespace BPrivate {
|
||||
class SharedSolver;
|
||||
};
|
||||
|
||||
|
||||
namespace BALM {
|
||||
|
||||
@@ -113,6 +117,7 @@ private:
|
||||
private:
|
||||
friend class BALMLayout;
|
||||
friend class RowColumnManager;
|
||||
friend class BPrivate::SharedSolver;
|
||||
|
||||
BLayoutItem* fLayoutItem;
|
||||
int32 fID;
|
||||
|
||||
@@ -16,6 +16,11 @@ namespace LinearProgramming {
|
||||
};
|
||||
|
||||
|
||||
namespace BPrivate {
|
||||
class SharedSolver;
|
||||
};
|
||||
|
||||
|
||||
namespace BALM {
|
||||
|
||||
|
||||
@@ -37,6 +42,10 @@ public:
|
||||
XTab* Right() const;
|
||||
|
||||
private:
|
||||
friend class BALMLayout;
|
||||
friend class BALM::RowColumnManager;
|
||||
friend class BPrivate::SharedSolver;
|
||||
|
||||
Column(LinearProgramming::LinearSpec* ls,
|
||||
XTab* left, XTab* right);
|
||||
|
||||
@@ -48,11 +57,6 @@ private:
|
||||
// managed by RowColumnManager
|
||||
|
||||
BObjectList<Area> fAreas;
|
||||
|
||||
public:
|
||||
friend class BALMLayout;
|
||||
friend class BALM::RowColumnManager;
|
||||
|
||||
};
|
||||
|
||||
} // namespace BALM
|
||||
|
||||
@@ -16,6 +16,11 @@ namespace LinearProgramming {
|
||||
};
|
||||
|
||||
|
||||
namespace BPrivate {
|
||||
class SharedSolver;
|
||||
};
|
||||
|
||||
|
||||
namespace BALM {
|
||||
|
||||
|
||||
@@ -37,6 +42,10 @@ public:
|
||||
YTab* Bottom() const;
|
||||
|
||||
private:
|
||||
friend class BALMLayout;
|
||||
friend class BALM::RowColumnManager;
|
||||
friend class BPrivate::SharedSolver;
|
||||
|
||||
Row(LinearProgramming::LinearSpec* ls,
|
||||
YTab* top, YTab* bottom);
|
||||
|
||||
@@ -48,11 +57,6 @@ private:
|
||||
// managed by RowColumnManager
|
||||
|
||||
BObjectList<Area> fAreas;
|
||||
|
||||
public:
|
||||
friend class BALMLayout;
|
||||
friend class BALM::RowColumnManager;
|
||||
|
||||
};
|
||||
|
||||
} // namespace BALM
|
||||
|
||||
+11
-19
@@ -28,7 +28,7 @@ const BSize kUnsetSize(B_SIZE_UNSET, B_SIZE_UNSET);
|
||||
|
||||
namespace {
|
||||
|
||||
const char* kFriendField = "BALMLayout:friends";
|
||||
const char* kSolverField = "BALMLayout:solver";
|
||||
const char* kBadLayoutPolicyField = "BALMLayout:policy";
|
||||
const char* kXTabsField = "BALMLayout:xtabs";
|
||||
const char* kYTabsField = "BALMLayout:ytabs";
|
||||
@@ -269,6 +269,9 @@ BALMLayout::BALMLayout(BMessage* archive)
|
||||
if (err == B_OK && archive->GetInfo(kBadLayoutPolicyField, NULL) == B_OK)
|
||||
err = unarchiver.EnsureUnarchived(kBadLayoutPolicyField);
|
||||
|
||||
if (err == B_OK)
|
||||
err = unarchiver.EnsureUnarchived(kSolverField);
|
||||
|
||||
unarchiver.Finish(err);
|
||||
}
|
||||
|
||||
@@ -1061,6 +1064,9 @@ BALMLayout::Archive(BMessage* into, bool deep) const
|
||||
err = archiver.AddArchivable(kBadLayoutPolicyField, fBadLayoutPolicy);
|
||||
}
|
||||
|
||||
if (err == B_OK)
|
||||
err = archiver.AddArchivable(kSolverField, fSolver);
|
||||
|
||||
if (err == B_OK)
|
||||
err = archiver.AddArchivable(kMyTabsField, fLeft);
|
||||
if (err == B_OK)
|
||||
@@ -1140,26 +1146,14 @@ BALMLayout::AllUnarchived(const BMessage* archive)
|
||||
{
|
||||
BUnarchiver unarchiver(archive);
|
||||
|
||||
status_t err = B_OK;
|
||||
if (fSolver == NULL) {
|
||||
_SetSolver(new SharedSolver());
|
||||
|
||||
int32 friendCount = 0;
|
||||
archive->GetInfo(kFriendField, NULL, &friendCount);
|
||||
for (int32 i = 0; i < friendCount; i++) {
|
||||
BALMLayout* layout;
|
||||
err = unarchiver.FindObject(kFriendField, i,
|
||||
BUnarchiver::B_DONT_ASSUME_OWNERSHIP, layout);
|
||||
if (err != B_OK)
|
||||
return err;
|
||||
|
||||
layout->_SetSolver(fSolver);
|
||||
}
|
||||
}
|
||||
SharedSolver* solver;
|
||||
status_t err = unarchiver.FindObject(kSolverField, solver);
|
||||
|
||||
if (err != B_OK)
|
||||
return err;
|
||||
|
||||
_SetSolver(solver);
|
||||
|
||||
if (archive->GetInfo(kBadLayoutPolicyField, NULL) == B_OK) {
|
||||
BadLayoutPolicy* policy;
|
||||
err = unarchiver.FindObject(kBadLayoutPolicyField, policy);
|
||||
@@ -1235,8 +1229,6 @@ BALMLayout::AllArchived(BMessage* archive) const
|
||||
{
|
||||
status_t err = BAbstractLayout::AllArchived(archive);
|
||||
|
||||
if (err == B_OK)
|
||||
err = fSolver->AddFriendReferences(this, archive, kFriendField);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,11 @@
|
||||
#include "Tab.h"
|
||||
|
||||
|
||||
namespace BPrivate {
|
||||
class SharedSolver;
|
||||
};
|
||||
|
||||
|
||||
namespace BALM {
|
||||
|
||||
|
||||
@@ -41,6 +46,7 @@ public:
|
||||
void UpdateConstraints();
|
||||
void TabsChanged(Area* area);
|
||||
private:
|
||||
friend class BPrivate::SharedSolver;
|
||||
Row* _FindRowFor(Area* area);
|
||||
Column* _FindColumnFor(Area* area);
|
||||
|
||||
@@ -52,7 +58,7 @@ private:
|
||||
void _UpdateConstraints(Row* row);
|
||||
void _UpdateConstraints(Column* column);
|
||||
|
||||
BObjectList<Row> fRows;
|
||||
BObjectList<Row> fRows;
|
||||
BObjectList<Column> fColumns;
|
||||
|
||||
LinearSpec* fLinearSpec;
|
||||
|
||||
@@ -6,13 +6,26 @@
|
||||
|
||||
#include "SharedSolver.h"
|
||||
|
||||
#include <set>
|
||||
|
||||
#include <ALMLayout.h>
|
||||
#include <AutoDeleter.h>
|
||||
#include <ObjectList.h>
|
||||
|
||||
#include "RowColumnManager.h"
|
||||
|
||||
|
||||
using LinearProgramming::LinearSpec;
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
type_code kConstraintsTypeCode = 'cnst';
|
||||
const char* kConstraintsField = "SharedSolver:constraints";
|
||||
|
||||
};
|
||||
|
||||
|
||||
struct SharedSolver::MinSizeValidator {
|
||||
inline void CallSolverMethod(LinearSpec* spec, VariableList* vars)
|
||||
{
|
||||
@@ -80,6 +93,19 @@ SharedSolver::SharedSolver()
|
||||
}
|
||||
|
||||
|
||||
SharedSolver::SharedSolver(BMessage* archive)
|
||||
:
|
||||
BArchivable(archive),
|
||||
fConstraintsValid(false),
|
||||
fMinValid(false),
|
||||
fMaxValid(false),
|
||||
fPreferredValid(false),
|
||||
fLayoutValid(false),
|
||||
fLayoutContext(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
SharedSolver::~SharedSolver()
|
||||
{
|
||||
if (fLayouts.CountItems() > 0)
|
||||
@@ -178,18 +204,184 @@ SharedSolver::ValidateLayout(BLayoutContext* context)
|
||||
|
||||
|
||||
status_t
|
||||
SharedSolver::AddFriendReferences(const BALMLayout* layout, BMessage* archive,
|
||||
const char* field)
|
||||
SharedSolver::Archive(BMessage* archive, bool deep) const
|
||||
{
|
||||
status_t err = B_OK;
|
||||
return BArchivable::Archive(archive, deep);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
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
|
||||
for each constraint in the linear spec:
|
||||
if it is not in the set above:
|
||||
archive it
|
||||
*/
|
||||
BArchiver archiver(archive);
|
||||
for (int32 i = fLayouts.CountItems() - 1; i >= 0 && err == B_OK; i--) {
|
||||
BALMLayout* current = fLayouts.ItemAt(i);
|
||||
if (current == layout)
|
||||
std::set<Constraint*> autoConstraints;
|
||||
for (int32 i = fLayouts.CountItems() - 1; i >= 0; i--) {
|
||||
BALMLayout* layout = fLayouts.ItemAt(i);
|
||||
if (!archiver.IsArchived(layout))
|
||||
continue;
|
||||
if (archiver.IsArchived(current))
|
||||
err = archiver.AddArchivable(field, current);
|
||||
|
||||
for (int32 j = layout->CountItems() - 1; j >= 0; j--)
|
||||
_AddConstraintsToSet(layout->AreaAt(j), autoConstraints);
|
||||
|
||||
for (int32 j = layout->fRowColumnManager->fRows.CountItems() - 1;
|
||||
j >= 0; j--) {
|
||||
Row* row = layout->fRowColumnManager->fRows.ItemAt(i);
|
||||
autoConstraints.insert(row->fPrefSizeConstraint);
|
||||
}
|
||||
|
||||
for (int32 j = layout->fRowColumnManager->fColumns.CountItems() - 1;
|
||||
j >= 0; j--) {
|
||||
Column* column = layout->fRowColumnManager->fColumns.ItemAt(i);
|
||||
autoConstraints.insert(column->fPrefSizeConstraint);
|
||||
}
|
||||
}
|
||||
|
||||
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())
|
||||
err = _AddConstraintToArchive(constraint, archive);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
SharedSolver::AllUnarchived(const BMessage* archive)
|
||||
{
|
||||
int32 count = 0;
|
||||
archive->GetInfo(kConstraintsField, NULL, &count);
|
||||
|
||||
status_t err = B_OK;
|
||||
BUnarchiver unarchiver(archive);
|
||||
for (int32 i = 0; i < count && err == B_OK; i++) {
|
||||
const void* constraintData;
|
||||
ssize_t numBytes;
|
||||
err = archive->FindData(kConstraintsField, kConstraintsTypeCode,
|
||||
i, &constraintData, &numBytes);
|
||||
if (err != B_OK)
|
||||
return err;
|
||||
|
||||
err = _InstantiateConstraint(constraintData, numBytes, unarchiver);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SharedSolver::_AddConstraintsToSet(Area* area,
|
||||
std::set<Constraint*>& constraints)
|
||||
{
|
||||
if (area->fMinContentWidth)
|
||||
constraints.insert(area->fMinContentWidth);
|
||||
if (area->fMaxContentWidth)
|
||||
constraints.insert(area->fMaxContentWidth);
|
||||
if (area->fMinContentHeight)
|
||||
constraints.insert(area->fMinContentHeight);
|
||||
if (area->fMaxContentHeight)
|
||||
constraints.insert(area->fMaxContentHeight);
|
||||
if (area->fContentAspectRatioC)
|
||||
constraints.insert(area->fContentAspectRatioC);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
SharedSolver::_AddConstraintToArchive(Constraint* constraint, BMessage* archive)
|
||||
{
|
||||
// TODO: check Read/Write calls
|
||||
BArchiver archiver(archive);
|
||||
BMallocIO buffer;
|
||||
SummandList* leftSide = constraint->LeftSide();
|
||||
int32 summandCount = leftSide->CountItems();
|
||||
buffer.Write(&summandCount, sizeof(summandCount));
|
||||
|
||||
for (int32 i = 0; i < summandCount; i++) {
|
||||
Summand* summand = leftSide->ItemAt(i);
|
||||
Variable* var = summand->Var();
|
||||
BArchivable* varArchivable = dynamic_cast<BArchivable*>(var);
|
||||
if (!varArchivable || !archiver.IsArchived(varArchivable))
|
||||
return B_NAME_NOT_FOUND;
|
||||
|
||||
int32 token;
|
||||
archiver.GetTokenForArchivable(varArchivable, token);
|
||||
buffer.Write(&token, sizeof(token));
|
||||
|
||||
double coefficient = summand->Coeff();
|
||||
buffer.Write(&coefficient, sizeof(coefficient));
|
||||
}
|
||||
|
||||
int32 op = constraint->Op();
|
||||
buffer.Write(&op, sizeof(op));
|
||||
|
||||
double rightSide = constraint->RightSide();
|
||||
buffer.Write(&rightSide, sizeof(rightSide));
|
||||
double penaltyNeg = constraint->PenaltyNeg();
|
||||
buffer.Write(&penaltyNeg, sizeof(penaltyNeg));
|
||||
double penaltyPos = constraint->PenaltyPos();
|
||||
buffer.Write(&penaltyPos, sizeof(penaltyPos));
|
||||
|
||||
return archive->AddData(kConstraintsField, kConstraintsTypeCode,
|
||||
buffer.Buffer(), buffer.BufferLength(), false);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
SharedSolver::_InstantiateConstraint(const void* rawData, ssize_t numBytes,
|
||||
BUnarchiver& unarchiver)
|
||||
{
|
||||
// TODO: check Read/Write calls
|
||||
BMemoryIO buffer(rawData, numBytes);
|
||||
int32 summandCount;
|
||||
buffer.Read((void*)&summandCount, sizeof(summandCount));
|
||||
|
||||
SummandList* summandList = new SummandList(20, true);
|
||||
ObjectDeleter<SummandList> deleter(summandList);
|
||||
status_t err = B_OK;
|
||||
for (int32 i = 0; i < summandCount; i++) {
|
||||
int32 token;
|
||||
buffer.Read((void*)&token, sizeof(token));
|
||||
|
||||
BArchivable* varArchivable;
|
||||
err = unarchiver.GetObject(token, varArchivable);
|
||||
if (err != B_OK)
|
||||
break;
|
||||
Variable* var = dynamic_cast<Variable*>(varArchivable);
|
||||
if (!var)
|
||||
return B_BAD_TYPE;
|
||||
|
||||
fLinearSpec.AddVariable(var);
|
||||
|
||||
double coefficient;
|
||||
buffer.Read(&coefficient, sizeof(coefficient));
|
||||
|
||||
summandList->AddItem(new Summand(coefficient, var));
|
||||
}
|
||||
|
||||
int32 op;
|
||||
buffer.Read(&op, sizeof(op));
|
||||
|
||||
double rightSide;
|
||||
buffer.Read(&rightSide, sizeof(rightSide));
|
||||
double penaltyNeg;
|
||||
buffer.Read(&penaltyNeg, sizeof(penaltyNeg));
|
||||
double penaltyPos;
|
||||
buffer.Read(&penaltyPos, sizeof(penaltyPos));
|
||||
|
||||
if (err == B_OK) {
|
||||
fLinearSpec.AddConstraint(summandList, (OperatorType)op, rightSide,
|
||||
penaltyNeg, penaltyPos);
|
||||
deleter.Detach();
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -275,3 +467,12 @@ SharedSolver::_Validate(bool& isValid, ResultType& result)
|
||||
isValid = true;
|
||||
fLayoutValid = false;
|
||||
}
|
||||
|
||||
|
||||
BArchivable*
|
||||
SharedSolver::Instantiate(BMessage* archive)
|
||||
{
|
||||
if (validate_instantiation(archive, "BPrivate::SharedSolver"))
|
||||
return new SharedSolver(archive);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
#define _SHARED_SOLVER_H
|
||||
|
||||
|
||||
#include <set>
|
||||
|
||||
#include <Archivable.h>
|
||||
#include <LayoutContext.h>
|
||||
#include <ObjectList.h>
|
||||
#include <Referenceable.h>
|
||||
@@ -17,18 +20,20 @@ class BMessage;
|
||||
|
||||
namespace BALM {
|
||||
class BALMLayout;
|
||||
class Area;
|
||||
};
|
||||
|
||||
|
||||
using BALM::BALMLayout;
|
||||
|
||||
using BALM::Area;
|
||||
|
||||
|
||||
namespace BPrivate {
|
||||
|
||||
|
||||
class SharedSolver : BLayoutContextListener, public BReferenceable {
|
||||
class SharedSolver : BLayoutContextListener, public BReferenceable,
|
||||
public BArchivable {
|
||||
public:
|
||||
SharedSolver(BMessage* archive);
|
||||
SharedSolver();
|
||||
~SharedSolver();
|
||||
|
||||
@@ -47,6 +52,13 @@ public:
|
||||
|
||||
status_t AddFriendReferences(const BALMLayout* layout,
|
||||
BMessage* archive, const char* field);
|
||||
|
||||
status_t Archive(BMessage* archive, bool deep) const;
|
||||
status_t AllArchived(BMessage* archive) const;
|
||||
status_t AllUnarchived(const BMessage* archive);
|
||||
|
||||
static BArchivable* Instantiate(BMessage* archive);
|
||||
|
||||
private:
|
||||
struct MinSizeValidator;
|
||||
struct MaxSizeValidator;
|
||||
@@ -56,6 +68,14 @@ private:
|
||||
friend struct MaxSizeValidator;
|
||||
friend struct PreferredSizeValidator;
|
||||
|
||||
|
||||
static void _AddConstraintsToSet(Area* area,
|
||||
std::set<Constraint*>& constraints);
|
||||
static status_t _AddConstraintToArchive(Constraint* constraint,
|
||||
BMessage* archive);
|
||||
status_t _InstantiateConstraint(const void* rawData,
|
||||
ssize_t numBytes, BUnarchiver& unarchiver);
|
||||
|
||||
void SetMaxSize(BALM::BALMLayout* layout,
|
||||
const BSize& max);
|
||||
void SetMinSize(BALM::BALMLayout* layout,
|
||||
|
||||
Reference in New Issue
Block a user