mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-20 14:20:39 +01:00
[calculation] Do not memoize the expression layouts but the expressions
final height to avoid overflowing the heap. The expression layouts are kept in the cell which are fewer then the number of calculations
This commit is contained in:
committed by
EmilieNumworks
parent
a67f422ab7
commit
1108ef21db
@@ -11,20 +11,14 @@ Calculation::Calculation() :
|
||||
m_exactOutputText(),
|
||||
m_approximateOutputText(),
|
||||
m_input(nullptr),
|
||||
m_inputLayout(nullptr),
|
||||
m_exactOutput(nullptr),
|
||||
m_exactOutputLayout(nullptr),
|
||||
m_approximateOutput(nullptr),
|
||||
m_approximateOutputLayout(nullptr),
|
||||
m_height(-1),
|
||||
m_equalSign(EqualSign::Unknown)
|
||||
{
|
||||
}
|
||||
|
||||
Calculation::~Calculation() {
|
||||
if (m_inputLayout != nullptr) {
|
||||
delete m_inputLayout;
|
||||
m_inputLayout = nullptr;
|
||||
}
|
||||
if (m_input != nullptr) {
|
||||
delete m_input;
|
||||
m_input = nullptr;
|
||||
@@ -33,18 +27,10 @@ Calculation::~Calculation() {
|
||||
delete m_exactOutput;
|
||||
m_exactOutput = nullptr;
|
||||
}
|
||||
if (m_exactOutputLayout != nullptr) {
|
||||
delete m_exactOutputLayout;
|
||||
m_exactOutputLayout = nullptr;
|
||||
}
|
||||
if (m_approximateOutput != nullptr) {
|
||||
delete m_approximateOutput;
|
||||
m_approximateOutput = nullptr;
|
||||
}
|
||||
if (m_approximateOutputLayout != nullptr) {
|
||||
delete m_approximateOutputLayout;
|
||||
m_approximateOutputLayout = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
Calculation& Calculation::operator=(const Calculation& other) {
|
||||
@@ -78,6 +64,27 @@ void Calculation::setContent(const char * c, Context * context, Expression * ans
|
||||
m_approximateOutput->writeTextInBuffer(m_approximateOutputText, sizeof(m_approximateOutputText));
|
||||
}
|
||||
|
||||
KDCoordinate Calculation::height(Context * context) {
|
||||
if (m_height < 0) {
|
||||
ExpressionLayout * inputLayout = createInputLayout();
|
||||
KDCoordinate inputHeight = inputLayout->size().height();
|
||||
delete inputLayout;
|
||||
Poincare::ExpressionLayout * approximateLayout = createApproximateOutputLayout(context);
|
||||
KDCoordinate approximateOutputHeight = approximateLayout->size().height();
|
||||
if (shouldOnlyDisplayApproximateOutput(context)) {
|
||||
m_height = inputHeight+approximateOutputHeight;
|
||||
} else {
|
||||
Poincare::ExpressionLayout * exactLayout = createExactOutputLayout(context);
|
||||
KDCoordinate exactOutputHeight = exactLayout->size().height();
|
||||
KDCoordinate outputHeight = max(exactLayout->baseline(), approximateLayout->baseline()) + max(exactOutputHeight-exactLayout->baseline(), approximateOutputHeight-approximateLayout->baseline());
|
||||
delete exactLayout;
|
||||
m_height = inputHeight + outputHeight;
|
||||
}
|
||||
delete approximateLayout;
|
||||
}
|
||||
return m_height;
|
||||
}
|
||||
|
||||
const char * Calculation::inputText() {
|
||||
return m_inputText;
|
||||
}
|
||||
@@ -97,11 +104,11 @@ Expression * Calculation::input() {
|
||||
return m_input;
|
||||
}
|
||||
|
||||
ExpressionLayout * Calculation::inputLayout() {
|
||||
if (m_inputLayout == nullptr && input() != nullptr) {
|
||||
m_inputLayout = input()->createLayout(PrintFloat::Mode::Decimal, Expression::ComplexFormat::Cartesian);
|
||||
ExpressionLayout * Calculation::createInputLayout() {
|
||||
if (input() != nullptr) {
|
||||
return input()->createLayout(PrintFloat::Mode::Decimal, Expression::ComplexFormat::Cartesian);
|
||||
}
|
||||
return m_inputLayout;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool Calculation::isEmpty() {
|
||||
@@ -123,26 +130,15 @@ void Calculation::tidy() {
|
||||
delete m_input;
|
||||
}
|
||||
m_input = nullptr;
|
||||
if (m_inputLayout != nullptr) {
|
||||
delete m_inputLayout;
|
||||
}
|
||||
m_inputLayout = nullptr;
|
||||
if (m_exactOutput != nullptr) {
|
||||
delete m_exactOutput;
|
||||
}
|
||||
m_exactOutput = nullptr;
|
||||
if (m_exactOutputLayout != nullptr) {
|
||||
delete m_exactOutputLayout;
|
||||
}
|
||||
m_exactOutputLayout = nullptr;
|
||||
if (m_approximateOutput != nullptr) {
|
||||
delete m_approximateOutput;
|
||||
}
|
||||
m_approximateOutput = nullptr;
|
||||
if (m_approximateOutputLayout != nullptr) {
|
||||
delete m_approximateOutputLayout;
|
||||
}
|
||||
m_approximateOutputLayout = nullptr;
|
||||
m_height = -1;
|
||||
m_equalSign = EqualSign::Unknown;
|
||||
}
|
||||
|
||||
@@ -155,11 +151,11 @@ Expression * Calculation::exactOutput(Context * context) {
|
||||
return m_exactOutput;
|
||||
}
|
||||
|
||||
ExpressionLayout * Calculation::exactOutputLayout(Context * context) {
|
||||
if (m_exactOutputLayout == nullptr && exactOutput(context) != nullptr) {
|
||||
m_exactOutputLayout = exactOutput(context)->createLayout();
|
||||
ExpressionLayout * Calculation::createExactOutputLayout(Context * context) {
|
||||
if (exactOutput(context) != nullptr) {
|
||||
return exactOutput(context)->createLayout();
|
||||
}
|
||||
return m_exactOutputLayout;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Expression * Calculation::approximateOutput(Context * context) {
|
||||
@@ -177,11 +173,11 @@ Expression * Calculation::approximateOutput(Context * context) {
|
||||
return m_approximateOutput;
|
||||
}
|
||||
|
||||
ExpressionLayout * Calculation::approximateOutputLayout(Context * context) {
|
||||
if (m_approximateOutputLayout == nullptr && approximateOutput(context) != nullptr) {
|
||||
m_approximateOutputLayout = approximateOutput(context)->createLayout();
|
||||
ExpressionLayout * Calculation::createApproximateOutputLayout(Context * context) {
|
||||
if (approximateOutput(context) != nullptr) {
|
||||
return approximateOutput(context)->createLayout();
|
||||
}
|
||||
return m_approximateOutputLayout;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool Calculation::shouldOnlyDisplayApproximateOutput(Context * context) {
|
||||
|
||||
@@ -24,15 +24,16 @@ public:
|
||||
/* c.reset() is the equivalent of c = Calculation() without copy assingment. */
|
||||
void reset();
|
||||
void setContent(const char * c, Poincare::Context * context, Poincare::Expression * ansExpression);
|
||||
KDCoordinate height(Poincare::Context * context);
|
||||
const char * inputText();
|
||||
const char * exactOutputText();
|
||||
const char * approximateOutputText();
|
||||
Poincare::Expression * input();
|
||||
Poincare::ExpressionLayout * inputLayout();
|
||||
Poincare::ExpressionLayout * createInputLayout();
|
||||
Poincare::Expression * approximateOutput(Poincare::Context * context);
|
||||
Poincare::Expression * exactOutput(Poincare::Context * context);
|
||||
Poincare::ExpressionLayout * exactOutputLayout(Poincare::Context * context);
|
||||
Poincare::ExpressionLayout * approximateOutputLayout(Poincare::Context * context);
|
||||
Poincare::ExpressionLayout * createExactOutputLayout(Poincare::Context * context);
|
||||
Poincare::ExpressionLayout * createApproximateOutputLayout(Poincare::Context * context);
|
||||
bool isEmpty();
|
||||
void tidy();
|
||||
bool shouldOnlyDisplayApproximateOutput(Poincare::Context * context);
|
||||
@@ -46,11 +47,9 @@ private:
|
||||
char m_exactOutputText[k_printedExpressionSize];
|
||||
char m_approximateOutputText[k_printedExpressionSize];
|
||||
Poincare::Expression * m_input;
|
||||
Poincare::ExpressionLayout * m_inputLayout;
|
||||
Poincare::Expression * m_exactOutput;
|
||||
Poincare::ExpressionLayout * m_exactOutputLayout;
|
||||
Poincare::Expression * m_approximateOutput;
|
||||
Poincare::ExpressionLayout * m_approximateOutputLayout;
|
||||
KDCoordinate m_height;
|
||||
EqualSign m_equalSign;
|
||||
};
|
||||
|
||||
|
||||
@@ -158,17 +158,8 @@ KDCoordinate HistoryController::rowHeight(int j) {
|
||||
return 0;
|
||||
}
|
||||
Calculation * calculation = m_calculationStore->calculationAtIndex(j);
|
||||
KDCoordinate inputHeight = calculation->inputLayout()->size().height();
|
||||
App * calculationApp = (App *)app();
|
||||
Poincare::ExpressionLayout * approximateLayout = calculation->approximateOutputLayout(calculationApp->localContext());
|
||||
KDCoordinate approximateOutputHeight = approximateLayout->size().height();
|
||||
if (calculation->shouldOnlyDisplayApproximateOutput(calculationApp->localContext())) {
|
||||
return inputHeight + approximateOutputHeight + 3*HistoryViewCell::k_digitVerticalMargin;
|
||||
}
|
||||
Poincare::ExpressionLayout * exactLayout = calculation->exactOutputLayout(calculationApp->localContext());
|
||||
KDCoordinate exactOutputHeight = exactLayout->size().height();
|
||||
KDCoordinate outputHeight = max(exactLayout->baseline(), approximateLayout->baseline()) + max(exactOutputHeight-exactLayout->baseline(), approximateOutputHeight-approximateLayout->baseline());
|
||||
return inputHeight + outputHeight + 3*HistoryViewCell::k_digitVerticalMargin;
|
||||
return calculation->height(calculationApp->localContext()) + 3*HistoryViewCell::k_digitVerticalMargin;
|
||||
}
|
||||
|
||||
KDCoordinate HistoryController::cumulatedHeightFromIndex(int j) {
|
||||
|
||||
@@ -9,12 +9,30 @@ namespace Calculation {
|
||||
|
||||
HistoryViewCell::HistoryViewCell(Responder * parentResponder) :
|
||||
Responder(parentResponder),
|
||||
m_inputLayout(nullptr),
|
||||
m_exactOutputLayout(nullptr),
|
||||
m_approximateOutputLayout(nullptr),
|
||||
m_inputView(this),
|
||||
m_scrollableOutputView(this),
|
||||
m_selectedSubviewType(HistoryViewCell::SubviewType::Output)
|
||||
{
|
||||
}
|
||||
|
||||
HistoryViewCell::~HistoryViewCell() {
|
||||
if (m_inputLayout != nullptr) {
|
||||
delete m_inputLayout;
|
||||
m_inputLayout = nullptr;
|
||||
}
|
||||
if (m_exactOutputLayout != nullptr) {
|
||||
delete m_exactOutputLayout;
|
||||
m_exactOutputLayout = nullptr;
|
||||
}
|
||||
if (m_approximateOutputLayout != nullptr) {
|
||||
delete m_approximateOutputLayout;
|
||||
m_approximateOutputLayout = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
OutputExpressionsView * HistoryViewCell::outputView() {
|
||||
return m_scrollableOutputView.outputView();
|
||||
|
||||
@@ -83,12 +101,27 @@ void HistoryViewCell::layoutSubviews() {
|
||||
}
|
||||
|
||||
void HistoryViewCell::setCalculation(Calculation * calculation) {
|
||||
m_inputView.setExpressionLayout(calculation->inputLayout());
|
||||
if (m_inputLayout) {
|
||||
delete m_inputLayout;
|
||||
}
|
||||
m_inputLayout = calculation->createInputLayout();
|
||||
m_inputView.setExpressionLayout(m_inputLayout);
|
||||
App * calculationApp = (App *)app();
|
||||
/* Both output expressions have to be updated at the same time. The
|
||||
* outputView points to deleted layouts and a call to
|
||||
* outputView()->layoutSubviews() is going to fail. */
|
||||
Poincare::ExpressionLayout * outputExpressions[2] = {calculation->approximateOutputLayout(calculationApp->localContext()), calculation->shouldOnlyDisplayApproximateOutput(calculationApp->localContext()) ? nullptr : calculation->exactOutputLayout(calculationApp->localContext())};
|
||||
if (m_exactOutputLayout) {
|
||||
delete m_exactOutputLayout;
|
||||
m_exactOutputLayout = nullptr;
|
||||
}
|
||||
if (!calculation->shouldOnlyDisplayApproximateOutput(calculationApp->localContext())) {
|
||||
m_exactOutputLayout = calculation->createExactOutputLayout(calculationApp->localContext());
|
||||
}
|
||||
if (m_approximateOutputLayout) {
|
||||
delete m_approximateOutputLayout;
|
||||
}
|
||||
m_approximateOutputLayout = calculation->createApproximateOutputLayout(calculationApp->localContext());
|
||||
Poincare::ExpressionLayout * outputExpressions[2] = {m_approximateOutputLayout, m_exactOutputLayout};
|
||||
m_scrollableOutputView.outputView()->setExpressions(outputExpressions);
|
||||
I18n::Message equalMessage = calculation->exactAndApproximateDisplayedOutputsAreEqual(calculationApp->localContext()) == Calculation::EqualSign::Equal ? I18n::Message::Equal : I18n::Message::AlmostEqual;
|
||||
m_scrollableOutputView.outputView()->setEqualMessage(equalMessage);
|
||||
|
||||
@@ -15,6 +15,7 @@ public:
|
||||
Output
|
||||
};
|
||||
HistoryViewCell(Responder * parentResponder);
|
||||
~HistoryViewCell();
|
||||
void reloadCell() override;
|
||||
void reloadScroll();
|
||||
void setEven(bool even) override;
|
||||
@@ -35,6 +36,9 @@ public:
|
||||
OutputExpressionsView * outputView();
|
||||
private:
|
||||
constexpr static KDCoordinate k_resultWidth = 80;
|
||||
Poincare::ExpressionLayout * m_inputLayout;
|
||||
Poincare::ExpressionLayout * m_exactOutputLayout;
|
||||
Poincare::ExpressionLayout * m_approximateOutputLayout;
|
||||
ScrollableExpressionView m_inputView;
|
||||
ScrollableOutputExpressionsView m_scrollableOutputView;
|
||||
SubviewType m_selectedSubviewType;
|
||||
|
||||
Reference in New Issue
Block a user