[at-spi2-core] Allow caching of attributes



commit ee59329278ddd73b7371e278b6e4f1f306ba2da6
Author: Mike Gorse <mgorse novell com>
Date:   Thu May 26 17:27:28 2011 -0500

    Allow caching of attributes
    
    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 |   40 +++++++++++++++++++++++++++++++++++-----
 atspi/atspi-accessible.h |    2 ++
 atspi/atspi-constants.h  |    7 ++++++-
 atspi/atspi-misc.c       |    9 ++++-----
 4 files changed, 47 insertions(+), 11 deletions(-)
---
diff --git a/atspi/atspi-accessible.c b/atspi/atspi-accessible.c
index bcd37de..9461ece 100644
--- a/atspi/atspi-accessible.c
+++ b/atspi/atspi-accessible.c
@@ -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;
 }
diff --git a/atspi/atspi-accessible.h b/atspi/atspi-accessible.h
index d9e6e55..bbee0ce 100644
--- a/atspi/atspi-accessible.h
+++ b/atspi/atspi-accessible.h
@@ -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_ */
diff --git a/atspi/atspi-constants.h b/atspi/atspi-constants.h
index 4b857d7..3632854 100644
--- a/atspi/atspi-constants.h
+++ b/atspi/atspi-constants.h
@@ -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
diff --git a/atspi/atspi-misc.c b/atspi/atspi-misc.c
index eef82d1..4776c06 100644
--- a/atspi/atspi-misc.c
+++ b/atspi/atspi-misc.c
@@ -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;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]