]> git.0d.be Git - empathy.git/commitdiff
Add weak object, destroy notify and error reporting to empathy_contact_call_when_ready
authorSjoerd Simons <sjoerd.simons@collabora.co.uk>
Fri, 9 Jan 2009 16:15:34 +0000 (16:15 +0000)
committerXavier Claessens <xclaesse@src.gnome.org>
Fri, 9 Jan 2009 16:15:34 +0000 (16:15 +0000)
Signed-off-by: Sjoerd Simons <sjoerd.simons@collabora.co.uk>
svn path=/trunk/; revision=2190

libempathy/empathy-contact.c
libempathy/empathy-contact.h

index a8a617c29f05ada104ed2ebd42b69a7b2b91cd00..a48d69900548ee1eb5731e195ec34e6dfd79fbe1 100644 (file)
@@ -21,6 +21,7 @@
  * Authors: Mikael Hallendal <micke@imendio.com>
  *          Martyn Russell <martyn@imendio.com>
  *          Xavier Claessens <xclaesse@gmail.com>
+ *          Sjoerd Simons <sjoerd.simons@collabora.co.uk>
  */
 
 #include "config.h"
@@ -60,6 +61,8 @@ typedef struct {
     EmpathyContactReady ready;
     EmpathyContactReadyCb *callback;
     gpointer user_data;
+    GDestroyNotify destroy;
+    GObject *weak_object;
 } ReadyCbData;
 
 static void contact_finalize (GObject *object);
@@ -351,6 +354,43 @@ contact_is_ready (EmpathyContact *contact, EmpathyContactReady ready)
   return (priv->ready & ready) == ready;
 }
 
+static void
+contact_weak_object_notify (gpointer data, GObject *old_object)
+{
+  EmpathyContact *contact = EMPATHY_CONTACT (data);
+  EmpathyContactPriv *priv = GET_PRIV (contact);
+
+  GList *l, *ln;
+
+  for (l = priv->ready_callbacks ; l != NULL ; l = ln )
+    {
+      ReadyCbData *d = (ReadyCbData *)l->data;
+      ln = g_list_next (l);
+
+      if (d->weak_object == old_object)
+        {
+          if (d->destroy != NULL)
+            d->destroy (d->user_data);
+
+           priv->ready_callbacks = g_list_delete_link (priv->ready_callbacks,
+            l);
+        }
+    }
+}
+
+static void
+contact_call_ready_callback (EmpathyContact *contact, GError *error,
+  ReadyCbData *data)
+{
+  data->callback (contact, error, data->user_data, data->weak_object);
+  if (data->destroy != NULL)
+    data->destroy (data->user_data);
+
+  if (data->weak_object)
+    g_object_weak_unref (data->weak_object,
+      contact_weak_object_notify, contact);
+}
+
 
 static void
 contact_set_ready_flag (EmpathyContact *contact,
@@ -372,8 +412,7 @@ contact_set_ready_flag (EmpathyContact *contact,
 
           if (contact_is_ready (contact, d->ready))
             {
-              d->callback (contact, d->user_data);
-
+              contact_call_ready_callback (contact, NULL, d);
               priv->ready_callbacks = g_list_delete_link
                 (priv->ready_callbacks, l);
             }
@@ -807,8 +846,8 @@ empathy_contact_hash (gconstpointer key)
 }
 
 void empathy_contact_call_when_ready (EmpathyContact *contact,
-  EmpathyContactReady ready, EmpathyContactReadyCb *callback, gpointer
-  user_data)
+  EmpathyContactReady ready, EmpathyContactReadyCb *callback,
+  gpointer user_data, GDestroyNotify destroy, GObject *weak_object)
 {
   EmpathyContactPriv *priv = GET_PRIV (contact);
 
@@ -817,7 +856,9 @@ void empathy_contact_call_when_ready (EmpathyContact *contact,
 
   if (contact_is_ready (contact, ready))
     {
-      callback (contact, user_data);
+      callback (contact, NULL, user_data, weak_object);
+      if (destroy != NULL)
+        destroy (user_data);
     }
   else
     {
@@ -825,8 +866,13 @@ void empathy_contact_call_when_ready (EmpathyContact *contact,
       d->ready = ready;
       d->callback = callback;
       d->user_data = user_data;
-      priv->ready_callbacks = g_list_prepend (priv->ready_callbacks,
-        d);
+      d->destroy = destroy;
+      d->weak_object = weak_object;
+
+      if (weak_object != NULL)
+        g_object_weak_ref (weak_object, contact_weak_object_notify, contact);
+
+      priv->ready_callbacks = g_list_prepend (priv->ready_callbacks, d);
     }
 }
 
index 19f15c3c5d5c009edd0eb7387c4d6364544668c6..b8d970d97684d1e8053320406595d336f1e2d15b 100644 (file)
@@ -114,10 +114,11 @@ gboolean empathy_contact_equal (gconstpointer v1, gconstpointer v2);
 guint empathy_contact_hash (gconstpointer key);
 
 typedef void (EmpathyContactReadyCb)
-  (EmpathyContact *contact, gpointer user_data);
+  (EmpathyContact *contact, GError *error, gpointer user_data,
+   GObject *weak_object);
 void empathy_contact_call_when_ready (EmpathyContact *contact,
   EmpathyContactReady ready, EmpathyContactReadyCb *callback, gpointer
-  user_data);
+  user_data, GDestroyNotify destroy, GObject *weak_object);
 
 void empathy_contact_run_until_ready (EmpathyContact *contact,
     EmpathyContactReady ready, GMainLoop **loop);