[Telepathy-commits] [telepathy-gabble/master] remove buddies from view when they left all their activities

Guillaume Desmottes guillaume.desmottes at collabora.co.uk
Fri Sep 26 10:02:21 PDT 2008


20080612132854-7fe3f-5bb85d1be15bc5214785a00c11a9d9f40ae0c59f.gz
---
 src/conn-olpc.c                            |    5 +-
 src/olpc-view.c                            |  105 ++++++++++++++++++++++++----
 src/olpc-view.h                            |    2 +-
 tests/twisted/olpc/olpc-activity-search.py |    7 +-
 4 files changed, 98 insertions(+), 21 deletions(-)

diff --git a/src/conn-olpc.c b/src/conn-olpc.c
index ea491f7..85b8096 100644
--- a/src/conn-olpc.c
+++ b/src/conn-olpc.c
@@ -3079,13 +3079,12 @@ add_activities_to_view_from_node (GabbleConnection *conn,
           continue;
         }
 
-      gabble_olpc_view_add_buddies (view, buddies, buddies_properties);
+      gabble_olpc_view_add_buddies (view, buddies, buddies_properties, handle);
 
       g_array_free (buddies, TRUE);
       g_ptr_array_free (buddies_properties, TRUE);
     }
 
-  /* TODO: remove activities when needed */
   gabble_olpc_view_add_activities (view, activities);
 
   g_hash_table_destroy (activities);
@@ -3138,7 +3137,7 @@ add_buddies_to_view_from_node (GabbleConnection *conn,
     }
 
   /* FIXME: we should update properties when needed */
-  gabble_olpc_view_add_buddies (view, buddies, buddies_properties);
+  gabble_olpc_view_add_buddies (view, buddies, buddies_properties, 0);
 
   for (i = 0; i < buddies->len; i++)
     {
diff --git a/src/olpc-view.c b/src/olpc-view.c
index db37da6..fbce366 100644
--- a/src/olpc-view.c
+++ b/src/olpc-view.c
@@ -71,6 +71,8 @@ struct _GabbleOlpcViewPrivate
 
   /* TpHandle (owned in priv->buddies) => GHashTable * */
   GHashTable *buddy_properties;
+  /* TpHandle (owned in priv->buddies) => TpHandleSet of activity rooms */
+  GHashTable *buddy_rooms;
 
   gboolean dispose_has_run;
 };
@@ -96,6 +98,8 @@ gabble_olpc_view_init (GabbleOlpcView *self)
 
   priv->buddy_properties = g_hash_table_new_full (g_direct_hash, g_direct_equal,
       NULL, (GDestroyNotify) g_hash_table_unref);
+  priv->buddy_rooms = g_hash_table_new_full (g_direct_hash, g_direct_equal,
+      NULL, (GDestroyNotify) tp_handle_set_destroy);
 
   priv->dispose_has_run = FALSE;
 }
@@ -127,6 +131,12 @@ gabble_olpc_view_dispose (GObject *object)
       priv->buddy_properties = NULL;
     }
 
+  if (priv->buddy_rooms != NULL)
+    {
+      g_hash_table_destroy (priv->buddy_rooms);
+      priv->buddy_rooms = NULL;
+    }
+
   priv->dispose_has_run = TRUE;
 
   if (G_OBJECT_CLASS (gabble_olpc_view_parent_class)->dispose)
