diff options
author | Cosimo Alfarano <cosimo.alfarano@collabora.co.uk> | 2010-01-28 16:47:31 +0000 |
---|---|---|
committer | Cosimo Alfarano <cosimo.alfarano@collabora.co.uk> | 2010-01-28 16:47:31 +0000 |
commit | c7ec23cd07f386ea33131e88dbe328622c51da78 (patch) | |
tree | 7ef32c3618741842aa254d8bf0957f418bebc2a9 | |
parent | 38342ffb98648723a62cb884adca78700c0de6b7 (diff) |
added a Channel Factory to transparently handle channels
* channel-factory module will handle the creation of TplChannel subclasses transparently, updating two static array everytime it's a new subclass is added
-rw-r--r-- | telepathy-logger/Makefile.am | 1 | ||||
-rw-r--r-- | telepathy-logger/channel-factory.c | 81 | ||||
-rw-r--r-- | telepathy-logger/channel-factory.h | 38 | ||||
-rw-r--r-- | telepathy-logger/channel-text.c | 17 | ||||
-rw-r--r-- | telepathy-logger/channel.c | 50 | ||||
-rw-r--r-- | telepathy-logger/channel.h | 14 | ||||
-rw-r--r-- | telepathy-logger/observer.c | 19 |
7 files changed, 168 insertions, 52 deletions
diff --git a/telepathy-logger/Makefile.am b/telepathy-logger/Makefile.am index 79c1893b4..14cc182d8 100644 --- a/telepathy-logger/Makefile.am +++ b/telepathy-logger/Makefile.am @@ -26,6 +26,7 @@ LIBTPL_HEADERS = \ libtelepathy_logger_la_SOURCES = \ datetime.c \ channel.c \ + channel-factory.c \ channel-text.c \ conf.c \ contact.c \ diff --git a/telepathy-logger/channel-factory.c b/telepathy-logger/channel-factory.c new file mode 100644 index 000000000..35987efeb --- /dev/null +++ b/telepathy-logger/channel-factory.c @@ -0,0 +1,81 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 2009 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Cosimo Alfarano <cosimo.alfarano@collabora.co.uk> + */ + +#include "channel-factory.h" + +#include <telepathy-glib/util.h> + +#include <telepathy-logger/channel-text.h> + +/* +static TplChannel * +text_new_wrap (TpConnection *conn, + const gchar *object_path, + GHashTable *tp_chan_props, + TpAccount *account, + GError **error) +{ + g_debug ("FOO"); + return TPL_CHANNEL (tpl_channel_text_new (conn, object_path, tp_chan_props, + account, error)); +} +*/ +static gchar *channel_types[] = { + "org.freedesktop.Telepathy.Channel.Type.Text", + NULL +}; +static TplChannelConstructor channel_constructors[] = { + (TplChannelConstructor) tpl_channel_text_new, + NULL +}; + + + +TplChannel * +tpl_channel_factory (const gchar *channel_type, + TpConnection *conn, + const gchar *object_path, + GHashTable *tp_chan_props, + TpAccount *tp_acc, + GError **error) +{ + guint i; + TplChannelConstructor chan_constructor = NULL; + + if (G_N_ELEMENTS (channel_types) != G_N_ELEMENTS (channel_constructors)) + g_critical ("channel_types and channel_constructors have different sizes." + " An update to the channel factory's data is needed."); + + for(i=0; i < G_N_ELEMENTS (channel_types); ++i) + if (!tp_strdiff (channel_type, channel_types[i])) { + chan_constructor = channel_constructors[i]; + continue; + } + + if (chan_constructor == NULL) + { + g_debug ("%s: channel type not handled by this logger", channel_type); + return NULL; + } + + return chan_constructor (conn, object_path, tp_chan_props, tp_acc, error); +} + diff --git a/telepathy-logger/channel-factory.h b/telepathy-logger/channel-factory.h new file mode 100644 index 000000000..3d1677a7a --- /dev/null +++ b/telepathy-logger/channel-factory.h @@ -0,0 +1,38 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 2009 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Cosimo Alfarano <cosimo.alfarano@collabora.co.uk> + */ + +#ifndef __TPL_CHANNEL_FACTORY_H__ +#define __TPL_CHANNEL_FACTORY_H__ + +#include <glib-object.h> +#include <telepathy-glib/connection.h> +#include <telepathy-glib/account.h> + +#include <telepathy-logger/channel.h> + +typedef TplChannel* (*TplChannelConstructor) (TpConnection *conn, + const gchar *object_path, GHashTable *tp_chan_props, TpAccount *tp_acc, + GError **error); +TplChannel *tpl_channel_factory (const gchar *channel_type, + TpConnection *conn, const gchar *object_path, GHashTable *tp_chan_props, + TpAccount *tp_acc, GError **error); + +#endif /* __TPL_CHANNEL_FACTORY_H__ */ diff --git a/telepathy-logger/channel-text.c b/telepathy-logger/channel-text.c index 0afb70a82..09d18f161 100644 --- a/telepathy-logger/channel-text.c +++ b/telepathy-logger/channel-text.c @@ -58,6 +58,8 @@ static TpContactFeature features[TP_CONTACT_FEATURES_LEN] = { TP_CONTACT_FEATURE_PRESENCE }; +static void call_when_ready_wrapper (TplChannel *tpl_chan, GAsyncReadyCallback + cb, gpointer user_data); static void got_tpl_chan_ready_cb (GObject *obj, GAsyncResult *result, gpointer user_data); static void _channel_on_closed_cb (TpChannel *proxy, gpointer user_data, @@ -258,10 +260,12 @@ static void tpl_channel_text_class_init (TplChannelTextClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); + TplChannelClass *tpl_chan_class = TPL_CHANNEL_CLASS (klass); object_class->dispose = tpl_channel_text_dispose; object_class->finalize = tpl_channel_text_finalize; - //object_class->constructor = tpl_channel_text_constructor; + + tpl_chan_class->call_when_ready = call_when_ready_wrapper; g_type_class_add_private (object_class, sizeof (TplChannelTextPriv)); } @@ -305,6 +309,7 @@ tpl_channel_text_new (TpConnection *conn, /* Do what tpl_channel_new does + set TplChannelText specific properties */ +g_debug ("TPL CHAN TEXT NEW!"); g_return_val_if_fail (TP_IS_CONNECTION (conn), NULL); g_return_val_if_fail (TP_IS_ACCOUNT (account), NULL); g_return_val_if_fail (!TPL_STR_EMPTY (object_path), NULL); @@ -419,6 +424,14 @@ tpl_channel_text_set_chatroom_id (TplChannelText *self, priv->chatroom_id = g_strdup (data); } +static void +call_when_ready_wrapper (TplChannel *tpl_chan, + GAsyncReadyCallback cb, + gpointer user_data) +{ + tpl_channel_text_call_when_ready( TPL_CHANNEL_TEXT (tpl_chan), cb, + user_data); +} void tpl_channel_text_call_when_ready (TplChannelText *self, @@ -448,7 +461,7 @@ pendingproc_prepare_tpl_channel (TplActionChain *ctx) TplChannel *tpl_chan = TPL_CHANNEL (tpl_actionchain_get_object (ctx)); g_debug ("prepare tpl"); - TPL_CHANNEL_GET_CLASS (tpl_chan)->call_when_ready (tpl_chan, + TPL_CHANNEL_GET_CLASS (tpl_chan)->call_when_ready_protected (tpl_chan, got_tpl_chan_ready_cb, ctx); } diff --git a/telepathy-logger/channel.c b/telepathy-logger/channel.c index 3b68e02b1..45a6cd715 100644 --- a/telepathy-logger/channel.c +++ b/telepathy-logger/channel.c @@ -32,8 +32,8 @@ #define TPCHAN_PROP_PREFIX_LEN strlen(TPCHAN_PROP_PREFIX) static void tpl_channel_set_account (TplChannel *self, TpAccount *data); -static void tpl_channel_call_when_ready (TplChannel *self, GAsyncReadyCallback cb, - gpointer user_data); +static void call_when_ready_protected (TplChannel *self, + GAsyncReadyCallback cb, gpointer user_data); static void pendingproc_get_ready_tp_connection (TplActionChain *ctx); static void got_ready_tp_connection_cb (TpConnection *connection, const GError *error, gpointer user_data); @@ -42,17 +42,6 @@ static void got_ready_tp_channel_cb (TpChannel *channel, const GError *error, gpointer user_data); static void pendingproc_register_tpl_channel (TplActionChain *ctx); -static gchar *channel_types[] = { - "org.freedesktop.Telepathy.Channel.Type.Text", - NULL -}; - -static TplChannelConstructor *channel_constructors[] = { - (TplChannelConstructor*) tpl_channel_text_new, - NULL -}; - - G_DEFINE_ABSTRACT_TYPE (TplChannel, tpl_channel, TP_TYPE_CHANNEL) #define GET_PRIV(obj) TPL_GET_PRIV (obj, TplChannel) @@ -132,7 +121,7 @@ tpl_channel_class_init (TplChannelClass *klass) object_class->get_property = get_prop; object_class->set_property = set_prop; - klass->call_when_ready = tpl_channel_call_when_ready; + klass->call_when_ready_protected = call_when_ready_protected; param_spec = g_param_spec_object ("account", "Account", "TpAccount instance associated with TplChannel", @@ -179,25 +168,6 @@ tpl_channel_set_account (TplChannel *self, } -TplChannelConstructor * -tpl_channel_factory (const gchar *channel_type) -{ - guint i; - - if (G_N_ELEMENTS (channel_types) != G_N_ELEMENTS (channel_constructors)) - g_critical ("channel_types and channel_constructors have different sizes"); - - for(i=0; i < G_N_ELEMENTS (channel_types); ++i) - if (tp_strdiff (channel_type, channel_types[i])) - return channel_constructors[i]; - - /* if the flow reaches here, it means that channel_type is not among the - recognized ones */ - g_debug ("%s: channel type not handled by this logger", channel_type); - return NULL; -} - - /** * It has to be called by all the child classes in order to prepare all the * objects involved in the logging process. @@ -205,8 +175,20 @@ tpl_channel_factory (const gchar *channel_type) * It internally calls _call_when_ready for TpAccount TpConnection and * TpChannel itself. When everything is ready calls the user passed callback. */ +void tpl_channel_call_when_ready (TplChannel *self, + GAsyncReadyCallback cb, + gpointer user_data) +{ + g_return_if_fail (TPL_IS_CHANNEL (self)); + /* Subclasses have to implement it */ + g_return_if_fail (TPL_CHANNEL_GET_CLASS (self)->call_when_ready != NULL); + + TPL_CHANNEL_GET_CLASS (self)->call_when_ready (self, cb, user_data); +} + + static void -tpl_channel_call_when_ready (TplChannel *self, +call_when_ready_protected (TplChannel *self, GAsyncReadyCallback cb, gpointer user_data) { diff --git a/telepathy-logger/channel.h b/telepathy-logger/channel.h index 123ea18f1..2df877d53 100644 --- a/telepathy-logger/channel.h +++ b/telepathy-logger/channel.h @@ -52,20 +52,20 @@ typedef struct typedef struct { TpChannelClass parent_class; - + /* Virtual method, to be implemented by subclasses */ void (*call_when_ready) (TplChannel *self, GAsyncReadyCallback cb, gpointer user_data); + /* Protected method, should be called only by subclasses to prepare + * TplChannel */ + void (*call_when_ready_protected) (TplChannel *self, GAsyncReadyCallback cb, + gpointer user_data); } TplChannelClass; - GType tpl_channel_get_type (void); TpAccount *tpl_channel_get_account (TplChannel * self); -const gchar *tpl_channel_get_account_path (TplChannel * self); - -typedef TplChannel* (*TplChannelConstructor) (TpConnection *conn, - const gchar *object_path, GHashTable *tp_chan_props, GError **error); -TplChannelConstructor *tpl_channel_factory (const gchar *channel_type); +void tpl_channel_call_when_ready (TplChannel *self, GAsyncReadyCallback cb, + gpointer user_data); G_END_DECLS #endif // __TPL_CHANNEL_H__ diff --git a/telepathy-logger/observer.c b/telepathy-logger/observer.c index 4519ffc87..ac677276e 100644 --- a/telepathy-logger/observer.c +++ b/telepathy-logger/observer.c @@ -31,7 +31,7 @@ #include <telepathy-logger/conf.h> #include <telepathy-logger/channel.h> -#include <telepathy-logger/channel-text.h> +#include <telepathy-logger/channel-factory.h> #include <telepathy-logger/log-manager.h> // TODO move to a member of TplObserver @@ -82,6 +82,7 @@ tpl_observer_observe_channels (TpSvcClientObserver *self, TpDBusDaemon *tp_bus_daemon; TplConf *conf; GError *error = NULL; + const gchar *chan_type; g_return_if_fail (!TPL_STR_EMPTY (account) ); g_return_if_fail (!TPL_STR_EMPTY (connection) ); @@ -143,15 +144,15 @@ tpl_observer_observe_channels (TpSvcClientObserver *self, TplChannel *tpl_chan; gchar *path = g_value_get_boxed (g_value_array_get_nth (channel, 0)); - // d.bus.propertyName.str/gvalue hash + /* d.bus.propertyName.str/gvalue hash */ GHashTable *map = g_value_get_boxed (g_value_array_get_nth (channel, 1)); - //tpl_channel_factory (g_value_get_string (g_hash_table_lookup (map, - // TP_PROP_CHANNEL_CHANNEL_TYPE))); - - tpl_chan = TPL_CHANNEL (tpl_channel_text_new (tp_conn, path, map, - tp_acc, &error)); + chan_type = g_value_get_string (g_hash_table_lookup (map, + TP_PROP_CHANNEL_CHANNEL_TYPE)); + g_debug ("CHAN TYPE %s", chan_type); + tpl_chan = tpl_channel_factory (chan_type, tp_conn, path, map, tp_acc, + &error); if (tpl_chan == NULL) { g_debug ("%s", error->message); @@ -160,8 +161,8 @@ tpl_observer_observe_channels (TpSvcClientObserver *self, error = NULL; continue; } - tpl_channel_text_call_when_ready (TPL_CHANNEL_TEXT (tpl_chan), - got_tpl_channel_text_ready_cb, context); + tpl_channel_call_when_ready (tpl_chan, got_tpl_channel_text_ready_cb, + context); } g_object_unref (tp_acc); |