Memoize the ContactInfo SupportedFields values.
authorTravis Reitter <travis.reitter@collabora.co.uk>
Thu, 6 Oct 2011 22:46:22 +0000 (15:46 -0700)
committerTravis Reitter <travis.reitter@collabora.co.uk>
Tue, 11 Oct 2011 01:13:16 +0000 (18:13 -0700)
backends/telepathy/lib/tpf-persona-store.vala
backends/telepathy/lib/tpf-persona.vala

index 20b315f..ec033b9 100644 (file)
@@ -107,6 +107,9 @@ public class Tpf.PersonaStore : Folks.PersonaStore
   private Cancellable? _load_cache_cancellable = null;
   private bool _cached = false;
 
+  /* marshalled from ContactInfo.SupportedFields */
+  internal HashSet<string> _supported_fields;
+  internal Set<string> _supported_fields_ro;
   internal signal void group_members_changed (string group,
       GLib.List<Persona>? added, GLib.List<Persona>? removed);
   internal signal void group_removed (string group, GLib.Error? error);
@@ -228,6 +231,11 @@ public class Tpf.PersonaStore : Folks.PersonaStore
       get { return this._personas_ro; }
     }
 
+  internal Set<string> supported_fields
+    {
+      get { return this._supported_fields_ro; }
+    }
+
   /**
    * Create a new PersonaStore.
    *
@@ -530,6 +538,8 @@ public class Tpf.PersonaStore : Folks.PersonaStore
             }
         }
 
+      this._supported_fields = new HashSet<string> ();
+      this._supported_fields_ro = this._supported_fields.read_only_view;
       this._groups = new HashMap<string, Channel> ();
       this._favourite_handles = new HashSet<uint> ();
       this._self_contact = null;
@@ -773,6 +783,9 @@ public class Tpf.PersonaStore : Folks.PersonaStore
       /* account disconnected */
       if (account.connection == null)
         {
+          this._supported_fields.clear ();
+          this.notify_property ("supported-fields");
+
           /* When disconnecting, we want the PersonaStore to remain alive, but
            * all its Personas to be removed. We do *not* want the PersonaStore
            * to be destroyed, as that makes coming back online hard.
@@ -842,6 +855,9 @@ public class Tpf.PersonaStore : Folks.PersonaStore
       FolksTpLowlevel.connection_connect_to_new_group_channels (c,
           this._new_group_channels_cb);
 
+      this._marshall_supported_fields ();
+      this.notify_property ("supported-fields");
+
       FolksTpLowlevel.connection_get_alias_flags_async.begin (c, (s2, res) =>
           {
             var new_can_alias = MaybeBool.FALSE;
@@ -936,6 +952,32 @@ public class Tpf.PersonaStore : Folks.PersonaStore
       this._initialise_favourite_contacts.begin ();
     }
 
+  private void _marshall_supported_fields ()
+    {
+      var connection = this.account.connection;
+      if (connection != null)
+        {
+          this._supported_fields.clear ();
+
+          var ci_flags = connection.get_contact_info_flags ();
+          if ((ci_flags & ContactInfoFlags.CAN_SET) != 0)
+            {
+              var field_specs =
+                connection.get_contact_info_supported_fields ();
+              foreach (var field_spec in field_specs)
+                {
+                  /* XXX: we ignore the maximum count for each type of
+                    * field since the common-sense count for each
+                    * corresponding field (eg, full-name max = 1) in
+                    * Folks is already reflected in our API and we have
+                    * no other way to express it; but this seems a very
+                    * minor problem */
+                  this._supported_fields.add (field_spec.name);
+                }
+            }
+        }
+    }
+
   /**
    * If our account is disconnected, we want to continue to export a static
    * view of personas from the cache.
index 3f2511b..c18ebec 100644 (file)
@@ -201,40 +201,7 @@ public class Tpf.Persona : Folks.Persona,
       get
         {
           if (this.is_user)
-            {
-              var connection =
-                ((Tpf.PersonaStore) this.store).account.connection;
-              if (connection != null)
-                {
-                  var ci_flags = connection.get_contact_info_flags ();
-                  if ((ci_flags & ContactInfoFlags.CAN_SET) != 0)
-                    {
-                      var field_specs =
-                        connection.get_contact_info_supported_fields ();
-                      var supported_fields = new HashSet<string> ();
-                      foreach (var field_spec in field_specs)
-                        {
-                          /* XXX: we ignore the maximum count for each type of
-                           * field since the common-sense count for each
-                           * corresponding field (eg, full-name max = 1) in
-                           * Folks is already reflected in our API and we have
-                           * no other way to express it; but this seems a very
-                           * minor problem */
-                          supported_fields.add (field_spec.name);
-                        }
-
-                      this._writeable_properties =
-                        this._always_writeable_properties;
-
-                      if ("fn" in supported_fields)
-                        this._writeable_properties += "full-name";
-                      if ("tel" in supported_fields)
-                        this._writeable_properties += "phone-numbers";
-
-                      return this._writeable_properties;
-                    }
-                }
-            }
+            return this._writeable_properties;
 
           return this._always_writeable_properties;
         }
@@ -494,6 +461,7 @@ public class Tpf.Persona : Folks.Persona,
               store: store,
               is_user: contact.handle == connection.self_handle);
 
+
       this._full_name = "";
 
       contact.notify["alias"].connect ((s, p) =>
@@ -592,6 +560,27 @@ public class Tpf.Persona : Folks.Persona,
                   this._change_group (group, false);
                 }
             });
+
+      if (this.is_user)
+        {
+          ((Tpf.PersonaStore) this.store).notify["supported-fields"].connect (
+            (s, p) =>
+              {
+                this._store_notify_supported_fields ();
+              });
+          this._store_notify_supported_fields ();
+        }
+    }
+
+  private void _store_notify_supported_fields ()
+    {
+      var tpf_store = this.store as Tpf.PersonaStore;
+      this._writeable_properties = this._always_writeable_properties;
+
+      if ("fn" in tpf_store.supported_fields)
+        this._writeable_properties += "full-name";
+      if ("tel" in tpf_store.supported_fields)
+        this._writeable_properties += "phone-numbers";
     }
 
   private void _contact_notify_contact_info ()