diff --git a/apps/regression/regression_context.cpp b/apps/regression/regression_context.cpp index 89070e89a..6499e64fc 100644 --- a/apps/regression/regression_context.cpp +++ b/apps/regression/regression_context.cpp @@ -8,10 +8,6 @@ using namespace Shared; namespace Regression { -void RegressionContext::setExpressionForSymbolName(const Expression * expression, const Symbol * symbol, Context & context) { - m_parentContext->setExpressionForSymbolName(expression, symbol, context); -} - const Expression * RegressionContext::expressionForSymbol(const Symbol * symbol) { if (Symbol::isRegressionSymbol(symbol->name())) { const char * seriesName = Symbol::textForSpecialSymbols(symbol->name()); diff --git a/apps/regression/regression_context.h b/apps/regression/regression_context.h index 966b63a0b..1d9543103 100644 --- a/apps/regression/regression_context.h +++ b/apps/regression/regression_context.h @@ -2,25 +2,14 @@ #define REGRESSION_REGRESSION_CONTEXT_H #include -#include "../shared/double_pair_store.h" +#include "../shared/store_context.h" namespace Regression { -class RegressionContext : public Poincare::Context { +class RegressionContext : public Shared::StoreContext { public: - RegressionContext(Shared::DoublePairStore * store, Poincare::Context * parentContext = nullptr) : - Poincare::Context(), - m_store(store), - m_seriesPairIndex(-1), - m_parentContext(parentContext) - {} - void setSeriesPairIndex(int j) { m_seriesPairIndex = j; } - void setExpressionForSymbolName(const Poincare::Expression * expression, const Poincare::Symbol * symbol, Poincare::Context & context) override; + using Shared::StoreContext::StoreContext; const Poincare::Expression * expressionForSymbol(const Poincare::Symbol * symbol) override; -private: - Shared::DoublePairStore * m_store; - int m_seriesPairIndex; - Poincare::Context * m_parentContext; }; } diff --git a/apps/regression/store_controller.cpp b/apps/regression/store_controller.cpp index 70e822e51..91e143495 100644 --- a/apps/regression/store_controller.cpp +++ b/apps/regression/store_controller.cpp @@ -15,10 +15,16 @@ namespace Regression { StoreController::StoreController(Responder * parentResponder, Store * store, ButtonRowController * header) : Shared::StoreController(parentResponder, store, header), - m_titleCells{} + m_titleCells{}, + m_regressionContext(store) { } +StoreContext * StoreController::storeContext() { + m_regressionContext.setParentContext(const_cast(static_cast(app()->container()))->globalContext()); + return &m_regressionContext; +} + void StoreController::setFormulaLabel() { int series = selectedColumn() / Store::k_numberOfColumnsPerSeries; int isXColumn = selectedColumn() % Store::k_numberOfColumnsPerSeries == 0; @@ -27,37 +33,7 @@ void StoreController::setFormulaLabel() { } void StoreController::fillColumnWithFormula(Expression * formula) { - int currentColumn = selectedColumn(); - // Fetch the series used in the formula to compute the size of the filled in series - char variables[7] = {0, 0, 0, 0, 0, 0, 0}; - formula->getVariables(Symbol::isRegressionSymbol, variables); - int numberOfValuesToCompute = -1; - int index = 0; - while (variables[index] != 0) { - const char * seriesName = Symbol::textForSpecialSymbols(variables[index]); - assert(strlen(seriesName) == 2); - int series = (int)(seriesName[1] - '0') - 1; - assert(series >= 0 && series < DoublePairStore::k_numberOfSeries); - if (numberOfValuesToCompute == -1) { - numberOfValuesToCompute = m_store->numberOfPairsOfSeries(series); - } else { - numberOfValuesToCompute = min(numberOfValuesToCompute, m_store->numberOfPairsOfSeries(series)); - } - index++; - } - if (numberOfValuesToCompute == -1) { - numberOfValuesToCompute = m_store->numberOfPairsOfSeries(selectedColumn()/DoublePairStore::k_numberOfColumnsPerSeries); - } - - RegressionContext regressionContext(m_store, const_cast(static_cast(app()->container()))->globalContext()); - for (int j = 0; j < numberOfValuesToCompute; j++) { - // Set the context - regressionContext.setSeriesPairIndex(j); - // Compute the new value using the formula - double evaluation = formula->approximateToScalar(regressionContext); - setDataAtLocation(evaluation, currentColumn, j + 1); - } - selectableTableView()->reloadData(); + privateFillColumnWithFormula(formula, Symbol::isRegressionSymbol); } void StoreController::willDisplayCellAtLocation(HighlightCell * cell, int i, int j) { diff --git a/apps/regression/store_controller.h b/apps/regression/store_controller.h index efbb25326..a009b3557 100644 --- a/apps/regression/store_controller.h +++ b/apps/regression/store_controller.h @@ -3,6 +3,7 @@ #include #include "store.h" +#include "regression_context.h" #include "../shared/store_controller.h" #include "../shared/store_title_cell.h" @@ -11,6 +12,7 @@ namespace Regression { class StoreController : public Shared::StoreController { public: StoreController(Responder * parentResponder, Store * store, ButtonRowController * header); + Shared::StoreContext * storeContext() override; void setFormulaLabel() override; void fillColumnWithFormula(Poincare::Expression * formula) override; void willDisplayCellAtLocation(HighlightCell * cell, int i, int j) override; @@ -19,6 +21,7 @@ private: View * loadView() override; void unloadView(View * view) override; Shared::StoreTitleCell * m_titleCells[k_numberOfTitleCells]; + RegressionContext m_regressionContext; }; } diff --git a/apps/shared/Makefile b/apps/shared/Makefile index 3242b58ae..aa878289a 100644 --- a/apps/shared/Makefile +++ b/apps/shared/Makefile @@ -46,6 +46,7 @@ app_objs += $(addprefix apps/shared/,\ separator_even_odd_buffer_text_cell.o\ simple_interactive_curve_view_controller.o\ store_cell.o\ + store_context.o\ store_controller.o\ store_parameter_controller.o\ store_selectable_table_view.o\ diff --git a/apps/shared/store_context.cpp b/apps/shared/store_context.cpp new file mode 100644 index 000000000..db4dd28bf --- /dev/null +++ b/apps/shared/store_context.cpp @@ -0,0 +1,14 @@ +#include "store_context.h" +#include +#include +#include + +using namespace Poincare; + +namespace Shared { + +void StoreContext::setExpressionForSymbolName(const Expression * expression, const Symbol * symbol, Context & context) { + m_parentContext->setExpressionForSymbolName(expression, symbol, context); +} + +} diff --git a/apps/shared/store_context.h b/apps/shared/store_context.h new file mode 100644 index 000000000..7b0513fb7 --- /dev/null +++ b/apps/shared/store_context.h @@ -0,0 +1,28 @@ +#ifndef SHARED_STORE_CONTEXT_H +#define SHARED_STORE_CONTEXT_H + +#include +#include "double_pair_store.h" + +namespace Shared { + +class StoreContext : public Poincare::Context { +public: + StoreContext(Shared::DoublePairStore * store) : + Poincare::Context(), + m_store(store), + m_seriesPairIndex(-1), + m_parentContext(nullptr) + {} + void setParentContext(Poincare::Context * parentContext) { m_parentContext = parentContext; } + void setSeriesPairIndex(int j) { m_seriesPairIndex = j; } + void setExpressionForSymbolName(const Poincare::Expression * expression, const Poincare::Symbol * symbol, Poincare::Context & context) override; +protected: + Shared::DoublePairStore * m_store; + int m_seriesPairIndex; + Poincare::Context * m_parentContext; +}; + +} + +#endif diff --git a/apps/shared/store_controller.cpp b/apps/shared/store_controller.cpp index a977cf2c7..d5e333b5c 100644 --- a/apps/shared/store_controller.cpp +++ b/apps/shared/store_controller.cpp @@ -268,6 +268,40 @@ void StoreController::unloadView(View * view) { delete view; } +void StoreController::privateFillColumnWithFormula(Expression * formula, Expression::isVariableTest isVariable) { + int currentColumn = selectedColumn(); + // Fetch the series used in the formula to compute the size of the filled in series + char variables[7] = {0, 0, 0, 0, 0, 0, 0}; + formula->getVariables(isVariable, variables); + int numberOfValuesToCompute = -1; + int index = 0; + while (variables[index] != 0) { + const char * seriesName = Symbol::textForSpecialSymbols(variables[index]); + assert(strlen(seriesName) == 2); + int series = (int)(seriesName[1] - '0') - 1; + assert(series >= 0 && series < DoublePairStore::k_numberOfSeries); + if (numberOfValuesToCompute == -1) { + numberOfValuesToCompute = m_store->numberOfPairsOfSeries(series); + } else { + numberOfValuesToCompute = min(numberOfValuesToCompute, m_store->numberOfPairsOfSeries(series)); + } + index++; + } + if (numberOfValuesToCompute == -1) { + numberOfValuesToCompute = m_store->numberOfPairsOfSeries(selectedColumn()/DoublePairStore::k_numberOfColumnsPerSeries); + } + + StoreContext * store = storeContext(); + for (int j = 0; j < numberOfValuesToCompute; j++) { + // Set the context + store->setSeriesPairIndex(j); + // Compute the new value using the formula + double evaluation = formula->approximateToScalar(*store); + setDataAtLocation(evaluation, currentColumn, j + 1); + } + selectableTableView()->reloadData(); +} + bool StoreController::cellShouldBeTransparent(int i, int j) { int seriesIndex = i/DoublePairStore::k_numberOfColumnsPerSeries; return j > 1 + m_store->numberOfPairsOfSeries(seriesIndex); diff --git a/apps/shared/store_controller.h b/apps/shared/store_controller.h index 233520df7..f478a921e 100644 --- a/apps/shared/store_controller.h +++ b/apps/shared/store_controller.h @@ -6,6 +6,7 @@ #include "editable_cell_table_view_controller.h" #include "double_pair_store.h" #include "store_cell.h" +#include "store_context.h" #include "store_parameter_controller.h" #include "store_selectable_table_view.h" @@ -15,6 +16,7 @@ class StoreController : public EditableCellTableViewController, public ButtonRow public: StoreController(Responder * parentResponder, DoublePairStore * store, ButtonRowController * header); + virtual StoreContext * storeContext() = 0; void displayFormulaInput(); virtual void setFormulaLabel() = 0; virtual void fillColumnWithFormula(Poincare::Expression * formula) = 0; @@ -83,6 +85,7 @@ protected: virtual HighlightCell * titleCells(int index) = 0; char m_draftTextBuffer[TextField::maxBufferSize()]; int seriesAtColumn(int column) const { return column / DoublePairStore::k_numberOfColumnsPerSeries; } + void privateFillColumnWithFormula(Poincare::Expression * formula, Poincare::Expression::isVariableTest isVariable); StoreCell * m_editableCells[k_maxNumberOfEditableCells]; DoublePairStore * m_store; StoreParameterController m_storeParameterController; diff --git a/apps/statistics/statistics_context.cpp b/apps/statistics/statistics_context.cpp index e8fecc66e..301345d7c 100644 --- a/apps/statistics/statistics_context.cpp +++ b/apps/statistics/statistics_context.cpp @@ -8,10 +8,6 @@ using namespace Shared; namespace Statistics { -void StatisticsContext::setExpressionForSymbolName(const Expression * expression, const Symbol * symbol, Context & context) { - m_parentContext->setExpressionForSymbolName(expression, symbol, context); -} - const Expression * StatisticsContext::expressionForSymbol(const Symbol * symbol) { if (Symbol::isSeriesSymbol(symbol->name())) { const char * seriesName = Symbol::textForSpecialSymbols(symbol->name()); diff --git a/apps/statistics/statistics_context.h b/apps/statistics/statistics_context.h index fde874032..6263bf4fd 100644 --- a/apps/statistics/statistics_context.h +++ b/apps/statistics/statistics_context.h @@ -1,26 +1,14 @@ #ifndef STATISTICS_STATISTICS_CONTEXT_H #define STATISTICS_STATISTICS_CONTEXT_H -#include -#include "../shared/double_pair_store.h" +#include "../shared/store_context.h" namespace Statistics { -class StatisticsContext : public Poincare::Context { +class StatisticsContext : public Shared::StoreContext { public: - StatisticsContext(Shared::DoublePairStore * store, Poincare::Context * parentContext = nullptr) : - Poincare::Context(), - m_store(store), - m_seriesPairIndex(-1), - m_parentContext(parentContext) - {} - void setSeriesPairIndex(int j) { m_seriesPairIndex = j; } - void setExpressionForSymbolName(const Poincare::Expression * expression, const Poincare::Symbol * symbol, Poincare::Context & context) override; + using Shared::StoreContext::StoreContext; const Poincare::Expression * expressionForSymbol(const Poincare::Symbol * symbol) override; -private: - Shared::DoublePairStore * m_store; - int m_seriesPairIndex; - Poincare::Context * m_parentContext; }; } diff --git a/apps/statistics/store_controller.cpp b/apps/statistics/store_controller.cpp index c346f91bc..e57d95913 100644 --- a/apps/statistics/store_controller.cpp +++ b/apps/statistics/store_controller.cpp @@ -15,10 +15,16 @@ namespace Statistics { StoreController::StoreController(Responder * parentResponder, Store * store, ButtonRowController * header) : Shared::StoreController(parentResponder, store, header), m_titleCells{}, - m_store(store) + m_store(store), + m_statisticsContext(m_store) { } +StoreContext * StoreController::storeContext() { + m_statisticsContext.setParentContext(const_cast(static_cast(app()->container()))->globalContext()); + return &m_statisticsContext; +} + void StoreController::setFormulaLabel() { int series = selectedColumn() / Store::k_numberOfColumnsPerSeries; int isValueColumn = selectedColumn() % Store::k_numberOfColumnsPerSeries == 0; @@ -27,37 +33,7 @@ void StoreController::setFormulaLabel() { } void StoreController::fillColumnWithFormula(Expression * formula) { - int currentColumn = selectedColumn(); - // Fetch the series used in the formula to compute the size of the filled in series - char variables[7] = {0, 0, 0, 0, 0, 0, 0}; - formula->getVariables(Symbol::isSeriesSymbol, variables); - int numberOfValuesToCompute = -1; - int index = 0; - while (variables[index] != 0) { - const char * seriesName = Symbol::textForSpecialSymbols(variables[index]); - assert(strlen(seriesName) == 2); - int series = (int)(seriesName[1] - '0') - 1; - assert(series >= 0 && series < DoublePairStore::k_numberOfSeries); - if (numberOfValuesToCompute == -1) { - numberOfValuesToCompute = m_store->numberOfPairsOfSeries(series); - } else { - numberOfValuesToCompute = min(numberOfValuesToCompute, m_store->numberOfPairsOfSeries(series)); - } - index++; - } - if (numberOfValuesToCompute == -1) { - numberOfValuesToCompute = m_store->numberOfPairsOfSeries(selectedColumn()/DoublePairStore::k_numberOfColumnsPerSeries); - } - - StatisticsContext seriesContext(m_store, const_cast(static_cast(app()->container()))->globalContext()); - for (int j = 0; j < numberOfValuesToCompute; j++) { - // Set the context - seriesContext.setSeriesPairIndex(j); - // Compute the new value using the formula - double evaluation = formula->approximateToScalar(seriesContext); - setDataAtLocation(evaluation, currentColumn, j + 1); - } - selectableTableView()->reloadData(); + privateFillColumnWithFormula(formula, Symbol::isSeriesSymbol); } void StoreController::willDisplayCellAtLocation(HighlightCell * cell, int i, int j) { diff --git a/apps/statistics/store_controller.h b/apps/statistics/store_controller.h index 9e81df313..e744e885d 100644 --- a/apps/statistics/store_controller.h +++ b/apps/statistics/store_controller.h @@ -3,6 +3,7 @@ #include #include "store.h" +#include "statistics_context.h" #include "../shared/store_controller.h" #include "../shared/store_title_cell.h" @@ -11,6 +12,7 @@ namespace Statistics { class StoreController : public Shared::StoreController { public: StoreController(Responder * parentResponder, Store * store, ButtonRowController * header); + Shared::StoreContext * storeContext() override; void setFormulaLabel() override; void fillColumnWithFormula(Poincare::Expression * formula) override; void willDisplayCellAtLocation(HighlightCell * cell, int i, int j) override; @@ -21,6 +23,7 @@ private: void unloadView(View * view) override; Shared::StoreTitleCell * m_titleCells[k_numberOfTitleCells]; Store * m_store; + StatisticsContext m_statisticsContext; }; }