diff --git a/apps/graph/Makefile b/apps/graph/Makefile index 8dedf6855..fe6bac0db 100644 --- a/apps/graph/Makefile +++ b/apps/graph/Makefile @@ -5,7 +5,6 @@ app_objs += $(addprefix apps/graph/,\ app.o\ cartesian_function.o\ cartesian_function_store.o\ - storage_cartesian_function.o\ storage_cartesian_function_store.o\ graph/banner_view.o\ graph/calculation_graph_controller.o\ diff --git a/apps/graph/graph/storage_calculation_graph_controller.h b/apps/graph/graph/storage_calculation_graph_controller.h index 069e651c1..007371785 100644 --- a/apps/graph/graph/storage_calculation_graph_controller.h +++ b/apps/graph/graph/storage_calculation_graph_controller.h @@ -6,17 +6,17 @@ #include "../../shared/curve_view_cursor.h" #include "../../shared/interactive_curve_view_range.h" #include "../../shared/storage_function_banner_delegate.h" -#include "../storage_cartesian_function.h" +#include "../../shared/storage_cartesian_function.h" namespace Graph { -class StorageCalculationGraphController : public ViewController, public Shared::StorageFunctionBannerDelegate { +class StorageCalculationGraphController : public ViewController, public Shared::StorageFunctionBannerDelegate { public: StorageCalculationGraphController(Responder * parentResponder, StorageGraphView * graphView, BannerView * bannerView, Shared::InteractiveCurveViewRange * curveViewRange, Shared::CurveViewCursor * cursor, I18n::Message defaultMessage); View * view() override; void viewWillAppear() override; bool handleEvent(Ion::Events::Event event) override; - void setFunction(StorageCartesianFunction * function); + void setFunction(Shared::StorageCartesianFunction * function); protected: constexpr static float k_cursorTopMarginRatio = 0.07f; // (cursorHeight/2)/graphViewHeight constexpr static float k_cursorBottomMarginRatio = 0.15f; // (cursorHeight/2+bannerHeigh)/graphViewHeight @@ -29,7 +29,7 @@ protected: BannerView * m_bannerView; Shared::InteractiveCurveViewRange * m_graphRange; Shared::CurveViewCursor * m_cursor; - StorageCartesianFunction m_function; + Shared::StorageCartesianFunction m_function; MessageTextView m_defaultBannerView; bool m_isActive; }; diff --git a/apps/graph/graph/storage_calculation_parameter_controller.h b/apps/graph/graph/storage_calculation_parameter_controller.h index cf78bb03e..628b36512 100644 --- a/apps/graph/graph/storage_calculation_parameter_controller.h +++ b/apps/graph/graph/storage_calculation_parameter_controller.h @@ -2,7 +2,6 @@ #define GRAPH_STORAGE_CALCULATION_PARAMETER_CONTROLLER_H #include -#include "../storage_cartesian_function.h" #include "storage_tangent_graph_controller.h" #include "extremum_graph_controller.h" #include "integral_graph_controller.h" @@ -10,6 +9,7 @@ #include "root_graph_controller.h" #include "storage_graph_view.h" #include "banner_view.h" +#include "../../shared/storage_cartesian_function.h" #include "../../i18n.h" namespace Graph { @@ -26,12 +26,12 @@ public: HighlightCell * reusableCell(int index) override; int reusableCellCount() override; void willDisplayCellForIndex(HighlightCell * cell, int index) override; - void setFunction(StorageCartesianFunction * function); + void setFunction(Shared::StorageCartesianFunction * function); private: constexpr static int k_totalNumberOfCells = 6; MessageTableCell m_cells[k_totalNumberOfCells]; SelectableTableView m_selectableTableView; - StorageCartesianFunction * m_function; + Shared::StorageCartesianFunction * m_function; StorageTangentGraphController m_tangentGraphController; IntegralGraphController m_integralGraphController; MinimumGraphController m_minimumGraphController; diff --git a/apps/graph/graph/storage_curve_parameter_controller.h b/apps/graph/graph/storage_curve_parameter_controller.h index 383b2078d..82dc1a30d 100644 --- a/apps/graph/graph/storage_curve_parameter_controller.h +++ b/apps/graph/graph/storage_curve_parameter_controller.h @@ -11,7 +11,7 @@ namespace Graph { class StorageGraphController; -class StorageCurveParameterController : public Shared::StorageFunctionCurveParameterController { +class StorageCurveParameterController : public Shared::StorageFunctionCurveParameterController { public: StorageCurveParameterController(Shared::InteractiveCurveViewRange * graphRange, BannerView * bannerView, Shared::CurveViewCursor * cursor, StorageGraphView * graphView, StorageGraphController * graphController, StorageCartesianFunctionStore * functionStore); const char * title() override; @@ -21,8 +21,8 @@ public: int reusableCellCount() override; void willDisplayCellForIndex(HighlightCell * cell, int index) override; private: - Shared::StorageFunctionGoToParameterController * goToParameterController() override; - Shared::StorageFunctionGoToParameterController m_goToParameterController; + Shared::StorageFunctionGoToParameterController * goToParameterController() override; + Shared::StorageFunctionGoToParameterController m_goToParameterController; StorageGraphController * m_graphController; constexpr static int k_totalNumberOfCells = 3; MessageTableCellWithChevron m_calculationCell; diff --git a/apps/graph/graph/storage_graph_controller.h b/apps/graph/graph/storage_graph_controller.h index 225f7c415..006394cc0 100644 --- a/apps/graph/graph/storage_graph_controller.h +++ b/apps/graph/graph/storage_graph_controller.h @@ -13,7 +13,7 @@ namespace Graph { -class StorageGraphController : public Shared::StorageFunctionGraphController, public StorageGraphControllerHelper { +class StorageGraphController : public Shared::StorageFunctionGraphController, public StorageGraphControllerHelper { public: StorageGraphController(Responder * parentResponder, StorageCartesianFunctionStore * functionStore, Shared::InteractiveCurveViewRange * curveViewRange, Shared::CurveViewCursor * cursor, int * indexFunctionSelectedByCursor, uint32_t * modelVersion, uint32_t * rangeVersion, Poincare::Preferences::AngleUnit * angleUnitVersion, ButtonRowController * header); I18n::Message emptyMessage() override; diff --git a/apps/graph/graph/storage_graph_controller_helper.h b/apps/graph/graph/storage_graph_controller_helper.h index e7ce787e0..95e105d5d 100644 --- a/apps/graph/graph/storage_graph_controller_helper.h +++ b/apps/graph/graph/storage_graph_controller_helper.h @@ -1,18 +1,18 @@ #ifndef GRAPH_STORAGE_GRAPH_CONTROLLER_HELPER_H #define GRAPH_STORAGE_GRAPH_CONTROLLER_HELPER_H +#include "../../shared/interactive_curve_view_range.h" +#include "../../shared/storage_cartesian_function.h" #include "../../shared/storage_function_banner_delegate.h" #include "../../shared/text_field_delegate_app.h" -#include "../../shared/interactive_curve_view_range.h" -#include "../storage_cartesian_function.h" namespace Graph { class StorageGraphControllerHelper { protected: constexpr static int k_maxDigitLegendLength = 10; - bool privateMoveCursorHorizontally(Shared::CurveViewCursor * cursor, int direction, Shared::InteractiveCurveViewRange * range, int numberOfStepsInGradUnit, StorageCartesianFunction * function, Shared::TextFieldDelegateApp * app, float cursorTopMarginRatio, float cursorRightMarginRatio, float cursorBottomMarginRatio, float cursorLeftMarginRatio); - void reloadDerivativeInBannerViewForCursorOnFunction(Shared::CurveViewCursor * cursor, StorageCartesianFunction * function, Shared::TextFieldDelegateApp * app); + bool privateMoveCursorHorizontally(Shared::CurveViewCursor * cursor, int direction, Shared::InteractiveCurveViewRange * range, int numberOfStepsInGradUnit, Shared::StorageCartesianFunction * function, Shared::TextFieldDelegateApp * app, float cursorTopMarginRatio, float cursorRightMarginRatio, float cursorBottomMarginRatio, float cursorLeftMarginRatio); + void reloadDerivativeInBannerViewForCursorOnFunction(Shared::CurveViewCursor * cursor, Shared::StorageCartesianFunction * function, Shared::TextFieldDelegateApp * app); virtual Shared::BannerView * bannerView() = 0; }; diff --git a/apps/graph/graph/storage_graph_view.h b/apps/graph/graph/storage_graph_view.h index 935727039..d664afc5c 100644 --- a/apps/graph/graph/storage_graph_view.h +++ b/apps/graph/graph/storage_graph_view.h @@ -6,7 +6,7 @@ namespace Graph { -class StorageGraphView : public Shared::StorageFunctionGraphView { +class StorageGraphView : public Shared::StorageFunctionGraphView { public: StorageGraphView(StorageCartesianFunctionStore * functionStore, Shared::InteractiveCurveViewRange * graphRange, Shared::CurveViewCursor * cursor, Shared::BannerView * bannerView, View * cursorView); diff --git a/apps/graph/graph/storage_intersection_graph_controller.h b/apps/graph/graph/storage_intersection_graph_controller.h index f5fadfa5b..89cab8990 100644 --- a/apps/graph/graph/storage_intersection_graph_controller.h +++ b/apps/graph/graph/storage_intersection_graph_controller.h @@ -12,7 +12,7 @@ public: private: void reloadBannerView() override; Poincare::Expression::Coordinate2D computeNewPointOfInterest(double start, double step, double max, Poincare::Context * context) override; - StorageCartesianFunction m_intersectedFunction; + Shared::StorageCartesianFunction m_intersectedFunction; StorageCartesianFunctionStore * m_functionStore; }; diff --git a/apps/graph/graph/storage_tangent_graph_controller.h b/apps/graph/graph/storage_tangent_graph_controller.h index 6f28d90db..4795ddf48 100644 --- a/apps/graph/graph/storage_tangent_graph_controller.h +++ b/apps/graph/graph/storage_tangent_graph_controller.h @@ -10,12 +10,12 @@ namespace Graph { -class StorageTangentGraphController : public Shared::SimpleInteractiveCurveViewController, public Shared::StorageFunctionBannerDelegate, public GraphControllerHelper { +class StorageTangentGraphController : public Shared::SimpleInteractiveCurveViewController, public Shared::StorageFunctionBannerDelegate, public GraphControllerHelper { public: StorageTangentGraphController(Responder * parentResponder, StorageGraphView * graphView, BannerView * bannerView, Shared::InteractiveCurveViewRange * curveViewRange, Shared::CurveViewCursor * cursor); const char * title() override; void viewWillAppear() override; - void setFunction(StorageCartesianFunction * function); + void setFunction(Shared::StorageCartesianFunction * function); private: constexpr static float k_cursorTopMarginRatio = 0.07f; // (cursorHeight/2)/graphViewHeight constexpr static float k_cursorBottomMarginRatio = 0.22f; // (cursorHeight/2+bannerHeigh)/graphViewHeight @@ -28,7 +28,7 @@ private: StorageGraphView * m_graphView; BannerView * m_bannerView; Shared::InteractiveCurveViewRange * m_graphRange; - StorageCartesianFunction m_function; + Shared::StorageCartesianFunction m_function; }; } diff --git a/apps/graph/list/storage_list_controller.h b/apps/graph/list/storage_list_controller.h index a8c12afe3..85b823f6e 100644 --- a/apps/graph/list/storage_list_controller.h +++ b/apps/graph/list/storage_list_controller.h @@ -10,12 +10,12 @@ namespace Graph { -class StorageListController : public Shared::StorageFunctionListController { +class StorageListController : public Shared::StorageFunctionListController { public: StorageListController(Responder * parentResponder, StorageCartesianFunctionStore * functionStore, ButtonRowController * header, ButtonRowController * footer); const char * title() override; private: - Shared::StorageListParameterController * parameterController() override; + Shared::StorageListParameterController * parameterController() override; int maxNumberOfDisplayableRows() override; Shared::FunctionTitleCell * titleCells(int index) override; HighlightCell * expressionCells(int index) override; @@ -26,7 +26,7 @@ private: constexpr static int k_maxNumberOfDisplayableRows = 5; Shared::BufferFunctionTitleCell m_functionTitleCells[k_maxNumberOfDisplayableRows]; Shared::FunctionExpressionCell m_expressionCells[k_maxNumberOfDisplayableRows]; - Shared::StorageListParameterController m_parameterController; + Shared::StorageListParameterController m_parameterController; }; } diff --git a/apps/graph/storage_cartesian_function_store.cpp b/apps/graph/storage_cartesian_function_store.cpp index 49537b204..c9aeee27e 100644 --- a/apps/graph/storage_cartesian_function_store.cpp +++ b/apps/graph/storage_cartesian_function_store.cpp @@ -9,12 +9,12 @@ namespace Graph { //constexpr const char * StorageCartesianFunctionStore::k_functionNames[k_maxNumberOfFunctions]; -StorageCartesianFunction StorageCartesianFunctionStore::NullModel() { - return StorageCartesianFunction(""); +Shared::StorageCartesianFunction StorageCartesianFunctionStore::NullModel() { + return Shared::StorageCartesianFunction(""); } StorageCartesianFunctionStore::StorageCartesianFunctionStore() : - Shared::StorageFunctionStore() + Shared::StorageFunctionStore() { //addEmptyModel(); } diff --git a/apps/graph/storage_cartesian_function_store.h b/apps/graph/storage_cartesian_function_store.h index 27419abb3..9ee82bb3d 100644 --- a/apps/graph/storage_cartesian_function_store.h +++ b/apps/graph/storage_cartesian_function_store.h @@ -1,16 +1,16 @@ #ifndef GRAPH_STORAGE_CARTESIAN_FUNCTION_STORE_H #define GRAPH_STORAGE_CARTESIAN_FUNCTION_STORE_H -#include "storage_cartesian_function.h" +#include "../shared/storage_cartesian_function.h" #include "../shared/storage_function_store.h" #include #include namespace Graph { -class StorageCartesianFunctionStore : public Shared::StorageFunctionStore { +class StorageCartesianFunctionStore : public Shared::StorageFunctionStore { public: - static StorageCartesianFunction NullModel(); + static Shared::StorageCartesianFunction NullModel(); StorageCartesianFunctionStore(); /* StorageCartesianFunction activeCartesianFunctionAtIndex(int i) override { return (CartesianFunction *)Shared::FunctionStore::activeFunctionAtIndex(i); } diff --git a/apps/shared/Makefile b/apps/shared/Makefile index 291658b00..fac3c1f9a 100644 --- a/apps/shared/Makefile +++ b/apps/shared/Makefile @@ -50,6 +50,7 @@ app_objs += $(addprefix apps/shared/,\ scrollable_exact_approximate_expressions_view.o\ separator_even_odd_buffer_text_cell.o\ simple_interactive_curve_view_controller.o\ + storage_cartesian_function.o\ storage_expression_model.o\ storage_function.o\ storage_function_store.o\ diff --git a/apps/graph/storage_cartesian_function.cpp b/apps/shared/storage_cartesian_function.cpp similarity index 64% rename from apps/graph/storage_cartesian_function.cpp rename to apps/shared/storage_cartesian_function.cpp index b160fc48f..5eb1b51af 100644 --- a/apps/graph/storage_cartesian_function.cpp +++ b/apps/shared/storage_cartesian_function.cpp @@ -1,13 +1,12 @@ #include "storage_cartesian_function.h" -#include "../shared/storage_expression_model_store.h" -#include "../shared/poincare_helpers.h" +#include "storage_expression_model_store.h" +#include "poincare_helpers.h" #include #include using namespace Poincare; -using namespace Shared; -namespace Graph { +namespace Shared { void StorageCartesianFunction::DefaultName(char buffer[], size_t bufferSize) { /* a default name is "f[number].func", for instance "f12.func", that does not @@ -33,20 +32,21 @@ void StorageCartesianFunction::DefaultName(char buffer[], size_t bufferSize) { strlcpy(&buffer[dotCharIndex+1], GlobalContext::funcExtension, bufferSize - (dotCharIndex+1)); } -StorageCartesianFunction StorageCartesianFunction::NewModel(Ion::Storage::Record record) { - StorageCartesianFunction newFunction = StorageCartesianFunction(record); - newFunction.setColor(KDColorRed); - newFunction.setActive(true); - newFunction.setDisplayDerivative(true); - return newFunction; +StorageCartesianFunction StorageCartesianFunction::NewModel() { + char nameBuffer[100]; + DefaultName(nameBuffer, 100); + CartesianFunctionRecordData data; + Ion::Storage::Record::ErrorStatus r = Ion::Storage::sharedStorage()->createRecordWithFullName(nameBuffer, &data, sizeof(data)); + assert(r == Ion::Storage::Record::ErrorStatus::None); // TODO not a valid assertion! + return StorageCartesianFunction(Ion::Storage::sharedStorage()->recordNamed(nameBuffer)); } bool StorageCartesianFunction::displayDerivative() const { - return functionNode()->displayDerivative(); + return recordData()->displayDerivative(); } void StorageCartesianFunction::setDisplayDerivative(bool display) { - functionNode()->setDisplayDerivative(display); + return recordData()->setDisplayDerivative(display); } double StorageCartesianFunction::approximateDerivative(double x, Poincare::Context * context) const { @@ -83,9 +83,39 @@ Expression::Coordinate2D StorageCartesianFunction::nextIntersectionFrom(double s return reducedExp.nextIntersection(symbol(), start, step, max, *context, Preferences::sharedPreferences()->angleUnit(), reducedExp); } void StorageCartesianFunction::setContent(const char * c) { - Expression expressionToStore = StorageExpressionModel::contentFromString(c); -// TODO - StorageExpressionModel.setContentExpression(expressionToStore); + // Compute the expression to store + Expression expressionToStore = StorageExpressionModel::expressionToStoreFromString(c); + + // Prepare the new data to store + Ion::Storage::Record::Data newData = record().value(); + size_t expressionToStoreSize = expressionToStore.isUninitialized() ? 0 : expressionToStore.size(); + newData.size = sizeof(CartesianFunctionRecordData) + expressionToStoreSize; + + // Set the data + Ion::Storage::Record::ErrorStatus error = record().setValue(newData); + assert(error == Ion::Storage::Record::ErrorStatus::None); //TODO remove assertion and handle case + + // Copy the expression if needed + if (!expressionToStore.isUninitialized()) { + memcpy(expressionAddress(),expressionToStore.addressInPool(), expressionToStore.size()); + } + StorageExpressionModel::didSetContentData(); +} + +void * StorageCartesianFunction::expressionAddress() const { + return recordData()->expressionAddress(); +} + +size_t StorageCartesianFunction::expressionSize() const { + assert(!record().isNull()); + Ion::Storage::Record::Data d = record().value(); + return d.size-sizeof(FunctionRecordData); +} + +StorageCartesianFunction::CartesianFunctionRecordData * StorageCartesianFunction::recordData() const { + assert(!record().isNull()); + Ion::Storage::Record::Data d = record().value(); + return reinterpret_cast(const_cast(d.buffer)); } } diff --git a/apps/graph/storage_cartesian_function.h b/apps/shared/storage_cartesian_function.h similarity index 56% rename from apps/graph/storage_cartesian_function.h rename to apps/shared/storage_cartesian_function.h index 8f2abb916..f417253b4 100644 --- a/apps/graph/storage_cartesian_function.h +++ b/apps/shared/storage_cartesian_function.h @@ -1,22 +1,22 @@ -#ifndef GRAPH_STORAGE_CARTESIAN_FUNCTION_H -#define GRAPH_STORAGE_CARTESIAN_FUNCTION_H +#ifndef SHARED_STORAGE_CARTESIAN_FUNCTION_H +#define SHARED_STORAGE_CARTESIAN_FUNCTION_H -#include "../shared/global_context.h" -#include "../shared/storage_function.h" +#include "global_context.h" +#include "storage_function.h" #include -namespace Graph { +namespace Shared { -class StorageCartesianFunction : public Shared::StorageFunction { +class StorageCartesianFunction : public StorageFunction { public: - static const char * Extension() { return Shared::GlobalContext::funcExtension; } + static const char * Extension() { return GlobalContext::funcExtension; } static void DefaultName(char buffer[], size_t bufferSize); - static StorageCartesianFunction NewModel(Ion::Storage::Record record); + static StorageCartesianFunction NewModel(); StorageCartesianFunction(const char * text = nullptr) : - Shared::StorageFunction(text) + StorageFunction(text) {} StorageCartesianFunction(Ion::Storage::Record record) : - Shared::StorageFunction(record) + StorageFunction(record) {} bool operator==(const StorageCartesianFunction & other) const { return record() == other.record(); } bool operator!=(const StorageCartesianFunction & other) const { return !(*this == other); } @@ -27,13 +27,31 @@ public: Poincare::Expression::Coordinate2D nextMinimumFrom(double start, double step, double max, Poincare::Context * context) const; Poincare::Expression::Coordinate2D nextMaximumFrom(double start, double step, double max, Poincare::Context * context) const; double nextRootFrom(double start, double step, double max, Poincare::Context * context) const; - Poincare::Expression::Coordinate2D nextIntersectionFrom(double start, double step, double max, Poincare::Context * context, const Shared::StorageFunction * function) const; + Poincare::Expression::Coordinate2D nextIntersectionFrom(double start, double step, double max, Poincare::Context * context, const StorageFunction * function) const; const char * symbol() const override { static const char x[2] = {Poincare::Symbol::UnknownX, 0}; //TODO remove static return x; } // StorageExpressionModel void setContent(const char * c) override; + void * expressionAddress() const override; + size_t expressionSize() const override; +protected: + class CartesianFunctionRecordData : public FunctionRecordData { + public: + CartesianFunctionRecordData() : + FunctionRecordData(), + m_displayDerivative(true) + {} + bool displayDerivative() const { return m_displayDerivative; } + void setDisplayDerivative(bool display) { m_displayDerivative = display; } + void * expressionAddress() { return &m_expression; } + private: + bool m_displayDerivative; + char m_expression[0]; + }; +private: + CartesianFunctionRecordData * recordData() const; }; } diff --git a/apps/shared/storage_function_store.cpp b/apps/shared/storage_function_store.cpp index 0cfbae68f..94e3d234d 100644 --- a/apps/shared/storage_function_store.cpp +++ b/apps/shared/storage_function_store.cpp @@ -1,5 +1,5 @@ #include "storage_function_store.h" -#include +#include "storage_cartesian_function.h" #include namespace Shared { @@ -57,6 +57,6 @@ U StorageFunctionStore::firstAvailableAttribute(U attributes[], AttributeGett } //TODO specify templates -template class Shared::StorageFunctionStore; +template class Shared::StorageFunctionStore; /*template char const* const Shared::StorageFunctionStore::firstAvailableAttribute(char const* const*, char const* const (*)(Shared::StorageFunction)); template KDColor const Shared::StorageFunctionStore::firstAvailableAttribute(KDColor const*, KDColor const (*)(Shared::StorageFunction));*/