[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