[graph] Do not keep a function pointer as member variable but a record.

Indeed, function pointers can become invalid at any point...
This commit is contained in:
Émilie Feral
2018-10-16 17:56:16 +02:00
parent 974519f61a
commit c70278941a
61 changed files with 510 additions and 401 deletions

View File

@@ -6,10 +6,9 @@ using namespace Shared;
namespace Graph {
IntersectionGraphController::IntersectionGraphController(Responder * parentResponder, GraphView * graphView, BannerView * bannerView, Shared::InteractiveCurveViewRange * curveViewRange, CurveViewCursor * cursor, StorageCartesianFunctionStore * store) :
IntersectionGraphController::IntersectionGraphController(Responder * parentResponder, GraphView * graphView, BannerView * bannerView, Shared::InteractiveCurveViewRange * curveViewRange, CurveViewCursor * cursor) :
CalculationGraphController(parentResponder, graphView, bannerView, curveViewRange, cursor, I18n::Message::NoIntersectionFound),
m_intersectedFunction(nullptr),
m_functionStore(store)
m_intersectedRecord()
{
}
@@ -19,16 +18,18 @@ const char * IntersectionGraphController::title() {
void IntersectionGraphController::reloadBannerView() {
m_bannerView->setNumberOfSubviews(2);
reloadBannerViewForCursorOnFunction(m_cursor, m_function, 'x');
reloadBannerViewForCursorOnFunction(m_cursor, m_record, functionStore(), 'x');
constexpr size_t bufferSize = FunctionBannerDelegate::k_maxNumberOfCharacters+Poincare::PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits);
char buffer[bufferSize];
const char * space = " ";
const char * legend = "=";
// 'f(x)=g(x)=', keep 2 chars for '='
int numberOfChar = m_function->nameWithArgument(buffer, bufferSize-2, 'x');
StorageCartesianFunction * f = functionStore()->modelForRecord(m_record);
int numberOfChar = f->nameWithArgument(buffer, bufferSize-2, 'x');
numberOfChar += strlcpy(buffer+numberOfChar, legend, bufferSize-numberOfChar);
// keep 1 char for '=';
numberOfChar += m_intersectedFunction->nameWithArgument(buffer, bufferSize-numberOfChar-1, 'x');
StorageCartesianFunction * g = functionStore()->modelForRecord(m_intersectedRecord);
numberOfChar += g->nameWithArgument(buffer, bufferSize-numberOfChar-1, 'x');
numberOfChar += strlcpy(buffer+numberOfChar, legend, bufferSize-numberOfChar);
numberOfChar += PoincareHelpers::ConvertFloatToText<double>(m_cursor->y(), buffer+numberOfChar, bufferSize-numberOfChar, Constant::MediumNumberOfSignificantDigits);
strlcpy(buffer+numberOfChar, space, bufferSize-numberOfChar);
@@ -37,12 +38,13 @@ void IntersectionGraphController::reloadBannerView() {
Poincare::Expression::Coordinate2D IntersectionGraphController::computeNewPointOfInterest(double start, double step, double max, Poincare::Context * context) {
Poincare::Expression::Coordinate2D result = {.abscissa = NAN, .value = NAN};
for (int i = 0; i < m_functionStore->numberOfActiveFunctions(); i++) {
StorageFunction * f = m_functionStore->activeFunctionAtIndex(i);
if (f != m_function) {
Poincare::Expression::Coordinate2D intersection = m_function->nextIntersectionFrom(start, step, max, context, f);
for (int i = 0; i < functionStore()->numberOfActiveFunctions(); i++) {
Ion::Storage::Record record = functionStore()->activeRecordAtIndex(i);
if (record != m_record) {
StorageCartesianFunction * f = functionStore()->modelForRecord(record);
Poincare::Expression::Coordinate2D intersection = f->nextIntersectionFrom(start, step, max, context, f);
if ((std::isnan(result.abscissa) || std::fabs(intersection.abscissa-start) < std::fabs(result.abscissa-start)) && !std::isnan(intersection.abscissa)) {
m_intersectedFunction = f;
m_intersectedRecord = record;
result = (std::isnan(result.abscissa) || std::fabs(intersection.abscissa-start) < std::fabs(result.abscissa-start)) ? intersection : result;
}
}