[pyatspi2] Added a weak-ref-based "soft cache"
- From: Mike Gorse <mgorse src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pyatspi2] Added a weak-ref-based "soft cache"
- Date: Sat, 2 Oct 2010 10:06:11 +0000 (UTC)
commit ef0b55bef623d0306bb15959d7351a57da0a2db6
Author: Mike Gorse <mgorse novell com>
Date: Sat Oct 2 06:00:40 2010 -0400
Added a weak-ref-based "soft cache"
Added a "soft" cache to store the roles/state/parents returned from explicit
queries. In theory this should not be needed, but sometimes we don't receive
an AccessibleAdded when an object is created.
pyatspi/accessible.py | 30 ++++++++++++++++++++++++++----
pyatspi/cache.py | 33 ++++++++++++++++++++++++++++++---
2 files changed, 56 insertions(+), 7 deletions(-)
---
diff --git a/pyatspi/accessible.py b/pyatspi/accessible.py
index 0c7e633..d145877 100644
--- a/pyatspi/accessible.py
+++ b/pyatspi/accessible.py
@@ -95,6 +95,12 @@ class BoundingBox(list):
#------------------------------------------------------------------------------
+class _PropertyCache(dict):
+ def wipe(self):
+ self.__dict__ = {}
+
+#------------------------------------------------------------------------------
+
class AccessibleMeta(type):
def __new__(meta, *args, **kwargs):
cls = type.__new__(meta, *args, **kwargs)
@@ -207,6 +213,11 @@ class Accessible(BaseProxy):
self._cache = cache
self._relation_set = None
+ try:
+ self._soft_cache_data = self._cache.soft[(self._app_name, self._acc_path)]
+ except KeyError:
+ self._soft_cache_data = _PropertyCache()
+ self._cache.soft[(self._app_name, self._acc_path)] = self._soft_cache_data
# Python object protocol --------------------------------------------------------
@@ -412,7 +423,7 @@ class Accessible(BaseProxy):
return Role(self._cached_data.role)
else:
func = self.get_dbus_method("GetRole", dbus_interface=ATSPI_ACCESSIBLE)
- return Role(func())
+ return Role(self.getSoftCacheItem ("role", func))
def getRoleName(self):
"""
@@ -436,7 +447,7 @@ class Accessible(BaseProxy):
else:
func = self.get_dbus_method("GetState", dbus_interface=ATSPI_ACCESSIBLE)
try:
- return _marshal_state_set(func())
+ return _marshal_state_set(self.getSoftCacheItem("state", func))
except LookupError:
return _marshal_state_set ([1 << STATE_DEFUNCT, 0])
@@ -493,7 +504,7 @@ class Accessible(BaseProxy):
if self.cached:
name, path = self._cached_data.parent
else:
- name, path = self._pgetter (ATSPI_ACCESSIBLE, "Parent")
+ name, path = self.getSoftCacheProperty (ATSPI_ACCESSIBLE, "Parent")
if (path == ATSPI_ROOT_PATH):
itf = ATSPI_APPLICATION
@@ -511,13 +522,14 @@ class Accessible(BaseProxy):
return self._cached_data.interfaces
else:
func = self.get_dbus_method("GetInterfaces", dbus_interface=ATSPI_ACCESSIBLE)
- return func()
+ return self.getSoftCacheItem("interfaces", func)
_interfacesDoc = \
"""
D-Bus interfaces supported by this accessible object.
"""
interfaces = property(fget=_get_interfaces, doc=_interfacesDoc)
+ # TODO: Possibly merge this with getSoftCacheItem
def _getConstantProperty(self, interface, name):
if self.cached:
try:
@@ -531,4 +543,14 @@ class Accessible(BaseProxy):
return self.extraData[name]
return dbus.String(self._pgetter(interface, name))
+ def getSoftCacheItem(self, name, func):
+ if not(name in self._soft_cache_data):
+ self._soft_cache_data[name] = func()
+ return self._soft_cache_data[name]
+
+ def getSoftCacheProperty(self, interface, name):
+ if not((interface, name) in self._soft_cache_data):
+ self._soft_cache_data[(interface, name)] = self._pgetter(interface, name)
+ return self._soft_cache_data[(interface, name)]
+
#END----------------------------------------------------------------------------
diff --git a/pyatspi/cache.py b/pyatspi/cache.py
index b0ce9d1..bf5483d 100644
--- a/pyatspi/cache.py
+++ b/pyatspi/cache.py
@@ -16,6 +16,7 @@ import os
import dbus
import registry
import string
+import weakref
from interfaces import *
from role import ROLE_DESKTOP_FRAME
@@ -277,6 +278,17 @@ class ApplicationCacheManager (object):
elif minor == "accessible-parent":
item.parent = any_data
+ if (sender, path) in self._cache.soft:
+ item = self._cache.soft[(sender, path)]
+ if minor == "accessible-name":
+ item["name"] = any_data
+ elif minor == "accessible-role":
+ item["role"] = any_data
+ elif minor == "accessible-description":
+ item["description"] = any_data
+ elif minor == "accessible-parent":
+ item[(ATSPI_ACCESSIBLE, "parent")] = any_data
+
def _children_changed_handler (self,
minor, detail1, detail2, any_data, app,
interface=None, sender=None, member=None, path=None):
@@ -289,25 +301,38 @@ class ApplicationCacheManager (object):
item.children.insert (detail1, any_data)
elif minor.startswith("remove"):
item.children.remove (any_data)
+
if any_data in self._cache:
child = self._cache[any_data]
if child.parent == (sender, path):
child.parent = (sender, ATSPI_NULL_PATH)
+ if any_data in self._cache.soft:
+ child = self._cache.soft[any_data]
+ if (ATSPI_ACCESSIBLE, "Parent") in child and child[(ATSPI_ACCESSIBLE, "Parent")] == (sender, path):
+ child[(ATSPI_ACCESSIBLE, "Parent")] = (sender, ATSPI_NULL_PATH)
def _state_changed_handler (self,
minor, detail1, detail2, any_data, app,
interface=None, sender=None, member=None, path=None):
if interface==_ATSPI_EVENT_OBJECT_INTERFACE:
+ val = eval("int(state.STATE_" + string.upper(minor) + ")")
+ high = int(val / 32)
+ low = val % 32
if (sender, path) in self._cache:
item = self._cache[(sender, path)]
- val = eval("int(state.STATE_" + string.upper(minor) + ")")
- high = int(val / 32)
- low = val % 32
if (detail1 == 1):
item.state[high] |= (1 << low)
else:
item.state[high] &= ~(1 << low)
+ if (sender, path) in self._cache.soft:
+ item = self._cache.soft[(sender, path)]
+ if "state" in item:
+ if (detail1 == 1):
+ item["state"][high] |= (1 << low)
+ else:
+ item["state"][high] &= ~(1 << low)
+
def remove_all (self):
for bus_name, object_path in self._cache.keys():
if bus_name == self._bus_name:
@@ -325,6 +350,8 @@ class AccessibleCache (dict):
else:
self._manager = DesktopCacheManager (self)
+ self.soft = weakref.WeakValueDictionary()
+
def __call__ (self, bus_name, object_path):
return self[(bus_name, object_path)]
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]