Allow caching of attributes
authorMike Gorse <mgorse@novell.com>
Thu, 26 May 2011 22:27:28 +0000 (17:27 -0500)
committerMike Gorse <mgorse@novell.com>
Thu, 26 May 2011 22:27:28 +0000 (17:27 -0500)
Attributes can now be cached, but not enabling by default, since there
is currently no event to notify AT-SPI that attributes have changed (see
BGO#649771), so this is dangerous but may improve performance if we can
reliably assume that attributes will not change.

atspi/atspi-accessible.c
atspi/atspi-accessible.h
atspi/atspi-constants.h
atspi/atspi-misc.c

index bcd37de..9461ece 100644 (file)
@@ -157,10 +157,12 @@ atspi_accessible_finalize (GObject *object)
 
     g_free (accessible->description);
     g_free (accessible->name);
+  if (accessible->attributes)
+    g_hash_table_unref (accessible->attributes);
 
 #ifdef DEBUG_REF_COUNTS
   accessible_count--;
-  printf("at-spi: finalize: %d objects\n", accessible_count);
+  g_print ("at-spi: finalize: %d objects\n", accessible_count);
 #endif
 
   G_OBJECT_CLASS (atspi_accessible_parent_class)
@@ -573,8 +575,25 @@ atspi_accessible_get_attributes (AtspiAccessible *obj, GError **error)
 
     g_return_val_if_fail (obj != NULL, NULL);
 
-  message = _atspi_dbus_call_partial (obj, atspi_interface_accessible, "GetAttributes", error, "");
-  return _atspi_dbus_return_hash_from_message (message);
+  if (!_atspi_accessible_test_cache (obj, ATSPI_CACHE_ATTRIBUTES))
+  {
+    message = _atspi_dbus_call_partial (obj, atspi_interface_accessible,
+                                        "GetAttributes", error, "");
+    obj->attributes = _atspi_dbus_return_hash_from_message (message);
+    _atspi_accessible_add_cache (obj, ATSPI_CACHE_ATTRIBUTES);
+  }
+
+  if (!obj->attributes)
+    return NULL;
+  return g_hash_table_ref (obj->attributes);
+}
+
+static void
+add_to_attribute_array (gpointer key, gpointer value, gpointer data)
+{
+  GArray **array = (GArray **)data;
+  gchar *str = g_strconcat (key, ":", value, NULL);
+  *array = g_array_append_val (*array, str);
 }
 
 /**
@@ -596,6 +615,17 @@ atspi_accessible_get_attributes_as_array (AtspiAccessible *obj, GError **error)
 
     g_return_val_if_fail (obj != NULL, NULL);
 
+  if (_atspi_accessible_get_cache_mask (obj) & ATSPI_CACHE_ATTRIBUTES)
+  {
+    GArray *array = g_array_new (TRUE, TRUE, sizeof (gchar *));
+    GHashTable *attributes = atspi_accessible_get_attributes (obj, error);
+    if (!attributes)
+      return NULL;
+    g_hash_table_foreach (attributes, add_to_attribute_array, &array);
+    g_hash_table_unref (attributes);
+    return array;
+  }
+
   message = _atspi_dbus_call_partial (obj, atspi_interface_accessible, "GetAttributes", error, "");
   return _atspi_dbus_return_attribute_array_from_message (message);
 }
@@ -1324,7 +1354,7 @@ atspi_accessible_clear_cache (AtspiAccessible *accessible)
   }
 }
 
-static AtspiCache
+AtspiCache
 _atspi_accessible_get_cache_mask (AtspiAccessible *accessible)
 {
   AtspiCache mask;
@@ -1343,7 +1373,7 @@ _atspi_accessible_get_cache_mask (AtspiAccessible *accessible)
   }
 
   if (mask == ATSPI_CACHE_UNDEFINED)
-    mask = ATSPI_CACHE_ALL;
+    mask = ATSPI_CACHE_DEFAULT;
 
   return mask;
 }
index d9e6e55..bbee0ce 100644 (file)
@@ -51,6 +51,7 @@ struct _AtspiAccessible
   char *name;
   char *description;
   AtspiStateSet *states;
+  GHashTable *attributes;
   guint cached_properties;
 };
 
@@ -133,5 +134,6 @@ void atspi_accessible_clear_cache (AtspiAccessible *accessible);
 
 /* private */
 void _atspi_accessible_add_cache (AtspiAccessible *accessible, AtspiCache flag);
+AtspiCache _atspi_accessible_get_cache_mask (AtspiAccessible *accessible);
 gboolean _atspi_accessible_test_cache (AtspiAccessible *accessible, AtspiCache flag);
 #endif /* _ATSPI_ACCESSIBLE_H_ */
index 4b857d7..3632854 100644 (file)
@@ -769,8 +769,13 @@ typedef enum
   ATSPI_CACHE_STATES      = 1 << 4,
   ATSPI_CACHE_ROLE        = 1 << 5,
   ATSPI_CACHE_INTERFACES  = 1 << 6,
+  ATSPI_CACHE_ATTRIBUTES = 1 << 7,
   ATSPI_CACHE_ALL         = 0x3fffffff,
-  ATSPI_CACHE_UNDEFINED   = 0x40000000
+  ATSPI_CACHE_DEFAULT = ATSPI_CACHE_PARENT | ATSPI_CACHE_CHILDREN |
+                        ATSPI_CACHE_NAME | ATSPI_CACHE_DESCRIPTION |
+                        ATSPI_CACHE_STATES | ATSPI_CACHE_ROLE |
+                        ATSPI_CACHE_INTERFACES,
+  ATSPI_CACHE_UNDEFINED   = 0x40000000,
 } AtspiCache;
 
 #ifdef __cplusplus
index eef82d1..4776c06 100644 (file)
@@ -1143,7 +1143,9 @@ _atspi_dbus_return_hash_from_message (DBusMessage *message)
 GHashTable *
 _atspi_dbus_hash_from_iter (DBusMessageIter *iter)
 {
-  GHashTable *hash = g_hash_table_new (g_str_hash, g_str_equal);
+  GHashTable *hash = g_hash_table_new_full (g_str_hash, g_str_equal,
+                                            (GDestroyNotify) g_free,
+                                            (GDestroyNotify) g_free);
   DBusMessageIter iter_array, iter_dict;
 
   dbus_message_iter_recurse (iter, &iter_array);
@@ -1189,15 +1191,12 @@ _atspi_dbus_attribute_array_from_iter (DBusMessageIter *iter)
   {
     const char *name, *value;
     gchar *str;
-    GArray *new_array;
     dbus_message_iter_recurse (&iter_array, &iter_dict);
     dbus_message_iter_get_basic (&iter_dict, &name);
     dbus_message_iter_next (&iter_dict);
     dbus_message_iter_get_basic (&iter_dict, &value);
     str = g_strdup_printf ("%s:%s", name, value);
-    new_array = g_array_append_val (array, str);
-    if (new_array)
-      array = new_array;
+    array = g_array_append_val (array, str);
     dbus_message_iter_next (&iter_array);;
   }
   return array;