@@ -208,7 +218,7 @@ gabble_olpc_view_constructor (GType type,
   GabbleOlpcViewPrivate *priv;
   DBusGConnection *bus;
   TpBaseConnection *conn;
-  TpHandleRepoIface *contact_handles, *room_handles;
+  TpHandleRepoIface *contact_handles;
 
   obj = G_OBJECT_CLASS (gabble_olpc_view_parent_class)->
            constructor (type, n_props, props);
@@ -223,8 +233,6 @@ gabble_olpc_view_constructor (GType type,
 
   contact_handles = tp_base_connection_get_handles (conn,
       TP_HANDLE_TYPE_CONTACT);
-  room_handles = tp_base_connection_get_handles (conn,
-      TP_HANDLE_TYPE_ROOM);
 
   priv->buddies = tp_handle_set_new (contact_handles);
   priv->activities = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL,
@@ -433,14 +441,22 @@ olpc_view_close (GabbleSvcOLPCView *iface,
   g_signal_emit (G_OBJECT (self), signals[CLOSED], 0);
 }
 
+/* If room is not zero, these buddies are associated with the activity
+ * of this room. They'll leave the view if the activity is removed.
+ */
 void
 gabble_olpc_view_add_buddies (GabbleOlpcView *self,
                               GArray *buddies,
-                              GPtrArray *buddies_properties)
+                              GPtrArray *buddies_properties,
+                              TpHandle room)
 {
   GabbleOlpcViewPrivate *priv = GABBLE_OLPC_VIEW_GET_PRIVATE (self);
   guint i;
   GArray *empty;
+  TpHandleRepoIface *room_repo;
+
+  room_repo = tp_base_connection_get_handles ((TpBaseConnection *) priv->conn,
+      TP_HANDLE_TYPE_ROOM);
 
   g_assert (buddies->len == buddies_properties->len);
 
@@ -459,6 +475,25 @@ gabble_olpc_view_add_buddies (GabbleOlpcView *self,
       g_hash_table_insert (priv->buddy_properties, GUINT_TO_POINTER (handle),
           properties);
       g_hash_table_ref (properties);
+
+      if (room != 0)
+        {
+          /* buddies are in an activity */
+          TpHandleSet *set;
+
+          set = g_hash_table_lookup (priv->buddy_rooms, GUINT_TO_POINTER (
+                handle));
+
+          if (set == NULL)
+            {
+              set = tp_handle_set_new (room_repo);
+
+              g_hash_table_insert (priv->buddy_rooms, GUINT_TO_POINTER (
+                    handle), set);
+            }
+
+          tp_handle_set_add (set, room);
+        }
     }
 
   gabble_svc_olpc_view_emit_buddies_changed (self, buddies, empty);
@@ -467,14 +502,15 @@ gabble_olpc_view_add_buddies (GabbleOlpcView *self,
 }
 
 static void
-remove_properties_foreach (TpHandleSet *buddies,
-                           TpHandle handle,
-                           GabbleOlpcView *self)
+remove_buddy_foreach (TpHandleSet *buddies,
+                      TpHandle handle,
+                      GabbleOlpcView *self)
 {
   GabbleOlpcViewPrivate *priv = GABBLE_OLPC_VIEW_GET_PRIVATE (self);
 
   tp_handle_set_remove (priv->buddies, handle);
   g_hash_table_remove (priv->buddy_properties, GUINT_TO_POINTER (handle));
+  g_hash_table_remove (priv->buddy_rooms, GUINT_TO_POINTER (handle));
 }
 
 void
@@ -484,7 +520,7 @@ gabble_olpc_view_remove_buddies (GabbleOlpcView *self,
   GArray *removed, *empty;
 
   tp_handle_set_foreach (buddies,
-      (TpHandleSetMemberFunc) remove_properties_foreach, self);
+      (TpHandleSetMemberFunc) remove_buddy_foreach, self);
 
   empty = g_array_new (FALSE, FALSE, sizeof (TpHandle));
   removed = tp_handle_set_to_array (buddies);
@@ -545,6 +581,32 @@ gabble_olpc_view_add_activities (GabbleOlpcView *self,
   g_ptr_array_free (empty, TRUE);
 }
 
+struct remove_activity_foreach_buddy_ctx
+{
+  GabbleOlpcView *view;
+  TpHandle room;
+  /* buddies who have to be removed */
+  TpHandleSet *removed;
+};
+
+static void
+remove_activity_foreach_buddy (TpHandle buddy,
+                               TpHandleSet *set,
+                               struct remove_activity_foreach_buddy_ctx *ctx)
+{
+  if (set == NULL)
+    return;
+
+  if (tp_handle_set_remove (set, ctx->room))
+    {
+      if (tp_handle_set_size (set) == 0)
+        {
+          /* No more activity for this buddy. Remove it */
+          tp_handle_set_add (ctx->removed, buddy);
+        }
+    }
+}
+
 void
 gabble_olpc_view_remove_activities (GabbleOlpcView *self,
                                     TpHandleSet *rooms)
@@ -553,6 +615,10 @@ gabble_olpc_view_remove_activities (GabbleOlpcView *self,
   GPtrArray *removed, *empty;
   GArray *array;
   guint i;
+  TpHandleRepoIface *contact_repo;
+
+  contact_repo = tp_base_connection_get_handles (
+      (TpBaseConnection *) priv->conn, TP_HANDLE_TYPE_CONTACT);
 
   /* for easier iteration */
   array = tp_handle_set_to_array (rooms);
@@ -562,18 +628,31 @@ gabble_olpc_view_remove_activities (GabbleOlpcView *self,
 
   for (i = 0; i < array->len; i++)
     {
-      TpHandle handle;
+      TpHandle room;
       GabbleOlpcActivity *activity;
+      struct remove_activity_foreach_buddy_ctx ctx;
 
-      handle = g_array_index (array, TpHandle, i);
+      room = g_array_index (array, TpHandle, i);
 
       activity = g_hash_table_lookup (priv->activities,
-          GUINT_TO_POINTER (handle));
+          GUINT_TO_POINTER (room));
       if (activity == NULL)
         continue;
 
-      add_activity_to_array (handle, activity, removed);
-      g_hash_table_remove (priv->activities, GUINT_TO_POINTER (handle));
+      add_activity_to_array (room, activity, removed);
+      g_hash_table_remove (priv->activities, GUINT_TO_POINTER (room));
+
+      /* remove the activity from all rooms set */
+      ctx.view = self;
+      ctx.room = room;
+      ctx.removed = tp_handle_set_new (contact_repo);
+
+      g_hash_table_foreach (priv->buddy_rooms,
+          (GHFunc) remove_activity_foreach_buddy, &ctx);
+
+      gabble_olpc_view_remove_buddies (self, ctx.removed);
+
+      tp_handle_set_destroy (ctx.removed);
     }
 
   gabble_svc_olpc_view_emit_activities_changed (self, empty, removed);
diff --git a/src/olpc-view.h b/src/olpc-view.h
index 6a218e2..fcda7fd 100644
--- a/src/olpc-view.h
+++ b/src/olpc-view.h
@@ -71,7 +71,7 @@ GabbleOlpcView * gabble_olpc_view_new (GabbleConnection *conn,
     GabbleOlpcViewType type, guint id);
 
 void gabble_olpc_view_add_buddies (GabbleOlpcView *self,
-    GArray *handles, GPtrArray *buddies_properties);
+    GArray *handles, GPtrArray *buddies_properties, TpHandle room);
 
 void gabble_olpc_view_remove_buddies (GabbleOlpcView *self,
     TpHandleSet *handles);
diff --git a/tests/twisted/olpc/olpc-activity-search.py b/tests/twisted/olpc/olpc-activity-search.py
index 3829a28..ddc37c3 100644
--- a/tests/twisted/olpc/olpc-activity-search.py
+++ b/tests/twisted/olpc/olpc-activity-search.py
@@ -303,10 +303,9 @@ def test(q, bus, conn, stream):
     stream.send(message)
 
     # participants are removed from the view
-    # FIXME
-    #event = q.expect('dbus-signal', signal='BuddiesChanged')
-    #members_handles, removed = event.args
-    #assert conn.InspectHandles(1, members_handles) == ['fernand at localhost']
+    event = q.expect('dbus-signal', signal='BuddiesChanged')
+    added, removed = event.args
+    assert conn.InspectHandles(1, removed) == ['lucien at localhost']
 
     # activity is removed
     event = q.expect('dbus-signal', signal='ActivitiesChanged')
-- 
1.5.6.5




More information about the Telepathy-commits mailing list