diff --git a/apps/graph/list/type_parameter_controller.cpp b/apps/graph/list/type_parameter_controller.cpp index 93f4e6143..13a4ecb2e 100644 --- a/apps/graph/list/type_parameter_controller.cpp +++ b/apps/graph/list/type_parameter_controller.cpp @@ -24,7 +24,7 @@ bool TypeParameterController::handleEvent(Ion::Events::Event event) { App * myApp = App::app(); assert(!m_record.isNull()); Shared::ExpiringPointer function = myApp->functionStore()->modelForRecord(m_record); - function->setPlotType(plotType, Poincare::Preferences::sharedPreferences()->angleUnit()); + function->setPlotType(plotType, Poincare::Preferences::sharedPreferences()->angleUnit(), myApp->localContext()); StackViewController * stack = stackController(); stack->pop(); stack->pop(); diff --git a/apps/sequence/list/list_controller.cpp b/apps/sequence/list/list_controller.cpp index d3a491475..96ad9b5b1 100644 --- a/apps/sequence/list/list_controller.cpp +++ b/apps/sequence/list/list_controller.cpp @@ -149,7 +149,8 @@ bool ListController::editInitialConditionOfSelectedRecordWithText(const char * t resetMemoizationForIndex(k_memoizedCellsCount/2); Ion::Storage::Record record = modelStore()->recordAtIndex(modelIndexForRow(selectedRow())); Sequence * sequence = modelStore()->modelForRecord(record); - Ion::Storage::Record::ErrorStatus error = firstInitialCondition? sequence->setFirstInitialConditionContent(text) : sequence->setSecondInitialConditionContent(text); + Context * context = App::app()->localContext(); + Ion::Storage::Record::ErrorStatus error = firstInitialCondition? sequence->setFirstInitialConditionContent(text, context) : sequence->setSecondInitialConditionContent(text, context); return (error == Ion::Storage::Record::ErrorStatus::None); } @@ -265,19 +266,19 @@ void ListController::reinitSelectedExpression(ExpiringPointerfirstInitialConditionExpressionClone().isUninitialized()) { return; } - sequence->setFirstInitialConditionContent(""); + sequence->setFirstInitialConditionContent("", nullptr); // No context needed here break; case 2: if (sequence->secondInitialConditionExpressionClone().isUninitialized()) { return; } - sequence->setSecondInitialConditionContent(""); + sequence->setSecondInitialConditionContent("", nullptr); // No context needed here break; default: if (sequence->expressionClone().isUninitialized()) { return; } - sequence->setContent(""); + sequence->setContent("", nullptr); // No context needed break; } selectableTableView()->reloadData(); diff --git a/apps/sequence/sequence.cpp b/apps/sequence/sequence.cpp index 71448682e..e97f8d390 100644 --- a/apps/sequence/sequence.cpp +++ b/apps/sequence/sequence.cpp @@ -51,13 +51,13 @@ void Sequence::setType(Type t) { /* Reset all contents */ switch (t) { case Type::Explicit: - setContent(""); + setContent("", nullptr); // No context needed here break; case Type::SingleRecurrence: { char ex[5] = "u(n)"; ex[0] = fullName()[0]; - setContent(ex); + setContent(ex, nullptr); // No context needed here break; } case Type::DoubleRecurrence: @@ -66,12 +66,12 @@ void Sequence::setType(Type t) { char name = fullName()[0]; ex[0] = name; ex[7] = name; - setContent(ex); + setContent(ex, nullptr); // No context needed here break; } } - setFirstInitialConditionContent(""); - setSecondInitialConditionContent(""); + setFirstInitialConditionContent("", nullptr); // No context needed here + setSecondInitialConditionContent("", nullptr); // No context needed here } void Sequence::setInitialRank(int rank) { diff --git a/apps/sequence/sequence.h b/apps/sequence/sequence.h index 9647b9ba8..e7901de68 100644 --- a/apps/sequence/sequence.h +++ b/apps/sequence/sequence.h @@ -43,14 +43,14 @@ public: Poincare::Expression firstInitialConditionExpressionReduced(Poincare::Context * context) const { return m_firstInitialCondition.expressionReduced(this, context); } Poincare::Expression firstInitialConditionExpressionClone() const { return m_firstInitialCondition.expressionClone(this); } Poincare::Layout firstInitialConditionLayout() { return m_firstInitialCondition.layout(this); } - Ion::Storage::Record::ErrorStatus setFirstInitialConditionContent(const char * c) { return m_firstInitialCondition.setContent(this, c); } + Ion::Storage::Record::ErrorStatus setFirstInitialConditionContent(const char * c, Poincare::Context * context) { return m_firstInitialCondition.setContent(this, c, context); } // Second initial condition Poincare::Layout secondInitialConditionName() { return m_secondInitialCondition.name(this); } void secondInitialConditionText(char * buffer, size_t bufferSize) const { return m_secondInitialCondition.text(this, buffer, bufferSize); } Poincare::Expression secondInitialConditionExpressionReduced(Poincare::Context * context) const { return m_secondInitialCondition.expressionReduced(this, context); } Poincare::Expression secondInitialConditionExpressionClone() const { return m_secondInitialCondition.expressionClone(this); } Poincare::Layout secondInitialConditionLayout() { return m_secondInitialCondition.layout(this); } - Ion::Storage::Record::ErrorStatus setSecondInitialConditionContent(const char * c) { return m_secondInitialCondition.setContent(this, c); } + Ion::Storage::Record::ErrorStatus setSecondInitialConditionContent(const char * c, Poincare::Context * context) { return m_secondInitialCondition.setContent(this, c, context); } // Sequence properties int numberOfElements() { return (int)type() + 1; } diff --git a/apps/sequence/test/sequence.cpp b/apps/sequence/test/sequence.cpp index 02aaddec9..8d423b010 100644 --- a/apps/sequence/test/sequence.cpp +++ b/apps/sequence/test/sequence.cpp @@ -12,19 +12,19 @@ using namespace Shared; namespace Sequence { -Sequence * addSequence(SequenceStore * store, Sequence::Type type, const char * definition, const char * condition1, const char * condition2) { +Sequence * addSequence(SequenceStore * store, Sequence::Type type, const char * definition, const char * condition1, const char * condition2, Context * context) { Ion::Storage::Record::ErrorStatus err = store->addEmptyModel(); assert(err == Ion::Storage::Record::ErrorStatus::None); (void) err; // Silence compilation warning about unused variable. Ion::Storage::Record record = store->recordAtIndex(store->numberOfModels()-1); Sequence * u = store->modelForRecord(record); u->setType(type); - u->setContent(definition); + u->setContent(definition, context); if (condition1) { - u->setFirstInitialConditionContent(condition1); + u->setFirstInitialConditionContent(condition1, context); } if (condition2) { - u->setSecondInitialConditionContent(condition2); + u->setSecondInitialConditionContent(condition2, context); } return u; } @@ -36,7 +36,7 @@ void check_sequences_defined_by(double result[MaxNumberOfSequences][10], Sequenc Sequence * seqs[MaxNumberOfSequences]; for (int i = 0; i < MaxNumberOfSequences; i++) { - seqs[i] = addSequence(&store, types[i], definitions[i], conditions1[i], conditions2[i]); + seqs[i] = addSequence(&store, types[i], definitions[i], conditions1[i], conditions2[i], &globalContext); } for (int j = 0; j < 10; j++) { @@ -55,7 +55,7 @@ void check_sum_of_sequence_between_bounds(double result, double start, double en SequenceStore store; SequenceContext sequenceContext(&globalContext, &store); - Sequence * seq = addSequence(&store, type, definition, condition1, condition2); + Sequence * seq = addSequence(&store, type, definition, condition1, condition2, &globalContext); double sum = PoincareHelpers::ApproximateToScalar(seq->sumBetweenBounds(start, end, &sequenceContext), &globalContext); quiz_assert(std::fabs(sum - result) < 0.00000001); diff --git a/apps/shared/continuous_function.cpp b/apps/shared/continuous_function.cpp index 273b8af75..96a7cb19a 100644 --- a/apps/shared/continuous_function.cpp +++ b/apps/shared/continuous_function.cpp @@ -120,7 +120,7 @@ ContinuousFunction::PlotType ContinuousFunction::plotType() const { return recordData()->plotType(); } -void ContinuousFunction::setPlotType(PlotType newPlotType, Poincare::Preferences::AngleUnit angleUnit) { +void ContinuousFunction::setPlotType(PlotType newPlotType, Poincare::Preferences::AngleUnit angleUnit, Context * context) { PlotType currentPlotType = plotType(); if (newPlotType == currentPlotType) { return; @@ -143,7 +143,7 @@ void ContinuousFunction::setPlotType(PlotType newPlotType, Poincare::Preferences constexpr int previousTextContentMaxSize = Constant::MaxSerializedExpressionSize; char previousTextContent[previousTextContentMaxSize]; m_model.text(this, previousTextContent, previousTextContentMaxSize, symbol()); - setContent(previousTextContent); + setContent(previousTextContent, context); // Handle parametric function switch if (currentPlotType == PlotType::Parametric) { diff --git a/apps/shared/continuous_function.h b/apps/shared/continuous_function.h index 2f07d327e..612651231 100644 --- a/apps/shared/continuous_function.h +++ b/apps/shared/continuous_function.h @@ -35,7 +35,7 @@ public: Parametric = 2 }; PlotType plotType() const; - void setPlotType(PlotType plotType, Poincare::Preferences::AngleUnit angleUnit); + void setPlotType(PlotType plotType, Poincare::Preferences::AngleUnit angleUnit, Poincare::Context * context); static I18n::Message ParameterMessageForPlotType(PlotType plotType); // Evaluation diff --git a/apps/shared/expression_model.cpp b/apps/shared/expression_model.cpp index 8153155ea..530f7b200 100644 --- a/apps/shared/expression_model.cpp +++ b/apps/shared/expression_model.cpp @@ -105,8 +105,8 @@ Layout ExpressionModel::layout(const Storage::Record * record, CodePoint symbol) return m_layout; } -Ion::Storage::Record::ErrorStatus ExpressionModel::setContent(Ion::Storage::Record * record, const char * c, CodePoint symbol) { - Expression e = ExpressionModel::BuildExpressionFromText(c, symbol); +Ion::Storage::Record::ErrorStatus ExpressionModel::setContent(Ion::Storage::Record * record, const char * c, Context * context, CodePoint symbol) { + Expression e = ExpressionModel::BuildExpressionFromText(c, symbol, context); return setExpressionContent(record, e); } @@ -155,12 +155,12 @@ void ExpressionModel::tidy() const { m_circular = -1; } -Poincare::Expression ExpressionModel::BuildExpressionFromText(const char * c, CodePoint symbol) { +Poincare::Expression ExpressionModel::BuildExpressionFromText(const char * c, CodePoint symbol, Poincare::Context * context) { Expression expressionToStore; // if c = "", we want to reinit the Expression if (c && *c != 0) { // Compute the expression to store, without replacing symbols - expressionToStore = Expression::Parse(c, Container::activeApp()->localContext()); + expressionToStore = Expression::Parse(c, context); if (!expressionToStore.isUninitialized() && symbol != 0) { expressionToStore = expressionToStore.replaceSymbolWithExpression(Symbol::Builder(symbol), Symbol::Builder(UCodePointUnknown)); } diff --git a/apps/shared/expression_model.h b/apps/shared/expression_model.h index d3f7f7d1e..b57ae5ac2 100644 --- a/apps/shared/expression_model.h +++ b/apps/shared/expression_model.h @@ -18,13 +18,13 @@ public: Poincare::Layout layout(const Ion::Storage::Record * record, CodePoint symbol = 0) const; // Setters - Ion::Storage::Record::ErrorStatus setContent(Ion::Storage::Record * record, const char * c, CodePoint symbol = 0); + Ion::Storage::Record::ErrorStatus setContent(Ion::Storage::Record * record, const char * c, Poincare::Context * context, CodePoint symbol = 0); Ion::Storage::Record::ErrorStatus setExpressionContent(Ion::Storage::Record * record, const Poincare::Expression & newExpression); virtual void tidy() const; protected: // Setters helper - static Poincare::Expression BuildExpressionFromText(const char * c, CodePoint symbol = 0); + static Poincare::Expression BuildExpressionFromText(const char * c, CodePoint symbol = 0, Poincare::Context * context = nullptr); mutable Poincare::Expression m_expression; mutable Poincare::Layout m_layout; private: diff --git a/apps/shared/expression_model_handle.h b/apps/shared/expression_model_handle.h index 7456ef3ad..b07c18e36 100644 --- a/apps/shared/expression_model_handle.h +++ b/apps/shared/expression_model_handle.h @@ -30,7 +30,7 @@ public: * behaviour but it is not true for its child classes (for example, in * Sequence). */ virtual void tidy() { model()->tidy(); } - Ion::Storage::Record::ErrorStatus setContent(const char * c) { return editableModel()->setContent(this, c, symbol()); } + Ion::Storage::Record::ErrorStatus setContent(const char * c, Poincare::Context * context) { return editableModel()->setContent(this, c, context, symbol()); } Ion::Storage::Record::ErrorStatus setExpressionContent(const Poincare::Expression & e) { return editableModel()->setExpressionContent(this, e); } protected: ExpressionModel * editableModel() { return const_cast(model()); } diff --git a/apps/shared/expression_model_list_controller.cpp b/apps/shared/expression_model_list_controller.cpp index bb160ec7a..a4dc882dc 100644 --- a/apps/shared/expression_model_list_controller.cpp +++ b/apps/shared/expression_model_list_controller.cpp @@ -216,7 +216,7 @@ void ExpressionModelListController::addEmptyModel() { } void ExpressionModelListController::reinitSelectedExpression(ExpiringPointer model) { - model->setContent(""); + model->setContent("", Container::activeApp()->localContext()); // Reset memoization of the selected cell which always corresponds to the k_memoizedCellsCount/2 memoized cell resetMemoizationForIndex(k_memoizedCellsCount/2); selectableTableView()->reloadData(); @@ -248,7 +248,7 @@ bool ExpressionModelListController::editSelectedRecordWithText(const char * text resetMemoizationForIndex(k_memoizedCellsCount/2); Ion::Storage::Record record = modelStore()->recordAtIndex(modelIndexForRow(selectedRow())); ExpiringPointer model = modelStore()->modelForRecord(record); - return (model->setContent(text) == Ion::Storage::Record::ErrorStatus::None); + return (model->setContent(text, Container::activeApp()->localContext()) == Ion::Storage::Record::ErrorStatus::None); } bool ExpressionModelListController::removeModelRow(Ion::Storage::Record record) { diff --git a/apps/solver/test/equation_store.cpp b/apps/solver/test/equation_store.cpp index 396c6a9ed..d48d1b06d 100644 --- a/apps/solver/test/equation_store.cpp +++ b/apps/solver/test/equation_store.cpp @@ -11,13 +11,13 @@ using namespace Poincare; namespace Solver { -void addEquationWithText(EquationStore * equationStore, const char * text) { +void addEquationWithText(EquationStore * equationStore, const char * text, Context * context) { Ion::Storage::Record::ErrorStatus err = equationStore->addEmptyModel(); quiz_assert_print_if_failure(err == Ion::Storage::Record::ErrorStatus::None, text); (void) err; // Silence warning in DEBUG=0 Ion::Storage::Record record = equationStore->recordAtIndex(equationStore->numberOfModels()-1); Shared::ExpiringPointer model = equationStore->modelForRecord(record); - model->setContent(text); + model->setContent(text, context); } void assert_equation_system_exact_solve_to(const char * equations[], EquationStore::Error error, EquationStore::Type type, const char * variables[], const char * solutions[], int numberOfSolutions) { @@ -25,7 +25,7 @@ void assert_equation_system_exact_solve_to(const char * equations[], EquationSto EquationStore equationStore; int index = 0; while (equations[index] != 0) { - addEquationWithText(&equationStore, equations[index++]); + addEquationWithText(&equationStore, equations[index++], &globalContext); } EquationStore::Error err = equationStore.exactSolve(&globalContext); quiz_assert_print_if_failure(err == error, equations[0]); @@ -58,7 +58,7 @@ void assert_equation_system_exact_solve_to(const char * equations[], EquationSto void assert_equation_approximate_solve_to(const char * equations, double xMin, double xMax, const char * variable, double solutions[], int numberOfSolutions, bool hasMoreSolutions) { Shared::GlobalContext globalContext; EquationStore equationStore; - addEquationWithText(&equationStore, equations); + addEquationWithText(&equationStore, equations, &globalContext); EquationStore::Error err = equationStore.exactSolve(&globalContext); quiz_assert(err == EquationStore::Error::RequireApproximateSolution); equationStore.setIntervalBound(0, xMin);