[folks] Split setup of PersonaStores out into a PersonaStore.prepare() method
- From: Philip Withnall <pwithnall src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [folks] Split setup of PersonaStores out into a PersonaStore.prepare() method
- Date: Wed, 21 Jul 2010 09:39:15 +0000 (UTC)
commit 14d0402e7ec633786ce91f9b877d2855deaff4d3
Author: Philip Withnall <philip withnall collabora co uk>
Date: Wed Jun 30 13:52:08 2010 +0100
Split setup of PersonaStores out into a PersonaStore.prepare() method
This allows the PersonaStore.personas_added and PersonaStore.personas_removed
signals to be connected to before the PersonaStore could first emit them,
removing a race condition.
backends/telepathy/tpf-persona-store.vala | 4 +++
folks/individual-aggregator.vala | 17 +++++++++++++++-
folks/persona-store.vala | 30 +++++++++++++++++++++++++++++
3 files changed, 50 insertions(+), 1 deletions(-)
---
diff --git a/backends/telepathy/tpf-persona-store.vala b/backends/telepathy/tpf-persona-store.vala
index f941630..095142c 100644
--- a/backends/telepathy/tpf-persona-store.vala
+++ b/backends/telepathy/tpf-persona-store.vala
@@ -117,6 +117,10 @@ public class Tpf.PersonaStore : Folks.PersonaStore
this.groups = new HashMap<string, Channel> ();
this.favourite_handles = new HashSet<uint> ();
this.ll = new TpLowlevel ();
+ }
+
+ public override async void prepare ()
+ {
this.account_manager = AccountManager.dup ();
this.account_manager.account_disabled.connect ((a) =>
diff --git a/folks/individual-aggregator.vala b/folks/individual-aggregator.vala
index 4282017..f1f523c 100644
--- a/folks/individual-aggregator.vala
+++ b/folks/individual-aggregator.vala
@@ -112,8 +112,23 @@ public class Folks.IndividualAggregator : Object
private void backend_persona_store_added_cb (Backend backend,
PersonaStore store)
{
- this.stores.set (this.get_store_full_id (store.type_id, store.id), store);
+ string store_id = this.get_store_full_id (store.type_id, store.id);
+
+ this.stores.set (store_id, store);
store.personas_changed.connect (this.personas_changed_cb);
+
+ store.prepare.begin ((obj, result) =>
+ {
+ try
+ {
+ store.prepare.end (result);
+ }
+ catch (GLib.Error e)
+ {
+ warning ("Error preparing PersonaStore '%s': %s", store_id,
+ e.message);
+ }
+ });
}
private void backend_persona_store_removed_cb (Backend backend,
diff --git a/folks/persona-store.vala b/folks/persona-store.vala
index 94cecbe..95350b4 100644
--- a/folks/persona-store.vala
+++ b/folks/persona-store.vala
@@ -39,6 +39,12 @@ public errordomain Folks.PersonaStoreError
/**
* A store for { link Persona}s.
+ *
+ * After creating a PersonaStore instance, you must connect to the
+ * { link PersonaStore.personas_changed} signal, //then// call
+ * { link PersonaStore.prepare}, otherwise a race condition may occur between
+ * emission of { link PersonaStore.personas_changed} and your code connecting to
+ * it.
*/
public abstract class Folks.PersonaStore : Object
{
@@ -46,6 +52,9 @@ public abstract class Folks.PersonaStore : Object
* Emitted when one or more { link Persona}s are added to or removed from
* the store.
*
+ * This will not be emitted until after { link PersonaStore.prepare} has been
+ * called.
+ *
* @param added a list of { link Persona}s which have been removed
* @param removed a list of { link Persona}s which have been removed
* @param message a string message from the backend, if any
@@ -63,6 +72,9 @@ public abstract class Folks.PersonaStore : Object
*
* At this point, the PersonaStore and all its { link Persona}s are invalid,
* so any client referencing it should unreference it.
+ *
+ * This will not be emitted until after { link PersonaStore.prepare} has been
+ * called.
*/
public abstract signal void removed ();
@@ -70,6 +82,9 @@ public abstract class Folks.PersonaStore : Object
* The type of PersonaStore this is.
*
* This is the same for all PersonaStores provided by a given { link Backend}.
+ *
+ * This is guaranteed to always be available; even before
+ * { link PersonaStore.prepare} is called.
*/
public abstract string type_id { get; protected set; }
@@ -88,6 +103,21 @@ public abstract class Folks.PersonaStore : Object
public abstract HashTable<string, Persona> personas { get; }
/**
+ * Prepare the PersonaStore for use.
+ *
+ * This connects the PersonaStore to whichever backend-specific services it
+ * requires to be able to provide { link Persona}s. This should be called
+ * //after// connecting to the { link PersonaStore.personas_changed} signal,
+ * or a race condition could occur, with the signal being emitted before your
+ * code has connected to it, and { link Persona}s getting "lost" as a result.
+ *
+ * This is normally handled transparently by the { link IndividualAggregator}.
+ *
+ * If this function throws an error, the PersonaStore will not be functional.
+ */
+ public abstract async void prepare () throws GLib.Error;
+
+ /**
* Add a new { link Persona} to the PersonaStore.
*
* The { link Persona} will be created by the PersonaStore backend from the
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]