From 13419f434fb841964e71a1095d2f59002eabbcfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Wed, 19 Dec 2018 15:16:00 +0100 Subject: [PATCH] [apps/shared] Memoize in StorageFuncListCtrl::indexFromCumulatedHeight --- ...storage_expression_model_list_controller.h | 6 ++- .../storage_function_list_controller.cpp | 37 +++++++++++++++++++ .../shared/storage_function_list_controller.h | 1 + 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/apps/shared/storage_expression_model_list_controller.h b/apps/shared/storage_expression_model_list_controller.h index 21116c000..063bcbf73 100644 --- a/apps/shared/storage_expression_model_list_controller.h +++ b/apps/shared/storage_expression_model_list_controller.h @@ -35,14 +35,16 @@ protected: virtual StorageExpressionModelStore * modelStore() = 0; virtual InputViewController * inputController() = 0; EvenOddMessageTextCell m_addNewModel; -private: +protected: // Memoization static constexpr int k_memoizedCellHeightsCount = 5; +private: + // Memoization + static constexpr int k_resetedMemoizedValue = -1; static_assert(StorageExpressionModelListController::k_memoizedCellHeightsCount == 5, "Wrong array size in initialization of StorageExpressionModelListController::m_memoizedCellHeight."); static_assert(StorageExpressionModelListController::k_memoizedCellHeightsCount % 2 == 1, "StorageExpressionModelListController::k_memoizedCellHeightsCount should be odd to be able to compute the middle element."); void resetMemoization(); virtual KDCoordinate notMemoizedCumulatedHeightFromIndex(int j) = 0; - static constexpr int k_resetedMemoizedValue = -1; KDCoordinate m_memoizedCellHeight[k_memoizedCellHeightsCount]; KDCoordinate m_cumulatedHeightForSelectedIndex; }; diff --git a/apps/shared/storage_function_list_controller.cpp b/apps/shared/storage_function_list_controller.cpp index a555a4c76..d15d10f8f 100644 --- a/apps/shared/storage_function_list_controller.cpp +++ b/apps/shared/storage_function_list_controller.cpp @@ -4,6 +4,7 @@ namespace Shared { static inline int max(int x, int y) { return x > y ? x : y; } +static inline int min(int x, int y) { return x < y ? x : y; } StorageFunctionListController::StorageFunctionListController(Responder * parentResponder, ButtonRowController * header, ButtonRowController * footer, I18n::Message text) : StorageExpressionModelListController(parentResponder, text), @@ -81,6 +82,42 @@ int StorageFunctionListController::indexFromCumulatedWidth(KDCoordinate offsetX) } } +int StorageFunctionListController::indexFromCumulatedHeight(KDCoordinate offsetY) { + if (offsetY == 0) { + return 0; + } + + /* We use memoization to speed up this method: if offsetY is "around" the + * memoized cumulatedHeightForIndex, we can compute its value easily by + * adding/substracting memoized row heights. */ + + int currentSelectedRow = selectedRow(); + int rowsCount = numberOfRows(); + if (rowsCount <= 1 || currentSelectedRow < 1) { + return TableViewDataSource::indexFromCumulatedHeight(offsetY); + } + + KDCoordinate currentCumulatedHeight = cumulatedHeightFromIndex(currentSelectedRow); + if (offsetY > currentCumulatedHeight) { + int iMax = min(k_memoizedCellHeightsCount/2 + 1, rowsCount - currentSelectedRow); + for (int i = 0; i < iMax; i++) { + currentCumulatedHeight+= rowHeight(currentSelectedRow + i); + if (offsetY <= currentCumulatedHeight) { + return currentSelectedRow + i; + } + } + } else { + int iMax = min(k_memoizedCellHeightsCount/2, currentSelectedRow); + for (int i = 1; i <= iMax; i++) { + currentCumulatedHeight-= rowHeight(currentSelectedRow-i); + if (offsetY > currentCumulatedHeight) { + return currentSelectedRow - i; + } + } + } + return TableViewDataSource::indexFromCumulatedHeight(offsetY); +} + int StorageFunctionListController::typeAtLocation(int i, int j) { if (isAddEmptyRow(j)){ return i + 2; diff --git a/apps/shared/storage_function_list_controller.h b/apps/shared/storage_function_list_controller.h index c47644ad1..c8e21fb30 100644 --- a/apps/shared/storage_function_list_controller.h +++ b/apps/shared/storage_function_list_controller.h @@ -26,6 +26,7 @@ public: KDCoordinate cumulatedWidthFromIndex(int i) override; KDCoordinate cumulatedHeightFromIndex(int j) override; int indexFromCumulatedWidth(KDCoordinate offsetX) override; + int indexFromCumulatedHeight(KDCoordinate offsetY) override; int typeAtLocation(int i, int j) override; HighlightCell * reusableCell(int index, int type) override; int reusableCellCount(int type) override;