[Telepathy-commits] [telepathy-gabble/master] GabbleChannelManager: rethink signal API, add signal emission helpers, add virtual method foreach_channel

Simon McVittie simon.mcvittie at collabora.co.uk
Mon Nov 3 11:20:34 PST 2008


20080728151548-53eee-0bd5d0b60ab70534ac34164d693a779d570ddf7a.gz
---
 src/channel-manager.c    |  275 ++++++++++++++++++++++++++++++++++++++++++++--
 src/channel-manager.h    |   45 +++++++-
 src/exportable-channel.h |    3 +
 3 files changed, 308 insertions(+), 15 deletions(-)

diff --git a/src/channel-manager.c b/src/channel-manager.c
index 0dddd98..c2e9007 100644
--- a/src/channel-manager.c
+++ b/src/channel-manager.c
@@ -23,13 +23,16 @@
 #include "config.h"
 #include "channel-manager.h"
 
+#include <telepathy-glib/dbus.h>
+
 #include "exportable-channel.h"
 #include "gabble-signals-marshal.h"
 
 enum {
-    NEW_CHANNELS,
-    CHANNEL_CLOSED,
-    REQUEST_SATISFIED,
+    S_NEW_CHANNELS,
+    S_REQUEST_SUCCEEDED,
+    S_REQUEST_FAILED,
+    S_CHANNEL_CLOSED,
     N_SIGNALS
 };
 
@@ -47,8 +50,16 @@ channel_manager_base_init (gpointer klass)
 
       /* FIXME: should probably have a better GType for a GPtrArray of
        * ExportableChannel */
