From ee845c3030dc75f0717d1ac8bfc40a6492b82198 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Wed, 6 Nov 2013 19:30:57 +0000 Subject: [PATCH 10/11] Simplify TpPresenceMixin by making the "get contact status" vfunc singular --- .../telepathy-glib/telepathy-glib-sections.txt | 2 +- examples/cm/call/conn.c | 57 ++++++++----------- examples/cm/contactlist/conn.c | 52 ++++++++--------- telepathy-glib/presence-mixin.c | 65 +++++++--------------- telepathy-glib/presence-mixin.h | 8 +-- tests/lib/contacts-conn.c | 48 +++++++--------- 6 files changed, 90 insertions(+), 142 deletions(-) diff --git a/docs/reference/telepathy-glib/telepathy-glib-sections.txt b/docs/reference/telepathy-glib/telepathy-glib-sections.txt index 2f25e6e..a260d01 100644 --- a/docs/reference/telepathy-glib/telepathy-glib-sections.txt +++ b/docs/reference/telepathy-glib/telepathy-glib-sections.txt @@ -1668,7 +1668,7 @@ TpBaseRoomConfigPrivate TpPresenceStatusOptionalArgumentSpec TpPresenceStatusSpec TpPresenceMixinStatusAvailableFunc -TpPresenceMixinGetContactStatusesFunc +TpPresenceMixinGetContactStatusFunc TpPresenceMixinSetOwnStatusFunc TpPresenceMixinGetMaximumStatusMessageLengthFunc TpPresenceStatus diff --git a/examples/cm/call/conn.c b/examples/cm/call/conn.c index e4d69eb..a8637da 100644 --- a/examples/cm/call/conn.c +++ b/examples/cm/call/conn.c @@ -231,47 +231,38 @@ status_available (GObject *object, return tp_base_connection_check_connected (base, NULL); } -static GHashTable * -get_contact_statuses (GObject *object, - const GArray *contacts) +static TpPresenceStatus * +get_contact_status (GObject *object, + TpHandle contact) { ExampleCallConnection *self = EXAMPLE_CALL_CONNECTION (object); TpBaseConnection *base = TP_BASE_CONNECTION (object); - guint i; - GHashTable *result = g_hash_table_new_full (g_direct_hash, g_direct_equal, - NULL, (GDestroyNotify) tp_presence_status_free); - - for (i = 0; i < contacts->len; i++) - { - TpHandle contact = g_array_index (contacts, guint, i); - ExampleCallPresence presence; - GHashTable *parameters; + ExampleCallPresence presence; + GHashTable *parameters; + TpPresenceStatus *result; - parameters = g_hash_table_new_full (g_str_hash, - g_str_equal, NULL, (GDestroyNotify) tp_g_value_slice_free); + parameters = g_hash_table_new_full (g_str_hash, + g_str_equal, NULL, (GDestroyNotify) tp_g_value_slice_free); - /* we know our own status from the connection; for this example CM, - * everyone else's status is assumed to be "available" */ - if (contact == tp_base_connection_get_self_handle (base)) - { - presence = (self->priv->away ? EXAMPLE_CALL_PRESENCE_AWAY - : EXAMPLE_CALL_PRESENCE_AVAILABLE); - - if (self->priv->presence_message[0] != '\0') - g_hash_table_insert (parameters, "message", - tp_g_value_slice_new_string (self->priv->presence_message)); - } - else - { - presence = EXAMPLE_CALL_PRESENCE_AVAILABLE; - } + /* we know our own status from the connection; for this example CM, + * everyone else's status is assumed to be "available" */ + if (contact == tp_base_connection_get_self_handle (base)) + { + presence = (self->priv->away ? EXAMPLE_CALL_PRESENCE_AWAY + : EXAMPLE_CALL_PRESENCE_AVAILABLE); - g_hash_table_insert (result, GUINT_TO_POINTER (contact), - tp_presence_status_new (presence, parameters)); - g_hash_table_unref (parameters); + if (self->priv->presence_message[0] != '\0') + g_hash_table_insert (parameters, "message", + tp_g_value_slice_new_string (self->priv->presence_message)); + } + else + { + presence = EXAMPLE_CALL_PRESENCE_AVAILABLE; } + result = tp_presence_status_new (presence, parameters); + g_hash_table_unref (parameters); return result; } @@ -436,7 +427,7 @@ example_call_connection_class_init ( tp_presence_mixin_class_init (object_class, G_STRUCT_OFFSET (ExampleCallConnectionClass, presence_mixin), - status_available, get_contact_statuses, set_own_status, + status_available, get_contact_status, set_own_status, presence_statuses); tp_presence_mixin_init_dbus_properties (object_class); } diff --git a/examples/cm/contactlist/conn.c b/examples/cm/contactlist/conn.c index 2e79406..ec37b08 100644 --- a/examples/cm/contactlist/conn.c +++ b/examples/cm/contactlist/conn.c @@ -297,42 +297,34 @@ status_available (GObject *object, return tp_base_connection_check_connected (base, NULL); } -static GHashTable * -get_contact_statuses (GObject *object, - const GArray *contacts) +static TpPresenceStatus * +get_contact_status (GObject *object, + TpHandle contact) { ExampleContactListConnection *self = EXAMPLE_CONTACT_LIST_CONNECTION (object); TpBaseConnection *base = TP_BASE_CONNECTION (object); - guint i; - GHashTable *result = g_hash_table_new_full (g_direct_hash, g_direct_equal, - NULL, (GDestroyNotify) tp_presence_status_free); + ExampleContactListPresence presence; + GHashTable *parameters; + TpPresenceStatus *result; - for (i = 0; i < contacts->len; i++) + /* we get our own status from the connection, and everyone else's status + * from the contact lists */ + if (contact == tp_base_connection_get_self_handle (base)) { - TpHandle contact = g_array_index (contacts, guint, i); - ExampleContactListPresence presence; - GHashTable *parameters; - - /* we get our own status from the connection, and everyone else's status - * from the contact lists */ - if (contact == tp_base_connection_get_self_handle (base)) - { - presence = (self->priv->away ? EXAMPLE_CONTACT_LIST_PRESENCE_AWAY - : EXAMPLE_CONTACT_LIST_PRESENCE_AVAILABLE); - } - else - { - presence = example_contact_list_get_presence ( - self->priv->contact_list, contact); - } - - parameters = g_hash_table_new_full (g_str_hash, - g_str_equal, NULL, (GDestroyNotify) tp_g_value_slice_free); - g_hash_table_insert (result, GUINT_TO_POINTER (contact), - tp_presence_status_new (presence, parameters)); - g_hash_table_unref (parameters); + presence = (self->priv->away ? EXAMPLE_CONTACT_LIST_PRESENCE_AWAY + : EXAMPLE_CONTACT_LIST_PRESENCE_AVAILABLE); } + else + { + presence = example_contact_list_get_presence ( + self->priv->contact_list, contact); + } + + parameters = g_hash_table_new_full (g_str_hash, + g_str_equal, NULL, (GDestroyNotify) tp_g_value_slice_free); + result = tp_presence_status_new (presence, parameters); + g_hash_table_unref (parameters); return result; } @@ -477,7 +469,7 @@ example_contact_list_connection_class_init ( tp_presence_mixin_class_init (object_class, G_STRUCT_OFFSET (ExampleContactListConnectionClass, presence_mixin), - status_available, get_contact_statuses, set_own_status, + status_available, get_contact_status, set_own_status, example_contact_list_presence_statuses ()); tp_presence_mixin_init_dbus_properties (object_class); diff --git a/telepathy-glib/presence-mixin.c b/telepathy-glib/presence-mixin.c index 0db0af1..2211634 100644 --- a/telepathy-glib/presence-mixin.c +++ b/telepathy-glib/presence-mixin.c @@ -164,19 +164,13 @@ */ /** - * TpPresenceMixinGetContactStatusesFunc: + * TpPresenceMixinGetContactStatusFunc: * @obj: An object with this mixin. - * @contacts: An array of #TpHandle for the contacts to get presence status for + * @contact: A #TpHandle of type %TP_HANDLE_TYPE_CONTACT * - * Signature of the callback used to get the stored presence status of - * contacts. The returned hash table should have contact handles mapped to - * their respective presence statuses in #TpPresenceStatus structs. + * Return the contact's status * - * The returned hash table will be freed with g_hash_table_unref. The - * callback is responsible for ensuring that this does any cleanup that - * may be necessary. - * - * Returns: (transfer full): The contact presence, must not be %NULL. + * Returns: (transfer full): The contact's presence status */ /** @@ -221,7 +215,7 @@ * TpPresenceMixinClass: * @status_available: The status-available function that was passed to * tp_presence_mixin_class_init() - * @get_contact_statuses: The get-contact-statuses function that was passed to + * @get_contact_status: The get-contact-status function that was passed to * tp_presence_mixin_class_init() * @set_own_status: The set-own-status function that was passed to * tp_presence_mixin_class_init() @@ -389,7 +383,7 @@ tp_presence_mixin_get_offset_quark () * status can be set on a particular connection. Should usually be %NULL, to * consider all statuses with #TpPresenceStatusSpec.self set to %TRUE to be * settable. - * @get_contact_statuses: A callback to be used get the current presence status + * @get_contact_status: A callback to be used get the current presence status * for contacts. This is used in implementations of various D-Bus methods and * hence must be provided. * @set_own_status: A callback to be used to commit changes to the user's own @@ -412,7 +406,7 @@ void tp_presence_mixin_class_init (GObjectClass *obj_cls, glong offset, TpPresenceMixinStatusAvailableFunc status_available, - TpPresenceMixinGetContactStatusesFunc get_contact_statuses, + TpPresenceMixinGetContactStatusFunc get_contact_status, TpPresenceMixinSetOwnStatusFunc set_own_status, const TpPresenceStatusSpec *statuses) { @@ -421,7 +415,7 @@ tp_presence_mixin_class_init (GObjectClass *obj_cls, DEBUG ("called."); - g_assert (get_contact_statuses != NULL); + g_assert (get_contact_status != NULL); g_assert (set_own_status != NULL); g_assert (statuses != NULL); @@ -434,7 +428,7 @@ tp_presence_mixin_class_init (GObjectClass *obj_cls, mixin_cls = TP_PRESENCE_MIXIN_CLASS (obj_cls); mixin_cls->status_available = status_available; - mixin_cls->get_contact_statuses = get_contact_statuses; + mixin_cls->get_contact_status = get_contact_status; mixin_cls->set_own_status = set_own_status; mixin_cls->statuses = statuses; mixin_cls->get_maximum_status_message_length = NULL; @@ -915,50 +909,29 @@ tp_presence_mixin_fill_contact_attributes (GObject *obj, { TpPresenceMixinClass *mixin_cls = TP_PRESENCE_MIXIN_CLASS (G_OBJECT_GET_CLASS (obj)); - GHashTable *contact_statuses; - GArray *handles; + TpPresenceStatus *status; + GValueArray *presence; if (tp_strdiff (dbus_interface, TP_IFACE_CONNECTION_INTERFACE_PRESENCE1)) return FALSE; - handles = g_array_sized_new (FALSE, FALSE, sizeof (guint), 1); - g_array_append_val (handles, contact); + status = mixin_cls->get_contact_status (obj, contact); - /* FIXME: this would now be more efficient if it was singular */ - contact_statuses = mixin_cls->get_contact_statuses (obj, handles); - if (contact_statuses == NULL) + if (status == NULL) { - g_warning ("get_contact_statuses returned NULL"); + CRITICAL ("get_contact_status returned NULL"); } else { - GHashTableIter iter; - gpointer key, value; G_GNUC_BEGIN_IGNORE_DEPRECATIONS GType type = G_TYPE_VALUE_ARRAY; G_GNUC_END_IGNORE_DEPRECATIONS - g_hash_table_iter_init (&iter, contact_statuses); - while (g_hash_table_iter_next (&iter, &key, &value)) - { - TpHandle handle = GPOINTER_TO_UINT (key); - TpPresenceStatus *status = value; - GValueArray *presence; - - if (handle != contact) - g_warning ("get_contact_statuses returned someone else's status"); - - presence = construct_presence_value_array ( - status, mixin_cls->statuses); - - tp_contact_attribute_map_take_sliced_gvalue (attributes, contact, - TP_TOKEN_CONNECTION_INTERFACE_PRESENCE1_PRESENCE, - tp_g_value_slice_new_take_boxed (type, presence)); - } - - g_hash_table_unref (contact_statuses); + presence = construct_presence_value_array (status, mixin_cls->statuses); + tp_presence_status_free (status); + tp_contact_attribute_map_take_sliced_gvalue (attributes, contact, + TP_TOKEN_CONNECTION_INTERFACE_PRESENCE1_PRESENCE, + tp_g_value_slice_new_take_boxed (type, presence)); } - - g_array_unref (handles); return TRUE; } diff --git a/telepathy-glib/presence-mixin.h b/telepathy-glib/presence-mixin.h index 59f55ff..6d4e46b 100644 --- a/telepathy-glib/presence-mixin.h +++ b/telepathy-glib/presence-mixin.h @@ -74,8 +74,8 @@ void tp_presence_status_free (TpPresenceStatus *status); typedef gboolean (*TpPresenceMixinStatusAvailableFunc) (GObject *obj, guint which); -typedef GHashTable *(*TpPresenceMixinGetContactStatusesFunc) (GObject *obj, - const GArray *contacts); +typedef TpPresenceStatus *(*TpPresenceMixinGetContactStatusFunc) (GObject *obj, + TpHandle contact); typedef gboolean (*TpPresenceMixinSetOwnStatusFunc) (GObject *obj, const TpPresenceStatus *status, GError **error); @@ -90,7 +90,7 @@ typedef struct _TpPresenceMixinPrivate TpPresenceMixinPrivate; struct _TpPresenceMixinClass { TpPresenceMixinStatusAvailableFunc status_available; - TpPresenceMixinGetContactStatusesFunc get_contact_statuses; + TpPresenceMixinGetContactStatusFunc get_contact_status; TpPresenceMixinSetOwnStatusFunc set_own_status; const TpPresenceStatusSpec *statuses; @@ -132,7 +132,7 @@ GQuark tp_presence_mixin_get_offset_quark (void); void tp_presence_mixin_class_init (GObjectClass *obj_cls, glong offset, TpPresenceMixinStatusAvailableFunc status_available, - TpPresenceMixinGetContactStatusesFunc get_contact_statuses, + TpPresenceMixinGetContactStatusFunc get_contact_status, TpPresenceMixinSetOwnStatusFunc set_own_status, const TpPresenceStatusSpec *statuses); diff --git a/tests/lib/contacts-conn.c b/tests/lib/contacts-conn.c index 7dc864a..0812a3c 100644 --- a/tests/lib/contacts-conn.c +++ b/tests/lib/contacts-conn.c @@ -389,39 +389,31 @@ my_status_available (GObject *object, return tp_base_connection_check_connected (base, NULL); } -static GHashTable * -my_get_contact_statuses (GObject *object, - const GArray *contacts) +static TpPresenceStatus * +my_get_contact_status (GObject *object, + TpHandle contact) { TpTestsContactsConnection *self = TP_TESTS_CONTACTS_CONNECTION (object); - GHashTable *result = g_hash_table_new_full (g_direct_hash, g_direct_equal, - NULL, (GDestroyNotify) tp_presence_status_free); - guint i; - - for (i = 0; i < contacts->len; i++) - { - TpHandle handle = g_array_index (contacts, TpHandle, i); - gpointer key = GUINT_TO_POINTER (handle); - TpTestsContactsConnectionPresenceStatusIndex index; - const gchar *presence_message; - GHashTable *parameters; + TpPresenceStatus *result; + gpointer key = GUINT_TO_POINTER (contact); + TpTestsContactsConnectionPresenceStatusIndex index; + const gchar *presence_message; + GHashTable *parameters; - index = GPOINTER_TO_UINT (g_hash_table_lookup ( - self->priv->presence_statuses, key)); - presence_message = g_hash_table_lookup ( - self->priv->presence_messages, key); + index = GPOINTER_TO_UINT (g_hash_table_lookup ( + self->priv->presence_statuses, key)); + presence_message = g_hash_table_lookup ( + self->priv->presence_messages, key); - parameters = g_hash_table_new_full (g_str_hash, - g_str_equal, NULL, (GDestroyNotify) tp_g_value_slice_free); + parameters = g_hash_table_new_full (g_str_hash, + g_str_equal, NULL, (GDestroyNotify) tp_g_value_slice_free); - if (presence_message != NULL) - g_hash_table_insert (parameters, (gpointer) "message", - tp_g_value_slice_new_string (presence_message)); + if (presence_message != NULL) + g_hash_table_insert (parameters, (gpointer) "message", + tp_g_value_slice_new_string (presence_message)); - g_hash_table_insert (result, key, - tp_presence_status_new (index, parameters)); - g_hash_table_unref (parameters); - } + result = tp_presence_status_new (index, parameters); + g_hash_table_unref (parameters); return result; } @@ -553,7 +545,7 @@ tp_tests_contacts_connection_class_init (TpTestsContactsConnectionClass *klass) tp_presence_mixin_class_init (object_class, G_STRUCT_OFFSET (TpTestsContactsConnectionClass, presence_mixin), - my_status_available, my_get_contact_statuses, + my_status_available, my_get_contact_status, my_set_own_status, my_statuses); mixin_class = TP_PRESENCE_MIXIN_CLASS(klass); mixin_class->get_maximum_status_message_length = -- 1.8.4.2