-
-
Notifications
You must be signed in to change notification settings - Fork 955
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
weather: Add function for converting to units #2015
Conversation
Build size and comparison to main:
|
d8a0959
to
f07699a
Compare
You could use structs of one int to make the types really safe. |
I'm ok with the current state. I however thought about another option. SimpleWeatherService would define a Temperature type : struct Temperature {
int16_t temperature;
} Somewhere under DisplayApp, we would define another Temperature type : struct TemperatureCelsius {
int16_t temperature;
}
struct TemperatureFahrenheit {
int16_t temperature;
}
using Temperature = std::variant<TemperatureCelsius, TemperatureFahrenheit temperature Then, also under DisplayApp, we define a function that converts from SimpleWeatherService Temperature to "display" temperature : Pinetime::Applications::Temperature Convert(PineTime::Controllers::SimpleWeatherService::Temperature, Controllers::Settings::WeatherFormat format); This way, all the "temperature" types are strongly typed and it's impossible to implicitly convert from one to another. Also SimpleWeatherService does not have any code related to the UI anymore. |
There is now a Temperature struct in the weather service, which holds the internal representation. There is also a temperature struct in the Applications namespace, which holds the temperature in either Celsius or Fahrenheit.
f07699a
to
b9fd12e
Compare
b9fd12e
to
2462696
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@JF002 I've just refactored this a bit, what do you think? I wasn't able to use std::variant
, as it is very strict about knowing which variant to use at compile-time. That meant that we needed 2 completely separate code paths for Celsius and Fahrenheit.
@@ -61,13 +61,42 @@ namespace Pinetime { | |||
Unknown = 255 | |||
}; | |||
|
|||
class Temperature { | |||
public: | |||
explicit Temperature(int16_t raw = 0) : raw {raw} { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not a big fan of having the default value be 0 here, but otherwise the compiler complains about there being no default value for the array of Day
s in the Forecast
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be conceptually better (maybe not memory-wise) to make the days array of type:
std::array<std::optional<Day>, nbOfDays>
. Then you would not need to construct Day
s without values.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would defining Temperature in Kelvin internally and converting to DisplayTemperature in °C or °F depending on the user setting for displaying be helpful?
Sorry, I'm not into object based programming that much...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think that is the problem here. The internal representation is never shown directly and can therefore be whatever. The problem is, that right now we need a temperature value in a place where no value should be.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think std::optional
does make sense, I'm going to see how implementing it like that looks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this works quite well, what do you think?
I like the current approach with the raw value and the two representations! :) |
Also only iterate over the number of days actually in use, rather than MaxNbForecastDays.
int16_t minTemp = optCurrentForecast->days[i].minTemperature; | ||
lv_table_set_cell_type(forecast, 2, i, TemperatureStyle(maxTemp)); | ||
lv_table_set_cell_type(forecast, 3, i, TemperatureStyle(minTemp)); | ||
for (int i = 0; i < optCurrentForecast->nbDays; i++) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should be correct to use nbDays rather than MaxNbForecastDays here, but we should test it before merging.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
Handles rounding correctly.