[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