[gnome-calendar] weather-service: use GPtrArray for public API



commit 9f1885d8078754c8dee2f7543679fbed745e1fe7
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Sat Dec 16 23:10:45 2017 -0200

    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  | 72 +++++++++++++++++++-------------------------
 src/views/gcal-week-header.c | 32 ++++++++++----------
 src/views/gcal-week-view.c   |  4 +--
 src/views/gcal-year-view.c   | 19 +++++++-----
 6 files changed, 70 insertions(+), 85 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)
-        {
-          GcalMonthCell *wcell;
-          guint row;
-          guint column;
+      if (day_difference == cell)
+        return info;
+    }
 
-          row = day_difference / 7;
-          column = day_difference % 7;
-          wcell = GCAL_MONTH_CELL (self->month_cell[row][column]);
+  return NULL;
+}
 
-          gcal_month_cell_set_weather (wcell, info);
+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 *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 */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]