From 97cba08b23cb7a37d722a577c144cfd23e2e4080 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Tue, 9 Oct 2018 16:45:48 +0200 Subject: [PATCH] [apps] Clean GLobalContext --- apps/shared/global_context.cpp | 85 ++++++++++++++-------- apps/shared/global_context.h | 47 ++++++++---- apps/shared/storage_cartesian_function.cpp | 2 +- apps/variable_box_controller.cpp | 2 +- poincare/include/poincare/expression.h | 1 - poincare/src/expression.cpp | 8 -- 6 files changed, 90 insertions(+), 55 deletions(-) diff --git a/apps/shared/global_context.cpp b/apps/shared/global_context.cpp index c3bdc1ec8..e2bde901c 100644 --- a/apps/shared/global_context.cpp +++ b/apps/shared/global_context.cpp @@ -15,61 +15,91 @@ constexpr char GlobalContext::expExtension[]; constexpr char GlobalContext::funcExtension[]; //constexpr char GlobalContext::seqExtension[]; -/* Storage memory full */ - static bool sStorageMemoryFull = false; +bool GlobalContext::RecordBaseNameIsFree(const char * baseName) { + return RecordWithBaseName(baseName).isNull(); +} + bool GlobalContext::storageMemoryFull() { return sStorageMemoryFull; } +Poincare::Expression GlobalContext::ExpressionFromRecord(Ion::Storage::Record record) { + if (record.isNull() || record.value().size == 0) { + return Expression(); + } + if (Ion::Storage::FullNameHasExtension(record.fullName(), expExtension, strlen(expExtension))) { + return ExpressionFromSymbolRecord(record); + } + assert(Ion::Storage::FullNameHasExtension(record.fullName(), funcExtension, strlen(funcExtension))); + return ExpressionFromFunctionRecord(record); +} + +Poincare::Expression GlobalContext::ExpressionFromSymbolRecord(Ion::Storage::Record record) { + if (record.isNull() || record.value().size == 0) { + return Expression(); + } + assert(Ion::Storage::FullNameHasExtension(record.fullName(), expExtension, strlen(expExtension))); + // An expression record value is the expression itself + Ion::Storage::Record::Data d = record.value(); + return Expression::ExpressionFromAddress(d.buffer, d.size); +} +Poincare::Expression GlobalContext::ExpressionFromFunctionRecord(Ion::Storage::Record record) { + if (record.isNull() || record.value().size == 0) { + return Expression(); + } + assert(Ion::Storage::FullNameHasExtension(record.fullName(), funcExtension, strlen(funcExtension))); + /* An function record value has metadata before the expression. To get the + * expression, use the funciton record handle. */ + StorageCartesianFunction f = StorageCartesianFunction(record); + return f.expression(); +} + const Expression GlobalContext::expressionForSymbol(const SymbolAbstract & symbol) { - Ion::Storage::Record r = RecordWithName(symbol.name()); - return expressionForSymbolAndRecord(symbol, r); + Ion::Storage::Record r = RecordWithBaseName(symbol.name()); + return ExpressionForSymbolAndRecord(symbol, r); } void GlobalContext::setExpressionForSymbol(const Expression & expression, const SymbolAbstract & symbol, Context & context) { sStorageMemoryFull = false; /* If the new expression contains the symbol, replace it because it will be * destroyed afterwards (to be able to do A+2->A) */ - Ion::Storage::Record record = RecordWithName(symbol.name()); - Expression e = expressionForSymbolAndRecord(symbol, record); + Ion::Storage::Record record = RecordWithBaseName(symbol.name()); + Expression e = ExpressionFromRecord(record); if (e.isUninitialized()) { e = Undefined(); } Expression finalExpression = expression.clone().replaceSymbolWithExpression(symbol, e); + // Set the expression in the storage depending on the symbol type Ion::Storage::Record::ErrorStatus err = Ion::Storage::Record::ErrorStatus::None; if (symbol.type() == ExpressionNode::Type::Symbol) { - err = setExpressionForActualSymbol(finalExpression, symbol, record); + err = SetExpressionForActualSymbol(finalExpression, symbol, record); } else { assert(symbol.type() == ExpressionNode::Type::Function); - err = setExpressionForFunction(finalExpression, symbol, record); + err = SetExpressionForFunction(finalExpression, symbol, record); } + // Handle a storage error if (err != Ion::Storage::Record::ErrorStatus::None) { assert(err == Ion::Storage::Record::ErrorStatus::NotEnoughSpaceAvailable); sStorageMemoryFull = true; } } -Ion::Storage::Record GlobalContext::RecordWithName(const char * name) { - const char * extensions[2] = {expExtension, funcExtension/*, seqExtension*/}; - return Ion::Storage::sharedStorage()->recordBaseNamedWithExtensions(name, extensions, 2); -} - -const Expression GlobalContext::expressionForSymbolAndRecord(const SymbolAbstract & symbol, Ion::Storage::Record r) { +const Expression GlobalContext::ExpressionForSymbolAndRecord(const SymbolAbstract & symbol, Ion::Storage::Record r) { if (r.isNull()) { return Expression(); } if (symbol.type() == ExpressionNode::Type::Symbol) { - return expressionForActualSymbol(symbol, r); + return ExpressionForActualSymbol(symbol, r); } assert(symbol.type() == ExpressionNode::Type::Function); - return expressionForFunction(symbol, r); + return ExpressionForFunction(symbol, r); } -const Expression GlobalContext::expressionForActualSymbol(const SymbolAbstract & symbol, Ion::Storage::Record r) { +const Expression GlobalContext::ExpressionForActualSymbol(const SymbolAbstract & symbol, Ion::Storage::Record r) { assert(symbol.type() == ExpressionNode::Type::Symbol); // Constant symbols Symbol s = static_cast(symbol); @@ -80,38 +110,28 @@ const Expression GlobalContext::expressionForActualSymbol(const SymbolAbstract & return Float(M_E); } // Look up the file system for symbol - return Expression::ExpressionFromRecord(r); + return ExpressionFromSymbolRecord(r); } -const Expression GlobalContext::expressionForFunction(const SymbolAbstract & symbol, Ion::Storage::Record r) { - assert(symbol.type() == ExpressionNode::Type::Function); - StorageCartesianFunction f = StorageCartesianFunction(r); - return f.expression(); -} - -Ion::Storage::Record::ErrorStatus GlobalContext::setExpressionForActualSymbol(const Expression & expression, const SymbolAbstract & symbol, Ion::Storage::Record previousRecord) { +Ion::Storage::Record::ErrorStatus GlobalContext::SetExpressionForActualSymbol(const Expression & expression, const SymbolAbstract & symbol, Ion::Storage::Record previousRecord) { // Delete any record with same name (as it is going to be overriden) previousRecord.destroy(); return Ion::Storage::sharedStorage()->createRecordWithExtension(symbol.name(), expExtension, expression.addressInPool(), expression.size()); } -Ion::Storage::Record::ErrorStatus GlobalContext::setExpressionForFunction(const Expression & expressionToStore, const SymbolAbstract & symbol, Ion::Storage::Record previousRecord) { +Ion::Storage::Record::ErrorStatus GlobalContext::SetExpressionForFunction(const Expression & expressionToStore, const SymbolAbstract & symbol, Ion::Storage::Record previousRecord) { size_t expressionToStoreSize = expressionToStore.isUninitialized() ? 0 : expressionToStore.size(); size_t newDataSize = sizeof(StorageCartesianFunction::CartesianFunctionRecordData) + expressionToStoreSize; Ion::Storage::Record::ErrorStatus error = Ion::Storage::Record::ErrorStatus::None; if (Ion::Storage::FullNameHasExtension(previousRecord.fullName(), funcExtension, strlen(funcExtension))) { // The previous record was also a function: we want to keep its metadata - // Prepare the new data to store Ion::Storage::Record::Data newData = previousRecord.value(); newData.size = newDataSize; - // Set the data error = previousRecord.setValue(newData); } else { // The previous record was not a function. Destroy it and create the new record. previousRecord.destroy(); - // Prepare the new data to store StorageCartesianFunction::CartesianFunctionRecordData newData; - // Create the record error = Ion::Storage::sharedStorage()->createRecordWithExtension(symbol.name(), funcExtension, &newData, newDataSize); } if (error == Ion::Storage::Record::ErrorStatus::None && !expressionToStore.isUninitialized()) { @@ -121,4 +141,9 @@ Ion::Storage::Record::ErrorStatus GlobalContext::setExpressionForFunction(const return error; } +Ion::Storage::Record GlobalContext::RecordWithBaseName(const char * name) { + const char * extensions[2] = {expExtension, funcExtension/*, seqExtension*/}; + return Ion::Storage::sharedStorage()->recordBaseNamedWithExtensions(name, extensions, 2); +} + } diff --git a/apps/shared/global_context.h b/apps/shared/global_context.h index c2d9af530..a42feb3c0 100644 --- a/apps/shared/global_context.h +++ b/apps/shared/global_context.h @@ -7,6 +7,7 @@ #include #include #include +#include namespace Shared { @@ -14,23 +15,41 @@ class Integer; class GlobalContext final : public Poincare::Context { public: - // TODO: should this be store elsewhere? - static constexpr char funcExtension[] = "func"; - static constexpr char expExtension[] = "exp"; - /* The expression recorded in global context is already a expression. + static constexpr char funcExtension[] = "func"; // TODO: store this elsewhere? + static constexpr char expExtension[] = "exp"; // TODO: store this elsewhere? + //static constexpr char seqExtension[] = "seq"; + + // Storage information + static bool RecordBaseNameIsFree(const char * baseName); + static bool storageMemoryFull(); + + // Expression from record + static Poincare::Expression ExpressionFromRecord(Ion::Storage::Record record); + static Poincare::Expression ExpressionFromSymbolRecord(Ion::Storage::Record record); + static Poincare::Expression ExpressionFromFunctionRecord(Ion::Storage::Record record); + + /* Expression for symbol + * The expression recorded in global context is already an expression. * Otherwise, we would need the context and the angle unit to evaluate it */ const Poincare::Expression expressionForSymbol(const Poincare::SymbolAbstract & symbol) override; - void setExpressionForSymbol(const Poincare::Expression & expression, const Poincare::SymbolAbstract & symbol, Poincare::Context & context) override; - static Ion::Storage::Record RecordWithName(const char * name); - static bool storageMemoryFull(); - //TODO static constexpr uint16_t k_maxNumberOfSequences = 10; + void setExpressionForSymbol( + const Poincare::Expression & expression, + const Poincare::SymbolAbstract & symbol, + Poincare::Context & context) override; + private: - //static constexpr char seqExtension[] = "seq"; - const Poincare::Expression expressionForSymbolAndRecord(const Poincare::SymbolAbstract & symbol, Ion::Storage::Record r); - const Poincare::Expression expressionForActualSymbol(const Poincare::SymbolAbstract & symbol, Ion::Storage::Record r); - const Poincare::Expression expressionForFunction(const Poincare::SymbolAbstract & symbol, Ion::Storage::Record r); - Ion::Storage::Record::ErrorStatus setExpressionForActualSymbol(const Poincare::Expression & expression, const Poincare::SymbolAbstract & symbol, Ion::Storage::Record previousRecord); - Ion::Storage::Record::ErrorStatus setExpressionForFunction(const Poincare::Expression & expression, const Poincare::SymbolAbstract & symbol, Ion::Storage::Record previousRecord); + // Expression getters + static const Poincare::Expression ExpressionForSymbolAndRecord(const Poincare::SymbolAbstract & symbol, Ion::Storage::Record r); + static const Poincare::Expression ExpressionForActualSymbol(const Poincare::SymbolAbstract & symbol, Ion::Storage::Record r); + static const Poincare::Expression ExpressionForFunction(const Poincare::SymbolAbstract & symbol, Ion::Storage::Record r) { + assert(symbol.type() == Poincare::ExpressionNode::Type::Function); + return ExpressionFromFunctionRecord(r); + } + // Expression setters + static Ion::Storage::Record::ErrorStatus SetExpressionForActualSymbol(const Poincare::Expression & expression, const Poincare::SymbolAbstract & symbol, Ion::Storage::Record previousRecord); + static Ion::Storage::Record::ErrorStatus SetExpressionForFunction(const Poincare::Expression & expression, const Poincare::SymbolAbstract & symbol, Ion::Storage::Record previousRecord); + // Record getter + static Ion::Storage::Record RecordWithBaseName(const char * name); }; } diff --git a/apps/shared/storage_cartesian_function.cpp b/apps/shared/storage_cartesian_function.cpp index 5eb1b51af..8c1c56e3c 100644 --- a/apps/shared/storage_cartesian_function.cpp +++ b/apps/shared/storage_cartesian_function.cpp @@ -20,7 +20,7 @@ void StorageCartesianFunction::DefaultName(char buffer[], size_t bufferSize) { int dotCharIndex = -1; while (currentNumber < bufferSize - constantNameSize) { dotCharIndex = 1 + Poincare::Integer(currentNumber).serialize(&buffer[1], bufferSize - constantNameSize + 1); - if (GlobalContext::RecordWithName(buffer).isNull()) { + if (GlobalContext::RecordBaseNameIsFree(buffer)) { // Name found break; } diff --git a/apps/variable_box_controller.cpp b/apps/variable_box_controller.cpp index 9e84afc07..85739d299 100644 --- a/apps/variable_box_controller.cpp +++ b/apps/variable_box_controller.cpp @@ -175,7 +175,7 @@ Layout VariableBoxController::expressionLayoutForRecord(Storage::Record record, } assert(index-m_firstMemoizedLayoutIndex < k_maxNumberOfDisplayedRows); if (m_layouts[index-m_firstMemoizedLayoutIndex].isUninitialized()) { - m_layouts[index-m_firstMemoizedLayoutIndex] = Expression::ExpressionFromRecord(record).createLayout(Poincare::Preferences::sharedPreferences()->displayMode(), Constant::ShortNumberOfSignificantDigits); + m_layouts[index-m_firstMemoizedLayoutIndex] = GlobalContext::ExpressionFromRecord(record).createLayout(Poincare::Preferences::sharedPreferences()->displayMode(), Constant::ShortNumberOfSignificantDigits); } return m_layouts[index-m_firstMemoizedLayoutIndex]; } diff --git a/poincare/include/poincare/expression.h b/poincare/include/poincare/expression.h index 7286ca72b..7eac460dc 100644 --- a/poincare/include/poincare/expression.h +++ b/poincare/include/poincare/expression.h @@ -92,7 +92,6 @@ public: Expression() : TreeHandle() {} Expression clone() const; static Expression parse(char const * string); - static const Expression ExpressionFromRecord(const Ion::Storage::Record & record); static const Expression ExpressionFromAddress(const void * address, size_t size); /* Circuit breaker */ diff --git a/poincare/src/expression.cpp b/poincare/src/expression.cpp index e6a1ccf16..72903ec67 100644 --- a/poincare/src/expression.cpp +++ b/poincare/src/expression.cpp @@ -43,14 +43,6 @@ Expression Expression::parse(char const * string) { return expression; } -const Expression Expression::ExpressionFromRecord(const Ion::Storage::Record & record) { - if (record.isNull() || record.value().size == 0) { - return Expression(); - } - Ion::Storage::Record::Data d = record.value(); - return ExpressionFromAddress(d.buffer, d.size); -} - const Expression Expression::ExpressionFromAddress(const void * address, size_t size) { if (address == nullptr || size == 0) { return Expression();