[sequence] Fixed crash due to undefined sequence

Change-Id: Ie67ff4aa9a53eb8b04535e3b61737e11c9049316
This commit is contained in:
Arthur Camouseigt
2020-09-14 12:41:29 +02:00
committed by Émilie Feral
parent b8544e3708
commit 51002066e9
7 changed files with 27 additions and 10 deletions

View File

@@ -67,4 +67,11 @@ Shared::SequenceContext * App::localContext() {
return &m_sequenceContext; return &m_sequenceContext;
} }
NestedMenuController * App::variableBoxForInputEventHandler(InputEventHandler * textInput) {
MathVariableBoxController * varBox = AppsContainer::sharedAppsContainer()->variableBoxController();
varBox->setSender(textInput);
varBox->lockDeleteEvent(MathVariableBoxController::Page::Sequence);
return varBox;
}
} }

View File

@@ -47,6 +47,7 @@ public:
// TODO: override variableBoxForInputEventHandler to lock sequence in the variable box once they appear there // TODO: override variableBoxForInputEventHandler to lock sequence in the variable box once they appear there
// NestedMenuController * variableBoxForInputEventHandler(InputEventHandler * textInput) override; // NestedMenuController * variableBoxForInputEventHandler(InputEventHandler * textInput) override;
CodePoint XNT() override { return 'n'; } CodePoint XNT() override { return 'n'; }
NestedMenuController * variableBoxForInputEventHandler(InputEventHandler * textInput) override;
Shared::SequenceContext * localContext() override; Shared::SequenceContext * localContext() override;
Shared::SequenceStore * functionStore() override { return static_cast<Shared::GlobalContext *>(AppsContainer::sharedAppsContainer()->globalContext())->sequenceStore(); } Shared::SequenceStore * functionStore() override { return static_cast<Shared::GlobalContext *>(AppsContainer::sharedAppsContainer()->globalContext())->sequenceStore(); }
Shared::Interval * interval() { return snapshot()->interval(); } Shared::Interval * interval() { return snapshot()->interval(); }

View File

@@ -30,12 +30,14 @@ const Expression CacheContext<T>::expressionForSymbolAbstract(const Poincare::Sy
return Float<T>::Builder(m_values[index][1]); return Float<T>::Builder(m_values[index][1]);
} }
Ion::Storage::Record record = m_sequenceContext->sequenceStore()->recordAtIndex(index); Ion::Storage::Record record = m_sequenceContext->sequenceStore()->recordAtIndex(index);
Sequence * seq = m_sequenceContext->sequenceStore()->modelForRecord(record); if (!record.isNull()) {
rank.replaceSymbolWithExpression(Symbol::Builder(UCodePointUnknown), Float<T>::Builder(m_nValue)); Sequence * seq = m_sequenceContext->sequenceStore()->modelForRecord(record);
T n = PoincareHelpers::ApproximateToScalar<T>(rank, this); rank.replaceSymbolWithExpression(Symbol::Builder(UCodePointUnknown), Float<T>::Builder(m_nValue));
// In case the rank is not int or sequence referenced is not defined, return NAN T n = PoincareHelpers::ApproximateToScalar<T>(rank, this);
if (std::floor(n) == n && seq->fullName() != nullptr) { // In case the rank is not int or sequence referenced is not defined, return NAN
return Float<T>::Builder(seq->valueAtRank<T>(n, m_sequenceContext)); if (std::floor(n) == n && seq->fullName() != nullptr) {
return Float<T>::Builder(seq->valueAtRank<T>(n, m_sequenceContext));
}
} else { } else {
return Float<T>::Builder(NAN); return Float<T>::Builder(NAN);
} }

View File

