From fd56d936c7e8815a15632dbd4ecdb815472c8048 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Thu, 20 Sep 2018 11:06:31 +0200 Subject: [PATCH] [apps] Memoize matrix layouts in VariableBoxController --- apps/variable_box_controller.cpp | 53 ++++++++++++---------- apps/variable_box_controller.h | 4 +- poincare/include/poincare/global_context.h | 1 - poincare/include/poincare/grid_layout.h | 4 ++ poincare/src/global_context.cpp | 10 ---- 5 files changed, 35 insertions(+), 37 deletions(-) diff --git a/apps/variable_box_controller.cpp b/apps/variable_box_controller.cpp index 982f71729..1ef4b0ba7 100644 --- a/apps/variable_box_controller.cpp +++ b/apps/variable_box_controller.cpp @@ -84,6 +84,7 @@ bool VariableBoxController::ContentViewController::handleEvent(Ion::Events::Even if (m_currentPage == Page::Matrix) { const Symbol symbol = Symbol::matrixSymbol('0'+(char)selectedRow()); m_context->setExpressionForSymbolName(Expression(), symbol, *m_context); + m_matrixLayouts[selectedRow()] = Layout(); } m_selectableTableView.reloadData(); return true; @@ -138,29 +139,29 @@ void VariableBoxController::ContentViewController::willDisplayCellForIndex(Highl char label[3]; putLabelAtIndexInBuffer(index, label); myCell->setLabel(label); - const Expression evaluation = expressionForIndex(index); if (m_currentPage == Page::Scalar) { myCell->displayExpression(false); + const Expression evaluation = expressionForIndex(index); char buffer[PrintFloat::k_maxComplexBufferLength]; PoincareHelpers::Serialize(evaluation, buffer, PrintFloat::k_maxComplexBufferLength, Constant::ShortNumberOfSignificantDigits); myCell->setSubtitle(buffer); return; } + assert(m_currentPage == Page::Matrix); myCell->displayExpression(true); - if (!evaluation.isUninitialized()) { - /* TODO: implement list contexts */ - // TODO: handle matrix and scalar! - Layout layoutR = layoutForIndex(index); - const Matrix matrixEvaluation = static_cast(evaluation); - myCell->setLayout(layoutR); - char buffer[2*PrintFloat::bufferSizeForFloatsWithPrecision(2)+1]; - int numberOfChars = PrintFloat::convertFloatToText(matrixEvaluation.numberOfRows(), buffer, PrintFloat::bufferSizeForFloatsWithPrecision(2), 2, Preferences::PrintFloatMode::Decimal); - buffer[numberOfChars++] = 'x'; - PrintFloat::convertFloatToText(matrixEvaluation.numberOfColumns(), buffer+numberOfChars, PrintFloat::bufferSizeForFloatsWithPrecision(2), 2, Preferences::PrintFloatMode::Decimal); - myCell->setSubtitle(buffer); - } else { - myCell->setLayout(Layout()); + /* TODO: implement list contexts */ + // TODO: handle matrix and scalar! + Layout layoutR = matrixLayoutAtIndex(index); + myCell->setLayout(layoutR); + if (layoutR.isUninitialized()) { myCell->setSubtitle(I18n::translate(I18n::Message::Empty)); + } else { + char buffer[2*PrintFloat::bufferSizeForFloatsWithPrecision(2)+1]; + MatrixLayout matrixLayout = static_cast(layoutR); + int numberOfChars = PrintFloat::convertFloatToText(matrixLayout.numberOfRows(), buffer, PrintFloat::bufferSizeForFloatsWithPrecision(2), 2, Preferences::PrintFloatMode::Decimal); + buffer[numberOfChars++] = 'x'; + PrintFloat::convertFloatToText(matrixLayout.numberOfColumns(), buffer+numberOfChars, PrintFloat::bufferSizeForFloatsWithPrecision(2), 2, Preferences::PrintFloatMode::Decimal); + myCell->setSubtitle(buffer); } } @@ -168,7 +169,7 @@ KDCoordinate VariableBoxController::ContentViewController::rowHeight(int index) if (m_currentPage == Page::RootMenu || m_currentPage == Page::Scalar) { return Metric::ToolboxRowHeight; } - Layout layoutR = layoutForIndex(index); + Layout layoutR = matrixLayoutAtIndex(index); if (!layoutR.isUninitialized()) { return max(layoutR.layoutSize().height()+k_leafMargin, Metric::ToolboxRowHeight); } @@ -196,6 +197,10 @@ void VariableBoxController::ContentViewController::resetPage() { void VariableBoxController::ContentViewController::viewDidDisappear() { m_selectableTableView.deselectTable(); + // Tidy the memoized layouts to clean TreePool + for (int i = 0; i < GlobalContext::k_maxNumberOfMatrixExpressions; i++) { + m_matrixLayouts[i] = Layout(); + } // Tidy the layouts used to display the VariableBoxController to clean TreePool for (int i = 0; i < k_maxNumberOfDisplayedRows; i++) { m_leafCells[i].setLayout(Layout()); @@ -258,17 +263,15 @@ const Expression VariableBoxController::ContentViewController::expressionForInde return Expression(); } -Layout VariableBoxController::ContentViewController::layoutForIndex(int index) { - if (m_currentPage == Page::Matrix) { - const Symbol symbol = Symbol::matrixSymbol('0'+(char)index); - return m_context->layoutForSymbol(symbol, Constant::ShortNumberOfSignificantDigits); +Layout VariableBoxController::ContentViewController::matrixLayoutAtIndex(int index) { + assert(m_currentPage == Page::Matrix); + if (m_matrixLayouts[index].isUninitialized()) { + const Expression evaluation = expressionForIndex(index); + if (!evaluation.isUninitialized()) { + m_matrixLayouts[index] = evaluation.createLayout(Poincare::Preferences::sharedPreferences()->displayMode(), Constant::ShortNumberOfSignificantDigits); + } } -#if LIST_VARIABLES - if (m_currentPage == Page::List) { - return Layout(); - } -#endif - return Layout(); + return m_matrixLayouts[index]; } VariableBoxController::VariableBoxController(GlobalContext * context) : diff --git a/apps/variable_box_controller.h b/apps/variable_box_controller.h index 77580d4db..e24f0b964 100644 --- a/apps/variable_box_controller.h +++ b/apps/variable_box_controller.h @@ -53,7 +53,7 @@ private: void putLabelAtIndexInBuffer(int index, char * buffer); I18n::Message nodeLabelAtIndex(int index); const Poincare::Expression expressionForIndex(int index); - Poincare::Layout layoutForIndex(int index); + Poincare::Layout matrixLayoutAtIndex(int index); Poincare::GlobalContext * m_context; Responder * m_sender; int m_firstSelectedRow; @@ -61,6 +61,8 @@ private: Page m_currentPage; VariableBoxLeafCell m_leafCells[k_maxNumberOfDisplayedRows]; MessageTableCellWithChevron m_nodeCells[k_numberOfMenuRows]; + // Matrix layout memoization + Poincare::Layout m_matrixLayouts[Poincare::GlobalContext::k_maxNumberOfMatrixExpressions]; SelectableTableView m_selectableTableView; }; ContentViewController m_contentViewController; diff --git a/poincare/include/poincare/global_context.h b/poincare/include/poincare/global_context.h index e9200ea97..86bffd46d 100644 --- a/poincare/include/poincare/global_context.h +++ b/poincare/include/poincare/global_context.h @@ -18,7 +18,6 @@ public: /* The expression recorded in global context is already a expression. * Otherwise, we would need the context and the angle unit to evaluate it */ const Expression expressionForSymbol(const Symbol & symbol) override; - Layout layoutForSymbol(const Symbol & symbol, int numberOfSignificantDigits); void setExpressionForSymbolName(const Expression & expression, const Symbol & symbol, Context & context) override; static constexpr uint16_t k_maxNumberOfScalarExpressions = 26; //static constexpr uint16_t k_maxNumberOfListExpressions = 10; diff --git a/poincare/include/poincare/grid_layout.h b/poincare/include/poincare/grid_layout.h index d067a536a..562928911 100644 --- a/poincare/include/poincare/grid_layout.h +++ b/poincare/include/poincare/grid_layout.h @@ -22,6 +22,8 @@ public: m_numberOfColumns(0) {} + int numberOfRows() const { return m_numberOfRows; } + int numberOfColumns() const { return m_numberOfColumns; } virtual void setNumberOfRows(int numberOfRows) { m_numberOfRows = numberOfRows; } virtual void setNumberOfColumns(int numberOfColumns) { m_numberOfColumns = numberOfColumns; } KDSize gridSize() const { return KDSize(width(), height()); } @@ -92,6 +94,8 @@ public: void addChildAtIndex(Layout l, int index, int currentNumberOfChildren, LayoutCursor * cursor) { Layout::addChildAtIndex(l, index, currentNumberOfChildren, cursor); } + int numberOfRows() const { return node()->numberOfRows(); } + int numberOfColumns() const { return node()->numberOfColumns(); } private: virtual GridLayoutNode * node() const { return static_cast(Layout::node()); } void setNumberOfRows(int rows) { diff --git a/poincare/src/global_context.cpp b/poincare/src/global_context.cpp index 175152be7..bd43d8fc6 100644 --- a/poincare/src/global_context.cpp +++ b/poincare/src/global_context.cpp @@ -38,16 +38,6 @@ const Expression GlobalContext::expressionForSymbol(const Symbol & symbol) { return Expression(static_cast(TreePool::sharedPool()->copyTreeFromAddress(record.value().buffer, record.value().size))); } -Layout GlobalContext::layoutForSymbol(const Symbol & symbol, int numberOfSignificantDigits) { - if (Symbol::isMatrixSymbol(symbol.name())) { - Expression e = expressionForSymbol(symbol); - if (!e.isUninitialized()) { - return e.createLayout(Preferences::PrintFloatMode::Decimal, numberOfSignificantDigits); - } - } - return Layout(); -} - void GlobalContext::setExpressionForSymbolName(const Expression & expression, const Symbol & symbol, Context & context) { // Initiate Record features FileName symbolFileName = fileNameForSymbol(symbol);