changeset 329:aca5744f017a

Added fast path for Widget.findChild(name=name). Roughly 10x faster.
author phoku@33b003aa-7bff-0310-803a-e67f0ece8222
date Mon, 24 Aug 2009 10:01:06 +0000
parents d8bcff5f7222
children 33dd55160a9d
files engine/extensions/pychan/exceptions.py engine/extensions/pychan/widgets/widget.py
diffstat 2 files changed, 28 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/engine/extensions/pychan/exceptions.py	Mon Aug 24 09:20:28 2009 +0000
+++ b/engine/extensions/pychan/exceptions.py	Mon Aug 24 10:01:06 2009 +0000
@@ -1,4 +1,4 @@
-# coding: utf-8
+# -*- coding: utf-8 -*-
 
 class PyChanException(Exception):
 	"""
@@ -33,4 +33,8 @@
 	"""
 	Exception raised if private attributes/functions are used.
 	"""
-	pass
+
+class StopTreeWalking(StopIteration):
+	"""
+	Internal exception used to abort iteration over the widget tree.
+	"""
--- a/engine/extensions/pychan/widgets/widget.py	Mon Aug 24 09:20:28 2009 +0000
+++ b/engine/extensions/pychan/widgets/widget.py	Mon Aug 24 10:01:06 2009 +0000
@@ -288,11 +288,33 @@
 		Usage::
 		  closeButton = root_widget.findChild(name='close')
 		"""
+		if kwargs.keys() == ["name"]:
+			return self.findChildByName(kwargs["name"])
+
 		children = self.findChildren(**kwargs)
 		if children:
 			return children[0]
 		return None
 
+	def findChildByName(self,name):
+		"""
+		Find first contained child widget by its name.
+
+		Note that this is the fast version of findChild(name="...")
+		and that you don't have to call this explicitly, it is used
+		if possible.
+		"""
+		result = []
+		def _childCollector(widget):
+			if widget._name == name:
+				result.append(widget)
+				raise StopTreeWalking
+		try:
+			self.deepApply(_childCollector)
+		except StopTreeWalking:
+			return result[0]
+		return None
+
 	def addChild(self,widget):
 		"""
 		This function adds a widget as child widget and is only implemented