From 9f1885d8078754c8dee2f7543679fbed745e1fe7 Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Sat, 16 Dec 2017 23:10:45 -0200 Subject: [PATCH] weather-service: use GPtrArray for public API Using GLists and GSLists is a bad practice. These data structures are too much inneficient and GPtrArray has the advantage of having a free function pointer, so we can hide the underlying free function from the consumers of this API. This also gets rid of another allocation cycle in Month view. --- src/gcal-weather-service.c | 26 +++++-------- src/gcal-weather-service.h | 2 +- src/views/gcal-month-view.c | 74 ++++++++++++++++-------------------- src/views/gcal-week-header.c | 32 ++++++++-------- src/views/gcal-week-view.c | 4 +- src/views/gcal-year-view.c | 19 +++++---- 6 files changed, 71 insertions(+), 86 deletions(-) diff --git a/src/gcal-weather-service.c b/src/gcal-weather-service.c index e2e31250..bbf91b06 100644 --- a/src/gcal-weather-service.c +++ b/src/gcal-weather-service.c @@ -92,7 +92,7 @@ struct _GcalWeatherService gboolean location_service_running; /* weather: */ - GSList *weather_infos; /* owned[owned] */ + GPtrArray *weather_infos; /* owned[owned] */ gint64 weather_infos_upated; gint64 valid_timespan; GWeatherInfo *gweather_info; /* owned, nullable */ @@ -559,13 +559,13 @@ update_gclue_location (GcalWeatherService *self, g_clear_pointer (&wlocation, gweather_location_unref); } -static GSList* +static GPtrArray* preprocess_gweather_reports (GcalWeatherService *self, GSList *samples) { GWeatherInfo *first_tomorrow = NULL; /* unowned */ + GPtrArray *result = NULL; GSList **days = NULL; /* owned[owned[unowned]] */ - GSList *result = NULL; /* owned[owned] */ GSList *iter = NULL; /* unowned */ GDate cur_gdate; glong first_tomorrow_dtime = -1; @@ -585,6 +585,7 @@ preprocess_gweather_reports (GcalWeatherService *self, if (!get_time_day_start (self, &cur_gdate, &today_unix, &unix_now)) return NULL; + result = g_ptr_array_new_full (self->max_days, g_object_unref); days = g_malloc0 (sizeof (GSList*) * self->max_days); /* Split samples to max_days buckets: */ @@ -635,7 +636,7 @@ preprocess_gweather_reports (GcalWeatherService *self, secs_left_today = DAY_SECONDS - (unix_now - today_unix); secs_between = first_tomorrow_dtime - unix_now; - if (secs_left_today < 90*60 && secs_between <= 180*60) + if (secs_left_today < 90 * 60 && secs_between <= 180 * 60) days[0] = g_slist_prepend (days[0], first_tomorrow); } @@ -646,12 +647,7 @@ preprocess_gweather_reports (GcalWeatherService *self, g_autofree gchar *temperature; if (compute_weather_info_data (days[i], i == 0, &icon_name, &temperature)) - { - GcalWeatherInfo* gcwi; - - gcwi = gcal_weather_info_new (&cur_gdate, icon_name, temperature); - result = g_slist_prepend (result, g_steal_pointer (&gcwi)); - } + g_ptr_array_add (result, gcal_weather_info_new (&cur_gdate, icon_name, temperature)); g_date_add_days (&cur_gdate, 1); } @@ -921,8 +917,7 @@ update_weather (GcalWeatherService *self, { if (!reuse_old_on_error || !has_valid_weather_infos (self)) { - g_slist_free_full (self->weather_infos, g_object_unref); - self->weather_infos = NULL; + g_clear_pointer (&self->weather_infos, g_ptr_array_unref); self->weather_infos_upated = -1; g_signal_emit (self, signals[SIG_WEATHER_CHANGED], 0); @@ -930,7 +925,7 @@ update_weather (GcalWeatherService *self, } else if (gwforecast) { - g_slist_free_full (self->weather_infos, g_object_unref); + g_clear_pointer (&self->weather_infos, g_ptr_array_unref); self->weather_infos = preprocess_gweather_reports (self, gwforecast); self->weather_infos_upated = g_get_monotonic_time (); @@ -953,13 +948,12 @@ gcal_weather_service_finalize (GObject *object) g_clear_pointer (&self->duration_timer, gcal_timer_free); g_clear_pointer (&self->midnight_timer, gcal_timer_free); g_clear_pointer (&self->timezone, g_time_zone_unref); + g_clear_pointer (&self->weather_infos, g_ptr_array_unref); g_clear_object (&self->gweather_info); g_clear_object (&self->location_service); g_clear_object (&self->location_cancellable); - g_slist_free_full (self->weather_infos, g_object_unref); - if (self->network_changed_sid > 0) g_signal_handler_disconnect (g_network_monitor_get_default (), self->network_changed_sid); @@ -1294,7 +1288,7 @@ gcal_weather_service_get_check_interval_renew (GcalWeatherService *self) * * Returns: (transfer none): list of known weather reports. */ -GSList* +GPtrArray* gcal_weather_service_get_weather_infos (GcalWeatherService *self) { g_return_val_if_fail (GCAL_IS_WEATHER_SERVICE (self), NULL); diff --git a/src/gcal-weather-service.h b/src/gcal-weather-service.h index 52f78d40..cdcd4258 100644 --- a/src/gcal-weather-service.h +++ b/src/gcal-weather-service.h @@ -56,7 +56,7 @@ guint gcal_weather_service_get_check_interval_new (GcalWeatherSer guint gcal_weather_service_get_check_interval_renew (GcalWeatherService *self); -GSList* gcal_weather_service_get_weather_infos (GcalWeatherService *self); +GPtrArray* gcal_weather_service_get_weather_infos (GcalWeatherService *self); const gchar* gcal_weather_service_get_attribution (GcalWeatherService *self); diff --git a/src/views/gcal-month-view.c b/src/views/gcal-month-view.c index ee3b0610..5dc110a7 100644 --- a/src/views/gcal-month-view.c +++ b/src/views/gcal-month-view.c @@ -901,40 +901,20 @@ setup_month_grid (GcalMonthView *self, } } -static void -update_weather (GcalMonthView *self, - gboolean clear_old) +static GcalWeatherInfo* +get_weather_info_for_cell (GcalMonthView *self, + guint cell) { GcalMonthCell *first_cell; + GPtrArray *weather_infos; GDateTime *first_dt; - GSList *weather_infos; - GSList *l; GDate first; + guint i; - g_return_if_fail (GCAL_IS_MONTH_VIEW (self)); - - /* Drop old weather information */ - if (clear_old) - { - guint row; - guint col; - - for (row = 0; row < 6; row++) - { - for (col = 0; col < 7; col++) - { - GcalMonthCell *cell; - - cell = GCAL_MONTH_CELL (self->month_cell[row][col]); - gcal_month_cell_set_weather (cell, NULL); - } - } - } - - - /* Set new one */ if (!self->weather_service) - return; + return NULL; + + weather_infos = gcal_weather_service_get_weather_infos (self->weather_service); first_cell = GCAL_MONTH_CELL (self->month_cell[0][0]); first_dt = gcal_month_cell_get_date (first_cell); @@ -944,30 +924,40 @@ update_weather (GcalMonthView *self, g_date_time_get_month (first_dt), g_date_time_get_year (first_dt)); - weather_infos = gcal_weather_service_get_weather_infos (self->weather_service); - for (l = weather_infos; l; l = l->next) + for (i = 0; weather_infos && i < weather_infos->len; i++) { GcalWeatherInfo *info; GDate weather_date; gint day_difference; - info = GCAL_WEATHER_INFO (l->data); + info = g_ptr_array_index (weather_infos, i); gcal_weather_info_get_date (info, &weather_date); day_difference = g_date_days_between (&first, &weather_date); - if (day_difference >= 0 && day_difference < 6 * 7) + if (day_difference == cell) + return info; + } + + return NULL; +} + +static void +update_weather (GcalMonthView *self, + gboolean clear_old) +{ + guint row; + guint col; + + g_return_if_fail (GCAL_IS_MONTH_VIEW (self)); + + for (row = 0; row < 6; row++) + { + for (col = 0; col < 7; col++) { - GcalMonthCell *wcell; - guint row; - guint column; - - row = day_difference / 7; - column = day_difference % 7; - wcell = GCAL_MONTH_CELL (self->month_cell[row][column]); - - gcal_month_cell_set_weather (wcell, info); + GcalMonthCell *cell = GCAL_MONTH_CELL (self->month_cell[row][col]); + gcal_month_cell_set_weather (cell, get_weather_info_for_cell (self, row * 7 + col)); } } } @@ -1052,7 +1042,7 @@ update_month_cells (GcalMonthView *self) } } - update_weather (self, TRUE); + update_weather (self, FALSE); self->update_grid_id = 0; diff --git a/src/views/gcal-week-header.c b/src/views/gcal-week-header.c index 8e9fc600..a52ac51d 100644 --- a/src/views/gcal-week-header.c +++ b/src/views/gcal-week-header.c @@ -1705,28 +1705,29 @@ G_GNUC_END_IGNORE_DEPRECATIONS */ static gint gcal_week_header_add_weather_infos (GcalWeekHeader *self, - GSList *winfos) + GPtrArray *weather_infos) { - g_autoptr (GDateTime) _week_start = NULL; - GSList *iter; /* unowned */ + g_autoptr (GDateTime) week_start_dt = NULL; GDate week_start; - int consumed = 0; + gint consumed = 0; + guint i; g_return_val_if_fail (self != NULL, 0); - _week_start = get_start_of_week (self->active_date); + week_start_dt = get_start_of_week (self->active_date); g_date_set_dmy (&week_start, - g_date_time_get_day_of_month (_week_start), - g_date_time_get_month (_week_start), - g_date_time_get_year (_week_start)); + g_date_time_get_day_of_month (week_start_dt), + g_date_time_get_month (week_start_dt), + g_date_time_get_year (week_start_dt)); - for (iter = winfos; iter != NULL; iter = iter->next) + for (i = 0; weather_infos && i < weather_infos->len; i++) { GcalWeatherInfo *gwi; /* unowned */ GDate gwi_date; gint day_diff; - gwi = GCAL_WEATHER_INFO (iter->data); + gwi = g_ptr_array_index (weather_infos, i); + gcal_weather_info_get_date (gwi, &gwi_date); day_diff = g_date_days_between (&week_start, &gwi_date); @@ -1796,18 +1797,17 @@ gcal_week_header_set_weather_service (GcalWeekHeader *self, void gcal_week_header_update_weather_infos (GcalWeekHeader *self) { + GPtrArray* weather_infos; g_return_if_fail (GCAL_IS_WEEK_HEADER (self)); gcal_week_header_clear_weather_infos (self); - if (self->weather_service != NULL) - { - GSList* weather_infos = NULL; /* unowned */ + if (!self->weather_service) + return; - weather_infos = gcal_weather_service_get_weather_infos (self->weather_service); - gcal_week_header_add_weather_infos (self, weather_infos); - } + weather_infos = gcal_weather_service_get_weather_infos (self->weather_service); + gcal_week_header_add_weather_infos (self, weather_infos); } void diff --git a/src/views/gcal-week-view.c b/src/views/gcal-week-view.c index 1c7c41a5..dd02f35b 100644 --- a/src/views/gcal-week-view.c +++ b/src/views/gcal-week-view.c @@ -517,9 +517,7 @@ gcal_week_view_finalize (GObject *object) g_clear_pointer (&self->date, g_free); g_clear_object (&self->manager); - - if (self->weather_service != NULL) - g_clear_object (&self->weather_service); + g_clear_object (&self->weather_service); /* Chain up to parent's finalize() method. */ G_OBJECT_CLASS (gcal_week_view_parent_class)->finalize (object); diff --git a/src/views/gcal-year-view.c b/src/views/gcal-year-view.c index 3d2fe2d6..d0bcae16 100644 --- a/src/views/gcal-year-view.c +++ b/src/views/gcal-year-view.c @@ -2060,22 +2060,25 @@ update_weather (GcalYearView *self) g_return_if_fail (GCAL_IS_YEAR_VIEW (self)); - - if (self->weather_service != NULL && self->date != NULL) + if (self->weather_service && self->date) { - GSList *witer; /* unowned */ - GDate date; + GPtrArray *weather_infos; + GDate date; + guint i; g_date_set_dmy (&date, self->date->day, self->date->month, self->date->year); - witer = gcal_weather_service_get_weather_infos (self->weather_service); - for (; witer != NULL; witer = witer->next) + weather_infos = gcal_weather_service_get_weather_infos (self->weather_service); + + for (i = 0; weather_infos && i < weather_infos->len; i++) { - GcalWeatherInfo *info; /* unowned */ + GcalWeatherInfo *info; GDate wdate; - info = GCAL_WEATHER_INFO (witer->data); + info = g_ptr_array_index (weather_infos, i); + gcal_weather_info_get_date (info, &wdate); + if (g_date_compare (&date, &wdate) == 0) { const gchar *temp_str; /* unowned */