mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-18 16:27:34 +01:00
[apps/calculation] Raise exception if row height miscomputed
Scenario: Put the complex mode to exponential, then go back to Calculation and: Toolbox, Down, Down, Down, Down, OK, OK, Two, Plus, Imaginary, Toolbox, Down, Down, Down, Down, OK, Down, OK, Two, Plus, Imaginary, OK, Toolbox, Down, Down, Down, Down, Down, OK, Down, OK, Up, OK, Right, Zero, OK, OK, Toolbox, Down, Down, OK, Toolbox, Back, Up, Zero, Up, OK, Zero, Up, Up, Up
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
#include "history_controller.h"
|
||||
#include "app.h"
|
||||
#include <poincare/exception_checkpoint.h>
|
||||
#include <assert.h>
|
||||
|
||||
using namespace Shared;
|
||||
@@ -206,6 +207,10 @@ KDCoordinate HistoryController::rowHeight(int j) {
|
||||
KDCoordinate result = calculation->memoizedHeight(expanded);
|
||||
if (result < 0) {
|
||||
result = HistoryViewCell::Height(calculation.pointer(), expanded);
|
||||
if (result < 0) {
|
||||
// Raise, because Height modified the calculation and failed.
|
||||
Poincare::ExceptionCheckpoint::Raise();
|
||||
}
|
||||
calculation->setMemoizedHeight(expanded, result);
|
||||
}
|
||||
/* We might want to put an assertion here to check the memoization:
|
||||
|
||||
@@ -36,7 +36,16 @@ void HistoryViewCellDataSource::setSelectedSubviewType(SubviewType subviewType,
|
||||
|
||||
KDCoordinate HistoryViewCell::Height(Calculation * calculation, bool expanded) {
|
||||
HistoryViewCell cell(nullptr);
|
||||
cell.setCalculation(calculation, expanded);
|
||||
bool didForceOutput = false;
|
||||
cell.setCalculation(calculation, expanded, &didForceOutput);
|
||||
if (didForceOutput) {
|
||||
/* We could not compute the height of the calculation as it is (the display
|
||||
* output was forced to another value during the height computation).
|
||||
* Warning: the display output of calculation was actually changed, so it
|
||||
* will cause problems if we already did some computations with another
|
||||
* display value. */
|
||||
return -1;
|
||||
}
|
||||
KDRect ellipsisFrame = KDRectZero;
|
||||
KDRect inputFrame = KDRectZero;
|
||||
KDRect outputFrame = KDRectZero;
|
||||
@@ -237,7 +246,8 @@ void HistoryViewCell::resetMemoization() {
|
||||
m_calculationCRC32 = 0;
|
||||
}
|
||||
|
||||
void HistoryViewCell::setCalculation(Calculation * calculation, bool expanded) {
|
||||
void HistoryViewCell::setCalculation(Calculation * calculation, bool expanded, bool * didForceOutput) {
|
||||
assert(!didForceOutput || *didForceOutput == false);
|
||||
uint32_t newCalculationCRC = Ion::crc32Byte((const uint8_t *)calculation, ((char *)calculation->next()) - ((char *) calculation));
|
||||
if (newCalculationCRC == m_calculationCRC32 && m_calculationExpanded == expanded) {
|
||||
return;
|
||||
@@ -265,6 +275,9 @@ void HistoryViewCell::setCalculation(Calculation * calculation, bool expanded) {
|
||||
if (couldNotCreateExactLayout) {
|
||||
if (calculation->displayOutput(context) != ::Calculation::Calculation::DisplayOutput::ExactOnly) {
|
||||
calculation->forceDisplayOutput(::Calculation::Calculation::DisplayOutput::ApproximateOnly);
|
||||
if (didForceOutput) {
|
||||
*didForceOutput = true;
|
||||
}
|
||||
} else {
|
||||
/* We should only display the exact result, but we cannot create it
|
||||
* -> raise an exception. */
|
||||
@@ -287,6 +300,9 @@ void HistoryViewCell::setCalculation(Calculation * calculation, bool expanded) {
|
||||
/* Set the display output to ApproximateOnly, make room in the pool by
|
||||
* erasing the exact layout, and retry to create the approximate layout */
|
||||
calculation->forceDisplayOutput(::Calculation::Calculation::DisplayOutput::ApproximateOnly);
|
||||
if (didForceOutput) {
|
||||
*didForceOutput = true;
|
||||
}
|
||||
exactOutputLayout = Poincare::Layout();
|
||||
couldNotCreateApproximateLayout = false;
|
||||
approximateOutputLayout = calculation->createApproximateOutputLayout(context, &couldNotCreateApproximateLayout);
|
||||
|
||||
@@ -51,7 +51,7 @@ public:
|
||||
Poincare::Layout layout() const override;
|
||||
KDColor backgroundColor() const override { return m_even ? KDColorWhite : Palette::WallScreen; }
|
||||
void resetMemoization();
|
||||
void setCalculation(Calculation * calculation, bool expanded);
|
||||
void setCalculation(Calculation * calculation, bool expanded, bool * didForceOutput = nullptr);
|
||||
int numberOfSubviews() const override { return 2 + displayedEllipsis(); }
|
||||
View * subviewAtIndex(int index) override;
|
||||
void layoutSubviews(bool force = false) override;
|
||||
|
||||
Reference in New Issue
Block a user