Display¶
Beschreibung¶
Display ist eine abstrakte Klasse, die als Schnittstelle zwischen Menü und dem Ausgabegerät fungiert.
Von dieser Klasse erbt DisplayTFTeSPI
Funktionen¶
virtual |
~Display () |
virtual void |
init () = 0 |
virtual void |
rect (const uint16_t pos_x, const uint16_t pos_y, const uint16_t width, const uint16_t height, const uint8_t border_size, const uint8_t border_radius, const Color& border_color, const Color& infill_color) = 0 |
virtual void |
rect_center (const uint16_t pos_x, const uint16_t pos_y, const uint16_t width, const uint16_t height, const uint8_t border_size, const uint8_t border_radius, const Color& border_color, const Color& infill_color) = 0 |
virtual void |
rect (const uint16_t pos_x, const uint16_t pos_y, const uint16_t width, const uint16_t height, const uint8_t border_size, const uint8_t border_radius, const Color& border_color) = 0 |
virtual void |
rect_center (const uint16_t pos_x, const uint16_t pos_y, const uint16_t width, const uint16_t height, const uint8_t border_size, const uint8_t border_radius, const Color& border_color) = 0 |
virtual void |
circle (const uint16_t pos_x, const uint16_t pos_y, const uint16_t d, const uint8_t border_size, const Color& border_color, const Color& infill_color) = 0 |
virtual void |
circle (const uint16_t pos_x, const uint16_t pos_y, const uint16_t d, const uint8_t border_size, const Color& border_color) = 0 |
virtual void |
triangle (const uint16_t pos_x0, const uint16_t pos_y0, const uint16_t pos_x1, const uint16_t pos_y1, const uint16_t pos_x2, const uint16_t pos_y2, const uint8_t border_size, const Color& border_color, const Color& infill_color) = 0 |
virtual void |
triangle (const uint16_t pos_x0, const uint16_t pos_y0, const uint16_t pos_x1, const uint16_t pos_y1, const uint16_t pos_x2, const uint16_t pos_y2, const uint8_t border_size, const Color& border_color) = 0 |
virtual void |
text (const uint16_t pos_x, const uint16_t pos_y, const uint16_t width, const uint16_t height, const char* text, const Color& text_color) = 0 |
virtual void |
text_center (const uint16_t pos_x, const uint16_t pos_y, const uint8_t text_size, const char* text, const Color& text_color) = 0 |
virtual void |
line (const uint16_t x1, const uint16_t y1, const uint16_t x2, const uint16_t y2, const Color& color) = 0 |
virtual void |
point (const uint16_t x1, const uint16_t y1, const Color& color) = 0 |
virtual void |
fillScreen (const Color& color) = 0 |
virtual void |
drawBitmap (const uint16_t x, const uint16_t y, const uint16_t w, const uint16_t h, const uint8_t* bitmap, const Color& fgcolor) = 0 |
virtual void |
drawBitmap (const uint16_t x, const uint16_t y, const uint16_t w, const uint16_t h, const uint8_t* bitmap, const Color& fgcolor, const Color& bgcolor) = 0 |
virtual int16_t |
getHeight () = 0 |
virtual int16_t |
getWidth () = 0 |
virtual uint8_t |
getRotation () = 0 |
virtual uint8_t |
setRotation (uint8_t rotation) = 0 |
virtual bool |
getTouch (uint16_t* x, uint16_t* y) = 0 |
virtual bool |
|
void |
drawItem (uint16_t x, uint16_t y, Item* item, const Color& color) |
void |
drawItem (uint16_t x, uint16_t y, Item* item) |
static „Item*“ |
createItem (const std::string str) |
static „Item*“ |
createItem (const std::string str, const Color& color) |
static „Color“ |
parseColor (const std::string& str, const Color& color) |
static std::string |
processText (const std::string& input) |
static uint16_t |
stringToNumber (const std::string& str, const uint16_t& value) |
static double |
stringToNumber (const std::string& str, const double& value) |
Funktionen Beschreibung¶
virtual ~Display()¶
Der Destruktor wird bei der Zerstörung eines Display Objektes aufgerufen.
virtual void init() = 0¶
Diese virtuelle Funktion muss von einer abgeleiteten Klasse überschrieben werden. (Siehe DisplayTFTeSPI)
virtual void rect(const uint16_t pos_x, const uint16_t pos_y, const uint16_t width, const uint16_t height, const uint8_t border_size, const uint8_t border_radius, const Color& border_color, const Color& infill_color) = 0¶
Diese virtuelle Funktion muss von einer abgeleiteten Klasse überschrieben werden. (Siehe DisplayTFTeSPI)
virtual void rect_center(const uint16_t pos_x, const uint16_t pos_y, const uint16_t width, const uint16_t height, const uint8_t border_size, const uint8_t border_radius, const Color& border_color, const Color& infill_color) = 0¶
Diese virtuelle Funktion muss von einer abgeleiteten Klasse überschrieben werden. (Siehe DisplayTFTeSPI)
virtual void rect(const uint16_t pos_x, const uint16_t pos_y, const uint16_t width, const uint16_t height, const uint8_t border_size, const uint8_t border_radius, const Color& border_color) = 0¶
Diese virtuelle Funktion muss von einer abgeleiteten Klasse überschrieben werden. (Siehe DisplayTFTeSPI)
virtual void rect_center(const uint16_t pos_x, const uint16_t pos_y, const uint16_t width, const uint16_t height, const uint8_t border_size, const uint8_t border_radius, const Color& border_color) = 0¶
Diese virtuelle Funktion muss von einer abgeleiteten Klasse überschrieben werden. (Siehe DisplayTFTeSPI)
virtual void circle(const uint16_t pos_x, const uint16_t pos_y, const uint16_t d, const uint8_t border_size, const Color& border_color, const Color& infill_color) = 0¶
Diese virtuelle Funktion muss von einer abgeleiteten Klasse überschrieben werden. (Siehe DisplayTFTeSPI)
virtual void circle(const uint16_t pos_x, const uint16_t pos_y, const uint16_t d, const uint8_t border_size, const Color& border_color) = 0¶
Diese virtuelle Funktion muss von einer abgeleiteten Klasse überschrieben werden. (Siehe DisplayTFTeSPI)
virtual void triangle(const uint16_t pos_x0, const uint16_t pos_y0, const uint16_t pos_x1, const uint16_t pos_y1, const uint16_t pos_x2, const uint16_t pos_y2, const uint8_t border_size, const Color& border_color, const Color& infill_color) = 0¶
Diese virtuelle Funktion muss von einer abgeleiteten Klasse überschrieben werden. (Siehe DisplayTFTeSPI)
virtual void triangle(const uint16_t pos_x0, const uint16_t pos_y0, const uint16_t pos_x1, const uint16_t pos_y1, const uint16_t pos_x2, const uint16_t pos_y2, const uint8_t border_size, const Color& border_color) = 0¶
Diese virtuelle Funktion muss von einer abgeleiteten Klasse überschrieben werden. (Siehe DisplayTFTeSPI)
virtual void text(const uint16_t pos_x, const uint16_t pos_y, const uint16_t width, const uint16_t height, const char* text, const Color& text_color) = 0¶
Diese virtuelle Funktion muss von einer abgeleiteten Klasse überschrieben werden. (Siehe DisplayTFTeSPI)
virtual void text_center(const uint16_t pos_x, const uint16_t pos_y, const uint8_t text_size, const char* text, const Color& text_color) = 0¶
Diese virtuelle Funktion muss von einer abgeleiteten Klasse überschrieben werden. (Siehe DisplayTFTeSPI)
virtual void line(const uint16_t x1, const uint16_t y1, const uint16_t x2, const uint16_t y2, const Color& color) = 0¶
Diese virtuelle Funktion muss von einer abgeleiteten Klasse überschrieben werden. (Siehe DisplayTFTeSPI)
virtual void point(const uint16_t x1, const uint16_t y1, const Color& color) = 0¶
Diese virtuelle Funktion muss von einer abgeleiteten Klasse überschrieben werden. (Siehe DisplayTFTeSPI)
virtual void fillScreen (const Color& color) = 0¶
Diese virtuelle Funktion muss von einer abgeleiteten Klasse überschrieben werden. (Siehe DisplayTFTeSPI)
virtual void drawBitmap(const uint16_t x, const uint16_t y, const uint16_t w, const uint16_t h, const uint8_t* bitmap, const Color& fgcolor) = 0¶
Diese virtuelle Funktion muss von einer abgeleiteten Klasse überschrieben werden. (Siehe DisplayTFTeSPI)
virtual void drawBitmap(const uint16_t x, const uint16_t y, const uint16_t w, const uint16_t h, const uint8_t* bitmap, const Color& fgcolor, const Color& bgcolor) = 0¶
Diese virtuelle Funktion muss von einer abgeleiteten Klasse überschrieben werden. (Siehe DisplayTFTeSPI)
virtual int16_t getHeight() = 0¶
Diese virtuelle Funktion muss von einer abgeleiteten Klasse überschrieben werden. (Siehe DisplayTFTeSPI)
virtual int16_t getWidth() = 0¶
Diese virtuelle Funktion muss von einer abgeleiteten Klasse überschrieben werden. (Siehe DisplayTFTeSPI)
virtual uint8_t getRotation() = 0¶
Diese virtuelle Funktion muss von einer abgeleiteten Klasse überschrieben werden. (Siehe DisplayTFTeSPI)
virtual void setRotation(uint8_t rotation) = 0¶
Diese virtuelle Funktion muss von einer abgeleiteten Klasse überschrieben werden. (Siehe DisplayTFTeSPI)
virtual bool getTouch(uint16_t* x, uint16_t* y) = 0¶
Diese virtuelle Funktion muss von einer abgeleiteten Klasse überschrieben werden. (Siehe DisplayTFTeSPI)
virtual void startTouchCalibration() {}¶
1 virtual void startTouchCalibration() {};
Diese virtuelle Funktion muss von einer abgeleiteten Klasse überschrieben werden. (Siehe DisplayTFTeSPI)
void drawItem (uint16_t x, uint16_t y, Item* item, const Color& color)¶
1void Display::drawItem (uint16_t x, uint16_t y, Item* item, const Color& color) {
2 item->draw(x, y, this, color);
3}
Diese Funktion ruft die draw Funktion der Item Klasse auf, um ein Item Objekt in einer Farbe (color) auf dem aktuellen Display (this) bei
gewünschten X- und Y-Koordinaten zu zeichnen.
void drawItem (uint16_t x, uint16_t y, Item* item)¶
1void Display::drawItem (uint16_t x, uint16_t y, Item* item) {
2 item->draw(x, y, this);
3}
Diese Funktion ruft die draw Funktion der Item Klasse auf, um ein Item Objekt auf dem aktuellen Display (this) bei
gewünschten X- und Y-Koordinaten zu zeichnen.
static Item* createItem(const std::string str)¶
1Item* Display::createItem(const std::string str) {
2 return createItem(str, Color(0,0,0));
3}
Diese Funktion ruft die createItem Funktion auf, um ein Item aus einem String in der Standardfarbe schwarz zu erstellen.
Der String muss dabei in der Form type:name angegeben werden. Für type kann u.a. zwischen icon (um ein Icon zu erstellen), symb (um ein Symbol zu erstellen),
text (um einen Text zu erstellen) und file entschieden werden. Für name hingegen kann ein beliebiger Name gewählt werden. Namen dürfen auch doppelt gewählt werden.
static Item* createItem(const std::string str, const Color& color)¶
1Item* Display::createItem(const std::string str, const Color& defaultColor) {
2 std::string type, name;
3 double size = 0.0, scale = 1;
4 uint16_t width = 2, height = 2;
5
6 Color color = Color(defaultColor);
7 std::istringstream iss(str);
8 std::string word;
9
10 if (str == "") return new Text("", size);
11
12 while (iss >> word) {
13 size_t colonPos = word.find(':');
14 if (colonPos != std::string::npos) {
15 std::string key = word.substr(0, colonPos);
16 std::string value = word.substr(colonPos + 1);
17
18 // set type and his name (e.g. icon:settings)
19 if (type == "" && (key == "icon" || key == "file" || key == "symb" || key == "text")) {
20 type = key;
21 name = (key == "text") ? processText(value) : value;
22 }
23
24
25 // Find and set other parameters
26 else if (key == "color") {
27 color.setPrimaryColor(parseColor(value, color));
28 } else if (key == "border") {
29 color.setBorderColor(parseColor(value, color.getBorderColor()));
30 } else if (key == "size") {
31 // size = stringToNumber(value, size );
32 } else if (key == "height") {
33 // height = stringToNumber(value, height );
34 } else if (key == "width") {
35 // width = stringToNumber(value, width );
36 } else if (key == "scale") {
37 // scale = stringToNumber(value, scale );
38 }
39 }
40
41 // if no type was defined at the beginning, set type to text and end search for other parameters
42 if (type == "") {
43 type = "text";
44 name = str;
45 break;
46 }
47 }
48
49 if (name == "") return new Text("No Name", size, COLOR_RED);
50 else if (type == "") return new Text("No type", size, COLOR_RED);
51
52 else if (type == "text")
53 return new Text(name.c_str(), size, color);
54
55 else if (type=="icon") {
56 auto* icon = Icon::create(name, scale, color);
57 if (icon) return icon;
58 else return new Text("NOT FOUND", size, COLOR_RED);
59
60 // } else if (type == "file") { // TODO: implement loading and displaying bitmaps from memory
61
62 } else if (type == "symb") {
63 return Symbol::create(name, (uint16_t) height, (uint16_t) width, color, size, scale);
64 }
65
66 return new Text("ERR", 2, COLOR_RED);
67}
Diese Funktion erstellt ein Item aus einem String in einer spezifischen Farbe (defaultColor).
Der String muss dabei in der Form type:name angegeben werden. Für type kann u.a. zwischen icon (um ein Icon zu erstellen), symb (um ein Symbol zu erstellen),
text (um einen Text zu erstellen) und file entschieden werden. Für name hingegen kann ein beliebiger Name gewählt werden. Namen dürfen auch doppelt gewählt werden.
std::string type, name;
double size = 0.0, scale = 1;
uint16_t width = 2, height = 2;
Zuerst werden die zwei Strings type und name erstellt, in denen später der eingegebene Typ und Name gespeichert wird.
Die Variable size legt bei der späteren Erstellung eines Icons /Symbols /Texts die Größe, scale den Skalierungsfaktor von Icons /Symbolen
und width und height die Breite und Höhe von Symbolen fest.
Color color = Color(defaultColor);
std::istringstream iss(str);
std::string word;
Wir kopieren die defaultColor in eine neue Color color mithilfe des Color Konstruktors, um später potenziell einige Änderungen daran zu machen.
Außerdem wird mit std::istringstream der Eingabestring str verarbeitet, um die einzelnen Komponenten (also type, : und name)
identifizieren und aufteilen zu können. Der String word wird ebenfalls für diese Identifikation genutzt werden.
if (str == "") return new Text("", size);
Sollte kein String eingegeben worden sein, so wird ein leerer Text zurückgegeben.
while (iss >> word) {
size_t colonPos = word.find(':');
if (colonPos != std::string::npos) {
std::string key = word.substr(0, colonPos);
std::string value = word.substr(colonPos + 1);
Die while Schleife liest die einzelnen Komponenten aus iss und speichert sie in word. In colonPos wird dann die Position des Doppelpunktes innerhalb von word gespeichert. Nun lässt
sich identifizieren, wo sich type und name befinden. In key wird schließlich das Schlüsselwort gespeichert, welches auf den type schließen lässt. In value wird schließlich der name identifiziert und gespeichert.
if (type == "" && (key == "icon" || key == "file" || key == "symb" || key == "text")) {
type = key;
name = (key == "text") ? processText(value) : value;
}
Anschließend wird in type key gespeichert, solange key eine der genannten Möglichkeiten ist und solange in type nicht bereits ein anderer Wert gespeichert ist.
Sollte key den Wert "text" haben, wird value durch processText verarbeitet und das Ergebnis wird in name gespeichert. value bzw. name
enstspricht dann einem Text, der angezeigt werden soll (Wichtig zu beachten ist, dass Text in der Form text:hello_world und nicht test:hello world angegeben werden müssen, mehr dazu in der entsprechenden Funktion). Wenn dies nicht der Fall ist, wird value direkt in name kopiert.
else if (key == "color") {
color.setPrimaryColor(parseColor(value, color));
} else if (key == "border") {
color.setBorderColor(parseColor(value, color.getBorderColor()));
} else if (key == "size") {
// size = stringToNumber(value, size );
} else if (key == "height") {
// height = stringToNumber(value, height );
} else if (key == "width") {
// width = stringToNumber(value, width );
} else if (key == "scale") {
// scale = stringToNumber(value, scale );
}
}
Mithilfe dieses Codeblocks können auch andere Parameter identifiziert und erstellt werden. So kann mit dem key "color" die Hauptfarbe von color
(siehe parseColor, setPrimaryColor) oder mit "border" die Umrandungsfarbe von color
(siehe parseColor, setBorderColor) verändert werden.
if (type == "") {
type = "text";
name = str;
break;
}
}
Falls kein type definiert wurde, wird es standardmäßig auf "text" gesetzt und die While Schleife wird abgebrochen.
if (name == "") return new Text("No Name", size, COLOR_RED);
else if (type == "") return new Text("No type", size, COLOR_RED);
Falls kein name oder type spezifiziert wurde, wird ein Warnhinweis auf dem Display gezeichnet.
else if (type == "text")
return new Text(name.c_str(), size, color);
Wenn der type "text" ist, so wird mit dem Text Konstruktor ein Text Objekt mit name als Textinhalt erstellt.
else if (type=="icon") {
auto* icon = Icon::create(name, scale, color);
if (icon) return icon;
else return new Text("NOT FOUND", size, COLOR_RED);
Wenn der type "icon" ist, so wird die create Funktion für ein neues Icon Objekt icon aufgerufen.
else if (type=="icon") {
auto* icon = Icon::create(name, scale, color);
if (icon) return icon;
else return new Text("NOT FOUND", size, COLOR_RED);
Wenn der type "symb" ist, so wird die create Funktion ein neues Symbol Objekt erstellt.
return new Text("ERR", 2, COLOR_RED);
Sollte keines der oben genannten Objekte erstellt werden können, weil die Bedinungen nicht erfüllt sind, wird eine Fehlermeldung auf dem Display angezeigt.
Color parseColor(const std::string& str, const Color& color)¶
1Color Display::parseColor(const std::string& str, const Color& color) {
2
3 if (str == "yellow") return Color(255, 255, 0);
4 if (str == "gray") return Color(50, 50, 50);
5 if (str == "red") return Color(255, 0, 50);
6
7 std::stringstream ss(str);
8 std::string token;
9 size_t arrayPos = 0;
10 std::array<uint8_t, 3> rgb;
11 rgb.fill(0);
12 while (std::getline(ss, token, ',')) {
13 rgb[arrayPos++] = std::atoi(token.c_str());
14 if (arrayPos > 3) break;
15 }
16
17 if (arrayPos != 0) return Color(rgb[0], rgb[1], rgb[2]);
18
19 // else return default color
20 return color;
21}
Diese Funktion wird von der createItem Funktion aufgerufen, um aus dem dort ermittelten value eine Farbe zu identifizieren.
Dieser String str kann in der Form r,g,b angegeben werden, wobei jeweils natürliche Zahlen von 0 bis 255 anstelle von r, g und b eingegeben werden müssen
(z.B. 255,255,255 für weiß).
if (str == "yellow") return Color(255, 255, 0);
if (str == "gray") return Color(50, 50, 50);
if (str == "red") return Color(255, 0, 50);
Eine weitere Methode ist die direkte Eingabe der gewünschten Farbe, wobei standardmäßig nur die Farben Gelb, Grau und Rot implementiert sind. Bei Eingabe der entsprechenden Strings, wird dieser Color Konstruktor aufgerufen, um die richtige Farbe zurückzugeben.
std::stringstream ss(str);
std::string token;
Nun wird mit std::istringstream der Eingabestring str verarbeitet, um die einzelnen Komponenten (also r, ,, g, ,, b)
identifizieren und aufteilen zu können. Der String token wird ebenfalls für diese Identifikation genutzt werden.
size_t arrayPos = 0;
std::array<uint8_t, 3> rgb;
rgb.fill(0);
In dem Array rgb sollen die RGB Werte einzeln gespeichert werden.
Die Variable arrayPos wird u.a. zum iterieren dieses Arrays genutzt. Das Array wird außerdem vollständig mit 0 gefüllt, um Fehler zu vermeiden.
while (std::getline(ss, token, ',')) {
rgb[arrayPos++] = std::atoi(token.c_str());
if (arrayPos > 3) break;
}
In diesem Codeabschnitt werden die einzelnen Werte für r, g und b in das rgb Array gelegt und das so lange, bis alle drei Werte im Array liegen.
if (arrayPos != 0) return Color(rgb[0], rgb[1], rgb[2]);
Nach Durchlaufen der while Schleife wird schließlichaus mit den Werten im rgb Array durch den Aufruf des Color Konstruktors ein neues ein neues Color Objekt zurückgegeben.
return color;
Sollte die while Schleife nicht durchlaufen worden sein, wird color genauso wiederzurückgegeben.
std::string processText(const std::string& input)¶
1std::string Display::processText(const std::string& input) {
2 std::string result = input;
3
4 // 1. replace "__" with "#@@$~"
5 size_t doubleUnderscorePos;
6 while ((doubleUnderscorePos = result.find("__")) != std::string::npos) {
7 result.replace(doubleUnderscorePos, 2, "#@@$~");
8 }
9
10 // 2. replace '_' with ' '
11 size_t underscorePos;
12 while ((underscorePos = result.find("_")) != std::string::npos) {
13 result.replace(underscorePos, 1, " ");
14 }
15
16 // 3. replace "#@@$~" with '_'
17 size_t hashPos;
18 while ((hashPos = result.find("#@@$~")) != std::string::npos) {
19 result.replace(hashPos, 5, "_");
20 }
21
22 return result;
23}
Diese Funktion wird von der createItem Funktion aufgerufen, um aus dem dort ermittelten value einen Text zu identifizieren.
Texte müssen in der Form hello_world angegeben werden und nicht in der Form hello world. Ersteres erzeugt den Output hello world während zweiteres nichts nach dem Wort hello ausgibt.
size_t doubleUnderscorePos;
while ((doubleUnderscorePos = result.find("__")) != std::string::npos) {
result.replace(doubleUnderscorePos, 2, "#@@$~");
}
Möchte man in seiner Ausgabe einen Unterstrich _ mit einbauen, so muss in der Eingabe ein doppelter Unterstrich __ angegeben werden. Dieser wird zunächst
durch ein Platzhalter Symbol #@@$~ ersetzt. Die Umwandlung zu einem einfachen Unterstrich _ erfolgt im übernächsten Codeabschnitt.
size_t underscorePos;
while ((underscorePos = result.find("_")) != std::string::npos) {
result.replace(underscorePos, 1, " ");
}
Zunächst erfolgt jedoch die Umwandlung des einfachen Unterstrichs _ zu einem Leerzeichen, um eine Ausgabe wie sie im Einleitungsteil dieser Funktion beschrieben ist, zu erhalten.
size_t hashPos;
while ((hashPos = result.find("#@@$~")) != std::string::npos) {
result.replace(hashPos, 5, "_");
}
Schließlich erfolgt die Umwandlung des Plazhalters #@@$~ zum einfachen Unterstrich _.
Sollte es gewünscht sein, dass die Ausgabe einen doppelten Unterstrich enthält, muss ein vierfacher Unterstrich ____ in der Eingabe verwendet werden, für einen dreifachen Unterstrich ein sechsfacher etc.
return result;
Das Ergebnis wird zurückgegeben.
static uint16_t stringToNumber(const std::string& str, const uint16_t& value)¶
1uint16_t Display::stringToNumber(const std::string& str, const uint16_t& value) {
2 if (str == "") return value;
3
4 uint16_t result = 0;
5 for (char c : str) {
6 if (c >= '0' && c <= '9') {
7 result *= 10;
8 result += (c - '0');
9 }
10 else if (c == '.') break;
11 else return value;
12 }
13
14 return result;
15}
static double stringToNumber(const std::string& str, const double& value)¶
1double Display::stringToNumber(const std::string& str, const double& value) {
2 size_t dotPos = str.find('.');
3
4 if (dotPos == std::string::npos) {
5 auto number = stringToNumber(str, static_cast<double>(UINT16_MAX));
6 if (number == UINT16_MAX) return value;
7 else return static_cast<double>(number);
8 }
9
10 uint16_t intResult = stringToNumber(str.substr(0, dotPos), static_cast<double>(UINT16_MAX));
11 uint16_t decimalResult = stringToNumber(str.substr(dotPos + 1), static_cast<double>(UINT16_MAX));
12 double result = 0.0;
13
14 if (intResult == UINT16_MAX && decimalResult == UINT16_MAX) return value;
15 if (intResult != UINT16_MAX) result += intResult;
16 if (decimalResult != UINT16_MAX) result += static_cast<float>(decimalResult) / std::pow(10, (int) log10(decimalResult));
17
18 return result;
19}