Files
Upsilon/apps/calculation/calculation.h
Yaya-Cout d1b8cefcf9 Merge pull request #254 from RedGl0w/additional_result_trigo
Changes to the trigonometry additional result
2025-11-05 17:17:44 +00:00

118 lines
3.8 KiB
C++

#ifndef CALCULATION_CALCULATION_H
#define CALCULATION_CALCULATION_H
#include <apps/constant.h>
#include <escher.h>
#include <poincare/context.h>
#include <poincare/expression.h>
#include "../shared/poincare_helpers.h"
namespace Calculation {
class CalculationStore;
/* A calculation is:
* | uint8_t |KDCoordinate| KDCoordinate | uint8_t | ... | ... | ... |
* |m_displayOutput| m_height |m_expandedHeight|m_equalSign|m_inputText|m_exactOuputText|m_approximateOuputText|
*
* */
class Calculation {
friend CalculationStore;
public:
static constexpr int k_numberOfExpressions = 4;
enum class EqualSign : uint8_t {
Unknown,
Approximation,
Equal
};
enum class DisplayOutput : uint8_t {
Unknown,
ExactOnly,
ApproximateOnly,
ExactAndApproximate,
ExactAndApproximateToggle
};
enum class AdditionalInformationType {
None = 0,
Integer,
Rational,
SecondDegree,
TrigonometryInput,
TrigonometryOutput,
Unit,
Matrix,
Complex
};
static bool DisplaysExact(DisplayOutput d) { return d != DisplayOutput::ApproximateOnly; }
/* It is not really the minimal size, but it clears enough space for most
* calculations instead of clearing less space, then fail to serialize, clear
* more space, fail to serialize, clear more space, etc., until reaching
* sufficient free space. */
static int MinimalSize() { return sizeof(uint8_t) + 2*sizeof(KDCoordinate) + sizeof(uint8_t) + 3*Constant::MaxSerializedExpressionSize + sizeof(Calculation *); }
Calculation() :
m_displayOutput(DisplayOutput::Unknown),
m_height(-1),
m_expandedHeight(-1),
m_equalSign(EqualSign::Unknown)
{
assert(sizeof(m_inputText) == 0);
}
bool operator==(const Calculation& c);
Calculation * next() const;
// Texts
enum class NumberOfSignificantDigits {
Maximal,
UserDefined
};
const char * inputText() const { return m_inputText; }
const char * exactOutputText() const { return m_inputText + strlen(m_inputText) + 1; }
// See comment in approximateOutput implementation explaining the need of two approximateOutputTexts
const char * approximateOutputText(NumberOfSignificantDigits numberOfSignificantDigits) const;
// Expressions
Poincare::Expression input();
Poincare::Expression exactOutput();
Poincare::Expression approximateOutput(Poincare::Context * context, NumberOfSignificantDigits numberOfSignificantDigits);
// Layouts
Poincare::Layout createInputLayout();
Poincare::Layout createExactOutputLayout(bool * couldNotCreateExactLayout);
Poincare::Layout createApproximateOutputLayout(Poincare::Context * context, bool * couldNotCreateApproximateLayout);
// Heights
KDCoordinate height(bool expanded);
// Displayed output
DisplayOutput displayOutput(Poincare::Context * context);
void forceDisplayOutput(DisplayOutput d);
bool shouldOnlyDisplayExactOutput();
EqualSign exactAndApproximateDisplayedOutputsAreEqual(Poincare::Context * context);
// Additional Information
AdditionalInformationType additionalInformationType(Poincare::Context * context);
private:
static constexpr KDCoordinate k_heightComputationFailureHeight = 50;
static constexpr const char * k_maximalIntegerWithAdditionalInformation = "18446744073709551617"; // 2^64 + 1
void setHeights(KDCoordinate height, KDCoordinate expandedHeight);
/* Buffers holding text expressions have to be longer than the text written
* by user (of maximum length TextField::maxBufferSize()) because when we
* print an expression we add omitted signs (multiplications, parenthesis...) */
DisplayOutput m_displayOutput;
KDCoordinate m_height __attribute__((packed));
KDCoordinate m_expandedHeight __attribute__((packed));
EqualSign m_equalSign;
char m_inputText[0]; // MUST be the last member variable
};
}
#endif