add a throttle when publishing
authorGuillaume Desmottes <guillaume.desmottes@collabora.co.uk>
Tue, 30 Mar 2010 15:28:13 +0000 (17:28 +0200)
committerGuillaume Desmottes <guillaume.desmottes@collabora.co.uk>
Tue, 30 Mar 2010 15:28:13 +0000 (17:28 +0200)
src/position-publisher.c

index f986dcf..0029c04 100644 (file)
@@ -32,6 +32,9 @@
 
 G_DEFINE_TYPE(PositionPublisher, position_publisher, G_TYPE_OBJECT)
 
+/* Minimum time before 2 publishing (in seconds) */
+#define PUBLISH_THROTTLE 10
+
 /* private structure */
 typedef struct _PositionPublisherPrivate PositionPublisherPrivate;
 
@@ -41,6 +44,10 @@ struct _PositionPublisherPrivate
   LocationGPSDevice *gps_device;
   GSList *connections;
   GHashTable *location;
+  /* If not 0, we are waiting before publishing again */
+  guint throttle_timeout;
+  /* TRUE if location has been modified while we were waiting */
+  gboolean modified;
 
   gboolean dispose_has_run;
 };
@@ -53,6 +60,8 @@ static void conn_invalidated_cb (TpProxy *conn,
     gchar *message,
     PositionPublisher *self);
 
+static void publish_to_all (PositionPublisher *self);
+
 static void
 remove_connection (PositionPublisher *self,
     TpConnection *conn)
@@ -89,6 +98,23 @@ set_location_cb (TpConnection *conn,
   g_print ("SetLocation succeed\n");
 }
 
+static gboolean
+publish_throttle_timeout_cb (gpointer data)
+{
+  PositionPublisher *self = data;
+  PositionPublisherPrivate *priv = POSITION_PUBLISHER_GET_PRIVATE (self);
+
+  priv->throttle_timeout = 0;
+
+  if (priv->modified)
+    {
+      publish_to_all (self);
+      priv->modified = FALSE;
+    }
+
+  return FALSE;
+}
+
 static void
 publish_to_conn (PositionPublisher *self,
     TpConnection *conn)
@@ -98,8 +124,16 @@ publish_to_conn (PositionPublisher *self,
   if (priv->location == NULL)
     return;
 
+  if (priv->throttle_timeout != 0)
+    /* We are waiting */
+    return;
+
   tp_cli_connection_interface_location_call_set_location (conn, -1,
       priv->location, set_location_cb, NULL, NULL, G_OBJECT (self));
+
+  /* We won't publish during the next PUBLISH_THROTTLE seconds */
+  priv->throttle_timeout = g_timeout_add_seconds (PUBLISH_THROTTLE,
+      publish_throttle_timeout_cb, self);
 }
 
 static void
@@ -139,6 +173,8 @@ update_position (PositionPublisher *self,
       "accuracy", G_TYPE_DOUBLE, accuracy,
       NULL);
 
+  priv->modified = TRUE;
+
   publish_to_all (self);
 }
 
@@ -262,6 +298,9 @@ position_publisher_dispose (GObject *object)
 
   g_hash_table_unref (priv->location);
 
+  if (priv->throttle_timeout != 0)
+    g_source_remove (priv->throttle_timeout);
+
   if (G_OBJECT_CLASS (position_publisher_parent_class)->dispose)
     G_OBJECT_CLASS (position_publisher_parent_class)->dispose (object);
 }