[telepathy-glib/master] account: change behaviour of features

Jonny Lamb jonny.lamb at collabora.co.uk
Tue Sep 22 16:45:21 PDT 2009


Ignore unknown features (pretend they're ready on a become_ready call,
but not on _is_ready).

Also remove subtle "add features as _get_feature is called" behaviour
and have them all added in constructed.

Signed-off-by: Jonny Lamb <jonny.lamb at collabora.co.uk>
---
 telepathy-glib/account.c |  100 +++++++++++++++++++++++++++------------------
 telepathy-glib/account.h |    2 +-
 2 files changed, 61 insertions(+), 41 deletions(-)

diff --git a/telepathy-glib/account.c b/telepathy-glib/account.c
index 58b7569..54f4e05 100644
--- a/telepathy-glib/account.c
+++ b/telepathy-glib/account.c
@@ -184,6 +184,19 @@ tp_account_get_feature_quark_core (void)
   return g_quark_from_static_string ("tp-account-feature-core");
 }
 
+static const GQuark *
+_tp_account_get_known_features (void)
+{
+  static GQuark features[1] = { 0 };
+
+  if (G_UNLIKELY (features[0] == 0))
+    {
+      features[0] = TP_ACCOUNT_FEATURE_CORE;
+    }
+
+  return features;
+}
+
 static void
 tp_account_init (TpAccount *self)
 {
@@ -195,32 +208,42 @@ tp_account_init (TpAccount *self)
 
 static TpAccountFeature *
 _tp_account_get_feature (TpAccount *self,
-    GQuark feature,
-    gboolean add)
+    GQuark feature)
 {
   TpAccountPrivate *priv = self->priv;
   GList *l;
-  TpAccountFeature *feat = NULL;
 
   for (l = priv->features; l != NULL; l = l->next)
     {
-      feat = l->data;
+      TpAccountFeature *f = l->data;
 
-      if (feat->name == feature)
-        break;
+      if (f->name == feature)
+        return f;
     }
 
-  if (feat == NULL && add)
+  return NULL;
+}
+
+static gboolean
+_tp_account_check_features (TpAccount *self,
+    const GQuark *features)
+{
+  const GQuark *f;
+
+  for (f = features; *f != 0; f++)
     {
-      feat = g_slice_new0 (TpAccountFeature);
-      feat->name = feature;
-      feat->ready = FALSE;
-      priv->features = g_list_prepend (priv->features, feat);
+      TpAccountFeature *feat;
 
-      g_array_append_val (priv->features_array, feature);
+      feat = _tp_account_get_feature (self, *f);
+
+      /* features which are NULL (ie. don't exist) are always considered as
+       * being ready, except in _is_ready when it doesn't make sense to
+       * return TRUE. */
+      if (feat != NULL && !feat->ready)
+        return FALSE;
     }
 
-  return feat;
+  return TRUE;
 }
 
 static void
@@ -231,29 +254,22 @@ _tp_account_become_ready (TpAccount *self,
   TpAccountFeature *f = NULL;
   GList *l, *remove = NULL;
 
-  f = _tp_account_get_feature (self, feature, TRUE);
+  f = _tp_account_get_feature (self, feature);
+
+  g_assert (f != NULL);
 
   if (f->ready)
     return;
 
   f->ready = TRUE;
 
+  g_array_append_val (priv->features_array, feature);
+
   for (l = priv->callbacks; l != NULL; l = l->next)
     {
       TpAccountFeatureCallback *cb = l->data;
-      gboolean ready = TRUE;
-      guint i;
-
-      for (i = 0; cb->features[i] != 0; i++)
-        {
-          if (!tp_account_is_ready (self, cb->features[i]))
-            {
-              ready = FALSE;
-              break;
-            }
-        }
 
-      if (ready)
+      if (_tp_account_check_features (self, cb->features))
         {
           remove = g_list_prepend (remove, l);
           g_simple_async_result_complete (cb->result);
@@ -676,6 +692,8 @@ _tp_account_constructed (GObject *object)
     ((GObjectClass *) tp_account_parent_class)->constructed;
   GError *error = NULL;
   TpProxySignalConnection *sc;
+  guint i;
+  const GQuark *known_features;
 
   if (chain_up != NULL)
     chain_up (object);
@@ -686,6 +704,18 @@ _tp_account_constructed (GObject *object)
   priv->callbacks = NULL;
   priv->features_array = g_array_new (TRUE, FALSE, sizeof (GQuark));
 
+  known_features = _tp_account_get_known_features ();
+
+  /* Fill features list */
+  for (i = 0; i < G_N_ELEMENTS (known_features); i++)
+    {
+      TpAccountFeature *feature;
+      feature = g_slice_new0 (TpAccountFeature);
+      feature->name = known_features[i];
+      feature->ready = FALSE;
+      priv->features = g_list_prepend (priv->features, feature);
+    }
+
   sc = tp_cli_account_connect_to_removed (self, _tp_account_removed_cb,
       NULL, NULL, NULL, &error);
 
@@ -2499,7 +2529,6 @@ tp_account_get_avatar_finish (TpAccount *account,
  * tp_account_is_ready:
  * @account: a #TpAccount
  * @feature: a feature which is required
- * @error: a #GError to fill
  *
  * <!-- -->
  *
@@ -2513,7 +2542,7 @@ tp_account_is_ready (TpAccount *account,
 {
   TpAccountFeature *f;
 
-  f = _tp_account_get_feature (account, feature, FALSE);
+  f = _tp_account_get_feature (account, feature);
 
   if (f == NULL)
     return FALSE;
@@ -2547,18 +2576,9 @@ tp_account_prepare_async (TpAccount *account,
 {
   TpAccountPrivate *priv = account->priv;
   GSimpleAsyncResult *result;
-  guint i;
-  gboolean already_ready = TRUE;
 
-  for (i = 0; features[i] != 0; i++)
-    {
-      TpAccountFeature *f;
-
-      f = _tp_account_get_feature (account, features[i], TRUE);
-
-      if (!f->ready)
-        already_ready = FALSE;
-    }
+  /* In this object, there are no features which are activatable (core is
+   * forced on you). They'd be activated here though. */
 
   if (callback == NULL)
     return;
@@ -2566,7 +2586,7 @@ tp_account_prepare_async (TpAccount *account,
   result = g_simple_async_result_new (G_OBJECT (account),
       callback, user_data, tp_account_prepare_finish);
 
-  if (already_ready)
+  if (_tp_account_check_features (account, features))
     {
       g_simple_async_result_complete (result);
       g_object_unref (result);
diff --git a/telepathy-glib/account.h b/telepathy-glib/account.h
index 962d8b7..3e6da96 100644
--- a/telepathy-glib/account.h
+++ b/telepathy-glib/account.h
@@ -69,7 +69,7 @@ GType tp_account_get_type (void);
 #define TP_ACCOUNT_FEATURE_CORE \
   tp_account_get_feature_quark_core ()
 
-GQuark tp_account_get_feature_quark_core (void);
+GQuark tp_account_get_feature_quark_core (void) G_GNUC_CONST;
 
 TpAccount *tp_account_new (TpDBusDaemon *bus_daemon, const gchar *object_path,
     GError **error);
-- 
1.5.6.5




More information about the telepathy-commits mailing list