From 37146ffe648cfce22a1fb0e6047b09a53a9264ba Mon Sep 17 00:00:00 2001 From: Kalev Lember Date: Thu, 12 Sep 2013 01:09:33 +0200 Subject: [PATCH 6/7] locator: Rework the location updating logic Previously, we would emit the LocationUpdated signal for any location property change, disregarding the DistanceThreshold value. A change in the "description" property would trigger the LocationUpdated signal, even though we were well below the threshold. This commit changes it to emit LocationUpdated only when we cross the threshold. We keep track of the previous location where LocationUpdated was last emitted. While below the threshold, we update the location properties, but don't notify the clients; the clients only get notified once the threshold is crossed. https://bugs.freedesktop.org/show_bug.cgi?id=69105 --- src/gclue-locator.c | 57 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 32 insertions(+), 25 deletions(-) diff --git a/src/gclue-locator.c b/src/gclue-locator.c index 8e3fb80..84a9ce9 100644 --- a/src/gclue-locator.c +++ b/src/gclue-locator.c @@ -34,6 +34,7 @@ struct _GClueLocatorPrivate GClueIpclient *ipclient; GClueLocationInfo *location; + GClueLocationInfo *last_notified_location; guint threshold; GCancellable *cancellable; @@ -64,6 +65,7 @@ gclue_locator_finalize (GObject *object) gclue_locator_stop_sync (GCLUE_LOCATOR (object)); g_clear_object (&priv->ipclient); g_clear_object (&priv->location); + g_clear_object (&priv->last_notified_location); G_OBJECT_CLASS (gclue_locator_parent_class)->finalize (object); } @@ -158,37 +160,42 @@ gclue_locator_new (void) static void gclue_locator_update_location (GClueLocator *locator, - GClueLocationInfo *location) + GClueLocationInfo *new_location) { GClueLocatorPrivate *priv = locator->priv; - gdouble accuracy, new_accuracy; + gboolean notify_location = TRUE; gdouble distance; gdouble threshold_km; - const char *desc, *new_desc; - - if (priv->location == NULL) - goto update; - - accuracy = gclue_location_info_get_accuracy (priv->location); - new_accuracy = gclue_location_info_get_accuracy (location); - desc = gclue_location_info_get_description (priv->location); - new_desc = gclue_location_info_get_description (location); - - threshold_km = priv->threshold / 1000.0; - distance = gclue_location_info_get_distance_from (priv->location, - location); - if (accuracy == new_accuracy && - g_strcmp0 (desc, new_desc) == 0 && - distance < threshold_km) { - g_debug ("Location remain unchanged"); - return; - } - g_object_unref (priv->location); -update: g_debug ("Updating location"); - priv->location = g_object_ref (location); - g_object_notify (G_OBJECT (locator), "location"); + + if (priv->last_notified_location != NULL) { + threshold_km = priv->threshold / 1000.0; + distance = gclue_location_info_get_distance_from (priv->last_notified_location, + new_location); + if (distance < threshold_km) + notify_location = FALSE; + } + + if (notify_location || priv->location == NULL) { + g_clear_object (&priv->location); + priv->location = g_object_new (GCLUE_TYPE_LOCATION_INFO, NULL); + } + + g_object_set (priv->location, + "latitude", gclue_location_info_get_latitude (new_location), + "longitude", gclue_location_info_get_longitude (new_location), + "accuracy", gclue_location_info_get_accuracy (new_location), + "description", gclue_location_info_get_description (new_location), + NULL); + + if (notify_location) { + g_clear_object (&priv->last_notified_location); + priv->last_notified_location = g_object_ref (new_location); + + g_debug ("Notifying location update"); + g_object_notify (G_OBJECT (locator), "location"); + } } static void -- 1.8.3.1