mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-18 16:27:34 +01:00
[sequence] Fixed crash due to undefined sequence
Change-Id: Ie67ff4aa9a53eb8b04535e3b61737e11c9049316
This commit is contained in:
committed by
Émilie Feral
parent
b8544e3708
commit
51002066e9
@@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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(); }
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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)));
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user