From 8a0daab6beb652b5538953fc967db75b5f8f9fae 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 | 59 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 33 insertions(+), 26 deletions(-) diff --git a/src/gclue-locator.c b/src/gclue-locator.c index 4a05682..e9f6362 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,36 +160,41 @@ 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, 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; + gboolean notify_location = TRUE; + + if (priv->last_notified_location != NULL) { + gdouble distance; + gdouble threshold_km; + + 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_unref (priv->location); -update: - g_debug ("Updating location"); - priv->location = g_object_ref (location); - g_object_notify (G_OBJECT (locator), "location"); + 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