-      /* New channels have been created */
-      signals[NEW_CHANNELS] = g_signal_new ("new-channels",
+      /**
+       * GabbleChannelManager::new-channels:
+       * @self: the channel manager
+       * @channels: a #GPtrArray of #GabbleExportableChannel
+       *
+       * Emitted when new channels have been created. The Connection should
+       * generally emit NewChannels (and NewChannel) in response to this
+       * signal.
+       */
+      signals[S_NEW_CHANNELS] = g_signal_new ("new-channels",
           G_OBJECT_CLASS_TYPE (klass),
           G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
           0,
@@ -56,17 +67,59 @@ channel_manager_base_init (gpointer klass)
           g_cclosure_marshal_VOID__POINTER,
           G_TYPE_NONE, 1, G_TYPE_POINTER);
 
-      /* A QUEUED request has been satisfied by a channel */
-      signals[REQUEST_SATISFIED] = g_signal_new ("request-satisfied",
+      /**
+       * GabbleChannelManager::request-succeeded:
+       * @self: the channel manager
+       * @request_token: opaque pointer supplied by the requester,
+       *  representing a request
+       * @channel: the channel that satisfied the request
+       *
+       * Emitted when a channel request has been satisfied by a channel.
+       * The Connection should generally respond to this signal by returning
+       * success from CreateChannel or RequestChannel.
+       */
+      signals[S_REQUEST_SUCCEEDED] = g_signal_new ("request-succeeded",
           G_OBJECT_CLASS_TYPE (klass),
           G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
           0,
           NULL, NULL,
           gabble_marshal_VOID__POINTER_OBJECT,
-          G_TYPE_NONE, 1, G_TYPE_POINTER, GABBLE_TYPE_EXPORTABLE_CHANNEL);
+          G_TYPE_NONE, 2, G_TYPE_POINTER, GABBLE_TYPE_EXPORTABLE_CHANNEL);
 
-      /* A channel has been closed */
-      signals[CHANNEL_CLOSED] = g_signal_new ("channel-closed",
+      /**
+       * GabbleChannelManager::request-failed:
+       * @self: the channel manager
+       * @request_token: opaque pointer supplied by the requester,
+       *  representing a request
+       * @domain: the domain of a #GError indicating why the request
+       *  failed
+       * @code: the error code of a #GError indicating why the request
+       *  failed
+       * @message: the string part of a #GError indicating why the request
+       *  failed
+       *
+       * Emitted when a channel request has failed. The Connection should
+       * generally respond to this signal by returning failure from
+       * CreateChannel or RequestChannel.
+       */
+      signals[S_REQUEST_SUCCEEDED] = g_signal_new ("request-failed",
+          G_OBJECT_CLASS_TYPE (klass),
+          G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
+          0,
+          NULL, NULL,
+          gabble_marshal_VOID__POINTER_UINT_INT_STRING,
+          G_TYPE_NONE, 4, G_TYPE_POINTER, G_TYPE_UINT, G_TYPE_INT,
+          G_TYPE_STRING, GABBLE_TYPE_EXPORTABLE_CHANNEL);
+
+      /**
+       * GabbleChannelManager::channel-closed:
+       * @self: the channel manager
+       * @path: the channel's object-path
+       *
+       * Emitted when a channel has been closed. The Connection should
+       * generally respond to this signal by emitting ChannelClosed.
+       */
+      signals[S_CHANNEL_CLOSED] = g_signal_new ("channel-closed",
           G_OBJECT_CLASS_TYPE (klass),
           G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
           0,
@@ -102,3 +155,205 @@ gabble_channel_manager_get_type (void)
 
   return type;
 }
+
+
+/* Signal emission wrappers */
+
+
+/**
+ * gabble_channel_manager_emit_new_channels:
+ * @instance: An object implementing #GabbleChannelManager
+ * @channels: A #GPtrArray of #GabbleExportableChannel, which may be empty
+ *
+ * If @channels is non-empty, emit the #GabbleChannelManager::new-channels
+ * signal indicating that those channels have been created.
+ */
+void
+gabble_channel_manager_emit_new_channels (gpointer instance,
+                                          GPtrArray *channels)
+{
+  g_return_if_fail (GABBLE_IS_CHANNEL_MANAGER (instance));
+
+  if (channels->len == 0)
+    return;
+
+  /* just a quick sanity-check */
+  g_return_if_fail (GABBLE_IS_EXPORTABLE_CHANNEL (g_ptr_array_index (
+          channels, 0)));
+
+  g_signal_emit (instance, signals[S_NEW_CHANNELS], 0, channels);
+}
+
+
+/**
+ * gabble_channel_manager_emit_new_channel:
+ * @instance: An object implementing #GabbleChannelManager
+ * @channel: A #GabbleExportableChannel
+ *
+ * Emit the #GabbleChannelManager::new-channels signal indicating that the
+ * channel has been created. (This is a convenient shortcut for calling
+ * gabble_channel_manager_emit_new_channels() with an array of length 1.)
+ */
+void
+gabble_channel_manager_emit_new_channel (gpointer instance,
+                                         GabbleExportableChannel *channel)
+{
+  GPtrArray *array = g_ptr_array_sized_new (1);
+
+  g_return_if_fail (GABBLE_IS_CHANNEL_MANAGER (instance));
+  g_return_if_fail (GABBLE_IS_EXPORTABLE_CHANNEL (channel));
+
+  g_ptr_array_add (array, channel);
+  g_signal_emit (instance, signals[S_NEW_CHANNELS], 0, array);
+  g_ptr_array_free (array, TRUE);
+}
+
+
+/**
+ * gabble_channel_manager_emit_channel_closed:
+ * @instance: An object implementing #GabbleChannelManager
+ * @path: A channel's object-path
+ *
+ * Emit the #GabbleChannelManager::channel-closed signal indicating that
+ * the given channel has been closed. (This is a convenient shortcut for
+ * calling gabble_channel_manager_emit_channel_closed() with the
+ * #GabbleExportableChannel:object-path property of @channel.)
+ */
+void
+gabble_channel_manager_emit_channel_closed (gpointer instance,
+                                            const gchar *path)
+{
+  g_return_if_fail (GABBLE_IS_CHANNEL_MANAGER (instance));
+  g_return_if_fail (tp_dbus_check_valid_object_path (path, NULL));
+
+  g_signal_emit (instance, signals[S_CHANNEL_CLOSED], 0, path);
+}
+
+
+/**
+ * gabble_channel_manager_emit_channel_closed_for_object:
+ * @instance: An object implementing #GabbleChannelManager
+ * @channel: A #GabbleExportableChannel
+ *
+ * Emit the #GabbleChannelManager::channel-closed signal indicating that
+ * the given channel has been closed. (This is a convenient shortcut for
+ * calling gabble_channel_manager_emit_channel_closed() with the
+ * #GabbleExportableChannel:object-path property of @channel.)
+ */
+void
+gabble_channel_manager_emit_channel_closed_for_object (gpointer instance,
+    GabbleExportableChannel *channel)
+{
+  gchar *path;
+
+  g_return_if_fail (GABBLE_IS_EXPORTABLE_CHANNEL (channel));
+  g_object_get (channel,
+      "object-path", &path,
+      NULL);
+  gabble_channel_manager_emit_channel_closed (instance, path);
+  g_free (path);
+}
+
+
+/**
+ * gabble_channel_manager_emit_request_succeeded:
+ * @instance: An object implementing #GabbleChannelManager
+ * @request_token: An opaque pointer representing the request that
+ *  succeeded
+ * @channel: The channel that satisfies the request
+ *
+ * Emit the #GabbleChannelManager::request-succeeded signal indicating that
+ * @channel satisfies @request_token.
+ */
+void
+gabble_channel_manager_emit_request_succeeded (gpointer instance,
+    gpointer request_token,
+    GabbleExportableChannel *channel)
+{
+  g_return_if_fail (GABBLE_IS_EXPORTABLE_CHANNEL (channel));
+  g_return_if_fail (GABBLE_IS_CHANNEL_MANAGER (instance));
+
+  g_signal_emit (instance, signals[S_REQUEST_SUCCEEDED], 0, request_token,
+      channel);
+}
+
+
+/**
+ * gabble_channel_manager_emit_request_failed:
+ * @instance: An object implementing #GabbleChannelManager
+ * @request_token: An opaque pointer representing the request that
+ *  succeeded
+ * @domain: a #GError domain
+ * @code: a #GError code appropriate for @domain
+ * @message: the error message
+ *
+ * Emit the #GabbleChannelManager::request-failed signal indicating that
+ * the request @request_token failed for the given reason.
+ */
+void
+gabble_channel_manager_emit_request_failed (gpointer instance,
+                                            gpointer request_token,
+                                            GQuark domain,
+                                            gint code,
+                                            const gchar *message)
+{
+  g_return_if_fail (GABBLE_IS_CHANNEL_MANAGER (instance));
+
+  g_signal_emit (instance, signals[S_REQUEST_FAILED], 0, request_token,
+      domain, code, message);
+}
+
+
+/**
+ * gabble_channel_manager_emit_request_failed:
+ * @instance: An object implementing #GabbleChannelManager
+ * @request_token: An opaque pointer representing the request that
+ *  succeeded
+ * @domain: a #GError domain
+ * @code: a #GError code appropriate for @domain
+ * @format: a printf-style format string for the error message
+ * @...: arguments for the format string
+ *
+ * Emit the #GabbleChannelManager::request-failed signal indicating that
+ * the request @request_token failed for the given reason.
+ */
+void
+gabble_channel_manager_emit_request_failed_printf (gpointer instance,
+                                                   gpointer request_token,
+                                                   GQuark domain,
+                                                   gint code,
+                                                   const gchar *format,
+                                                   ...)
+{
+  va_list ap;
+  gchar *message;
+
+  va_start (ap, format);
+  message = g_strdup_vprintf (format, ap);
+  va_end (ap);
+
+  gabble_channel_manager_emit_request_failed (instance, request_token,
+      domain, code, message);
+
+  g_free (message);
+}
+
+
+/* Virtual-method wrappers */
+
+
+void
+gabble_channel_manager_foreach_channel (GabbleChannelManager *manager,
+                                        GabbleExportableChannelFunc func,
+                                        gpointer user_data)
+{
+  GabbleChannelManagerIface *iface = GABBLE_CHANNEL_MANAGER_GET_INTERFACE (
+      manager);
+  GabbleChannelManagerForeachChannelFunc method = iface->foreach_channel;
+
+  if (method != NULL)
+    {
+      method (manager, func, user_data);
+    }
+  /* ... else assume it has no channels, and do nothing */
+}
diff --git a/src/channel-manager.h b/src/channel-manager.h
index 1ac6dc9..6233eaa 100644
--- a/src/channel-manager.h
+++ b/src/channel-manager.h
@@ -26,6 +26,8 @@
 #include <glib-object.h>
 #include <telepathy-glib/channel-factory-iface.h>
 
+#include "exportable-channel.h"
+
 G_BEGIN_DECLS
 
 #define GABBLE_TYPE_CHANNEL_MANAGER (gabble_channel_manager_get_type ())
@@ -45,18 +47,51 @@ G_BEGIN_DECLS
 typedef struct _GabbleChannelManager GabbleChannelManager;
 typedef struct _GabbleChannelManagerIface GabbleChannelManagerIface;
 
+
+/* virtual methods */
+
+typedef void (*GabbleChannelManagerForeachChannelFunc) (
+    GabbleChannelManager *manager, GabbleExportableChannelFunc func,
+    gpointer user_data);
+
+void gabble_channel_manager_foreach_channel (GabbleChannelManager *manager,
+    GabbleExportableChannelFunc func, gpointer user_data);
+
+
 struct _GabbleChannelManagerIface {
     GTypeInterface parent;
+
+    GabbleChannelManagerForeachChannelFunc foreach_channel;
+
+    GCallback _future[8];
 };
 
+
 GType gabble_channel_manager_get_type (void);
 
-TpChannelFactoryRequestStatus gabble_channel_factory_create_channel (
-    GabbleChannelManager *manager, GHashTable *properties,
-    gpointer request_token, TpChannelIface **ret, GError **error);
 
-void gabble_channel_manager_foreach (GabbleChannelManager *manager,
-    TpChannelFunc func, gpointer user_data);
+/* signal emission */
+
+void gabble_channel_manager_emit_new_channel (gpointer instance,
+    GabbleExportableChannel *channel);
+void gabble_channel_manager_emit_new_channels (gpointer instance,
+    GPtrArray *channels);
+
+void gabble_channel_manager_emit_channel_closed (gpointer instance,
+    const gchar *path);
+void gabble_channel_manager_emit_channel_closed_for_object (gpointer instance,
+    GabbleExportableChannel *channel);
+
+void gabble_channel_manager_emit_request_succeeded (gpointer instance,
+    gpointer request_token, GabbleExportableChannel *channel);
+
+void gabble_channel_manager_emit_request_failed (gpointer instance,
+    gpointer request_token, GQuark domain, gint code, const gchar *message);
+void gabble_channel_manager_emit_request_failed_printf (gpointer instance,
+    gpointer request_token, GQuark domain, gint code, const gchar *format,
+    ...) G_GNUC_PRINTF (5, 6);
+
+
 
 G_END_DECLS
 
diff --git a/src/exportable-channel.h b/src/exportable-channel.h
index 8bdd94b..ed7e888 100644
--- a/src/exportable-channel.h
+++ b/src/exportable-channel.h
@@ -43,6 +43,9 @@ G_BEGIN_DECLS
 typedef struct _GabbleExportableChannel GabbleExportableChannel;
 typedef struct _GabbleExportableChannelIface GabbleExportableChannelIface;
 
+typedef void (*GabbleExportableChannelFunc) (GabbleExportableChannel *channel,
+    gpointer user_data);
+
 struct _GabbleExportableChannelIface {
     GTypeInterface parent;
 };
-- 
1.5.6.5




More information about the Telepathy-commits mailing list