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.
This commit is contained in:
+10
-16
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
+32
-42
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user