diff options
author | Will Thompson <will.thompson@collabora.co.uk> | 2012-03-28 14:09:58 +0100 |
---|---|---|
committer | Will Thompson <will.thompson@collabora.co.uk> | 2012-03-28 14:09:58 +0100 |
commit | 2776c23c3095ca4aaa356c6d9f0ee0c02b4c7edc (patch) | |
tree | f939ea4f34b1de3a211943ae74d20e6deeba2d9f | |
parent | b5fe86f5fe8e2cfbc257fff29c1b087e3d2b4f74 (diff) | |
download | telepathy-glib-2776c23c3095ca4aaa356c6d9f0ee0c02b4c7edc.tar.gz |
AutomaticClientFactory: add a channel type lookup table
This is a bit longer but it makes me feel smart.
-rw-r--r-- | telepathy-glib/automatic-client-factory.c | 165 |
1 files changed, 111 insertions, 54 deletions
diff --git a/telepathy-glib/automatic-client-factory.c b/telepathy-glib/automatic-client-factory.c index ebab26529..0411ecaab 100644 --- a/telepathy-glib/automatic-client-factory.c +++ b/telepathy-glib/automatic-client-factory.c @@ -120,6 +120,93 @@ G_DEFINE_TYPE (TpAutomaticClientFactory, tp_automatic_client_factory, #define chainup ((TpSimpleClientFactoryClass *) \ tp_automatic_client_factory_parent_class) +typedef gboolean (*CheckPropertiesFunc) ( + const gchar *object_path, + const GHashTable *properties); + +typedef TpChannel *(*NewFunc) ( + TpSimpleClientFactory *client, + TpConnection *conn, + const gchar *object_path, + const GHashTable *properties, + GError **error); + +typedef struct { + const gchar *channel_type; + GType gtype; + CheckPropertiesFunc check_properties; + NewFunc new_func; + /* 0-terminated. All of a sudden, 3 is not such a scary number. */ + GQuark features[3]; +} ChannelTypeMapping; + +static ChannelTypeMapping *channel_type_mapping = NULL; + +static gboolean +check_for_messages ( + const gchar *object_path, + const GHashTable *properties) +{ + /* Create a TpTextChannel only if the channel supports Messages */ + const gchar * const * interfaces; + + interfaces = tp_asv_get_strv (properties, TP_PROP_CHANNEL_INTERFACES); + + if (!tp_strv_contains (interfaces, TP_IFACE_CHANNEL_INTERFACE_MESSAGES)) + { + DEBUG ("channel %s doesn't implement Messages so we can't create " + "a TpTextChannel", object_path); + return FALSE; + } + + return TRUE; +} +static void +build_channel_type_mapping (void) +{ + ChannelTypeMapping i_hate_c[] = { + { TP_IFACE_CHANNEL_TYPE_STREAM_TUBE, + TP_TYPE_STREAM_TUBE_CHANNEL, + NULL, + (NewFunc) _tp_stream_tube_channel_new_with_factory, + { 0 }, + }, + { TP_IFACE_CHANNEL_TYPE_DBUS_TUBE, + TP_TYPE_DBUS_TUBE_CHANNEL, + NULL, + (NewFunc) _tp_dbus_tube_channel_new_with_factory, + { 0 }, + }, + { TP_IFACE_CHANNEL_TYPE_TEXT, + TP_TYPE_TEXT_CHANNEL, + check_for_messages, + (NewFunc) _tp_text_channel_new_with_factory, + { TP_TEXT_CHANNEL_FEATURE_INCOMING_MESSAGES, + TP_TEXT_CHANNEL_FEATURE_SMS, + 0 }, + }, + { TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER, + TP_TYPE_FILE_TRANSFER_CHANNEL, + NULL, + (NewFunc) _tp_file_transfer_channel_new_with_factory, + { TP_FILE_TRANSFER_CHANNEL_FEATURE_CORE, + 0 }, + }, + { TP_IFACE_CHANNEL_TYPE_CALL, + TP_TYPE_CALL_CHANNEL, + NULL, + (NewFunc) _tp_call_channel_new_with_factory, + { TP_CALL_CHANNEL_FEATURE_CORE, + 0 }, + }, + { NULL } + }; + + g_return_if_fail (channel_type_mapping == NULL); + + channel_type_mapping = g_memdup (i_hate_c, sizeof i_hate_c); +} + static TpChannel * create_channel_impl (TpSimpleClientFactory *self, TpConnection *conn, @@ -128,44 +215,20 @@ create_channel_impl (TpSimpleClientFactory *self, GError **error) { const gchar *chan_type; + ChannelTypeMapping *m; chan_type = tp_asv_get_string (properties, TP_PROP_CHANNEL_CHANNEL_TYPE); - if (!tp_strdiff (chan_type, TP_IFACE_CHANNEL_TYPE_STREAM_TUBE)) - { - return (TpChannel *) _tp_stream_tube_channel_new_with_factory (self, conn, - object_path, properties, error); - } - else if (!tp_strdiff (chan_type, TP_IFACE_CHANNEL_TYPE_DBUS_TUBE)) + for (m = channel_type_mapping; m->channel_type != NULL; m++) { - return (TpChannel *) _tp_dbus_tube_channel_new_with_factory (self, conn, - object_path, properties, error); - } - else if (!tp_strdiff (chan_type, TP_IFACE_CHANNEL_TYPE_TEXT)) - { - const gchar * const * interfaces; - - interfaces = tp_asv_get_strv (properties, TP_PROP_CHANNEL_INTERFACES); + if (tp_strdiff (chan_type, m->channel_type)) + continue; - /* Create a TpTextChannel only if the channel supports Messages */ - if (tp_strv_contains (interfaces, TP_IFACE_CHANNEL_INTERFACE_MESSAGES)) - { - return (TpChannel *) _tp_text_channel_new_with_factory (self, conn, - object_path, properties, error); - } + if (m->check_properties != NULL && + !m->check_properties (object_path, properties)) + break; - DEBUG ("channel %s doesn't implement Messages so we can't create " - "a TpTextChannel", object_path); - } - else if (!tp_strdiff (chan_type, TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER)) - { - return (TpChannel *) _tp_file_transfer_channel_new_with_factory (self, - conn, object_path, properties, error); - } - else if (!tp_strdiff (chan_type, TP_IFACE_CHANNEL_TYPE_CALL)) - { - return (TpChannel *) _tp_call_channel_new_with_factory (self, - conn, object_path, properties, error); + return m->new_func (self, conn, object_path, properties, error); } /* Chainup on parent implementation as fallback */ @@ -177,34 +240,26 @@ dup_channel_features_impl (TpSimpleClientFactory *self, TpChannel *channel) { GArray *features; - GQuark feature; + GQuark standard_features[] = { + TP_CHANNEL_FEATURE_GROUP, + TP_CHANNEL_FEATURE_PASSWORD, + }; + ChannelTypeMapping *m; /* Chainup to get desired features for all channel types */ features = chainup->dup_channel_features (self, channel); - feature = TP_CHANNEL_FEATURE_GROUP; - g_array_append_val (features, feature); - - feature = TP_CHANNEL_FEATURE_PASSWORD; - g_array_append_val (features, feature); + g_array_append_vals (features, standard_features, G_N_ELEMENTS (standard_features)); - if (TP_IS_TEXT_CHANNEL (channel)) - { - feature = TP_TEXT_CHANNEL_FEATURE_INCOMING_MESSAGES; - g_array_append_val (features, feature); - - feature = TP_TEXT_CHANNEL_FEATURE_SMS; - g_array_append_val (features, feature); - } - else if (TP_IS_FILE_TRANSFER_CHANNEL (channel)) + for (m = channel_type_mapping; m->channel_type != NULL; m++) { - feature = TP_FILE_TRANSFER_CHANNEL_FEATURE_CORE; - g_array_append_val (features, feature); - } - else if (TP_IS_CALL_CHANNEL (channel)) - { - feature = TP_CALL_CHANNEL_FEATURE_CORE; - g_array_append_val (features, feature); + if (G_TYPE_CHECK_INSTANCE_TYPE (channel, m->gtype)) + { + guint j; + for (j = 0; m->features[j] != 0; j++) + g_array_append_val (features, m->features[j]); + break; + } } return features; @@ -222,6 +277,8 @@ tp_automatic_client_factory_class_init (TpAutomaticClientFactoryClass *cls) simple_class->create_channel = create_channel_impl; simple_class->dup_channel_features = dup_channel_features_impl; + + build_channel_type_mapping (); } /** |