@@ -22,6 +22,7 @@ public:
Ion::Storage::Record::ErrorStatus setExpressionContent(Ion::Storage::Record * record, const Poincare::Expression & newExpression); Ion::Storage::Record::ErrorStatus setExpressionContent(Ion::Storage::Record * record, const Poincare::Expression & newExpression);
virtual void tidy() const; virtual void tidy() const;
bool hasValidExpression() { return !m_expression.isUninitialized(); }
protected: protected:
// Setters helper // Setters helper
static Poincare::Expression BuildExpressionFromText(const char * c, CodePoint symbol = 0, Poincare::Context * context = nullptr); static Poincare::Expression BuildExpressionFromText(const char * c, CodePoint symbol = 0, Poincare::Context * context = nullptr);

View File

@@ -127,7 +127,7 @@ const Expression GlobalContext::ExpressionForSequence(const SymbolAbstract & sym
char unknownN[bufferSize]; char unknownN[bufferSize];
Poincare::SerializationHelper::CodePoint(unknownN, bufferSize, UCodePointUnknown); Poincare::SerializationHelper::CodePoint(unknownN, bufferSize, UCodePointUnknown);
float rank = symbol.childAtIndex(0).approximateWithValueForSymbol<float>(unknownN, unknownSymbolValue, ctx, Preferences::sharedPreferences()->complexFormat(),Preferences::sharedPreferences()->angleUnit()); float rank = symbol.childAtIndex(0).approximateWithValueForSymbol<float>(unknownN, unknownSymbolValue, ctx, Preferences::sharedPreferences()->complexFormat(),Preferences::sharedPreferences()->angleUnit());
if (std::floor(rank) == rank) { if (std::floor(rank) == rank && seq.hasValidExpression()) {
SequenceContext sqctx(ctx, sequenceStore()); SequenceContext sqctx(ctx, sequenceStore());
return Float<double>::Builder(seq.evaluateXYAtParameter(rank, &sqctx).x2()); return Float<double>::Builder(seq.evaluateXYAtParameter(rank, &sqctx).x2());
} else { } else {

View File

@@ -59,6 +59,7 @@ public:
Poincare::Layout nameLayout(); Poincare::Layout nameLayout();
bool isDefined() override; bool isDefined() override;
bool isEmpty() override; bool isEmpty() override;
bool hasValidExpression() { return m_definition.hasValidExpression(); }
// Approximation // Approximation
Poincare::Coordinate2D<float> evaluateXYAtParameter(float x, Poincare::Context * context) const override { Poincare::Coordinate2D<float> evaluateXYAtParameter(float x, Poincare::Context * context) const override {
return Poincare::Coordinate2D<float>(x, templatedApproximateAtAbscissa(x, static_cast<SequenceContext *>(context))); return Poincare::Coordinate2D<float>(x, templatedApproximateAtAbscissa(x, static_cast<SequenceContext *>(context)));

View File

@@ -87,9 +87,14 @@ void TemplatedSequenceContext<T>::step(SequenceContext * sqctx, int sequenceInde
SequenceStore * sequenceStore = sqctx->sequenceStore(); SequenceStore * sequenceStore = sqctx->sequenceStore();
stop = stepMultipleSequences ? sequenceStore->numberOfModels() : start + 1; stop = stepMultipleSequences ? sequenceStore->numberOfModels() : start + 1;
for (int i = start; i < stop; i++) { for (int i = start; i < stop; i++) {
Sequence * u = sequenceStore->modelForRecord(sequenceStore->recordAtIndex(i)); Ion::Storage::Record record = sequenceStore->recordAtIndex(i);
int index = stepMultipleSequences ? SequenceStore::sequenceIndexForName(u->fullName()[0]) : 0; if (!record.isNull()) {
sequences[index] = u->isDefined() ? u : nullptr; Sequence * u = sequenceStore->modelForRecord(record);
int index = stepMultipleSequences ? SequenceStore::sequenceIndexForName(u->fullName()[0]) : 0;
sequences[index] = u->isDefined() ? u : nullptr;
} else {
sequences[i] = nullptr;
}
} }
// We approximate the value of the next rank for each sequence we want to update // We approximate the value of the next rank for each sequence we want to update