From ad74e38512597f26c6137d12b99e591ba2ba0f0e Mon Sep 17 00:00:00 2001 From: Thomas Leonard Date: Thu, 25 Nov 2004 13:43:23 +0000 Subject: [PATCH] Added tasks.InputBlocker, which triggers when an input source becomes readable (Thomas Leonard). git-svn-id: https://rox.svn.sourceforge.net/svnroot/rox/trunk/ROX-Lib2@3724 66de3db3-b00d-0410-b41b-f4738ad19bea --- Help/Changes | 5 +++++ python/rox/tasks.py | 27 ++++++++++++++++++++++++- tests/python/testtasks.py | 51 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 82 insertions(+), 1 deletion(-) create mode 100755 tests/python/testtasks.py diff --git a/Help/Changes b/Help/Changes index be9755b..5047804 100644 --- a/Help/Changes +++ b/Help/Changes @@ -3,6 +3,11 @@ by Thomas Leonard http://rox.sourceforge.net +25-Nov-2004 +~~~~~~~~~~~ +Added tasks.InputBlocker, which triggers when an input source becomes +readable (Thomas Leonard). + 21-Nov-2004 ~~~~~~~~~~~ Bugfix: Use only text nodes when getting the tool tip from the Options.xml diff --git a/python/rox/tasks.py b/python/rox/tasks.py index 2081735..d59c8d2 100644 --- a/python/rox/tasks.py +++ b/python/rox/tasks.py @@ -95,6 +95,11 @@ class Blocker: Blocker. If you override this method, be sure to still call this method with Blocker.add_task(self)!""" self._rox_lib_tasks[task] = True + + def remove_task(self, task): + """Called by the schedular when a Task that was waiting for + this blocker is resumed.""" + del self._rox_lib_tasks[task] class IdleBlocker(Blocker): """An IdleBlocker blocks until a task starts waiting on it, then @@ -119,6 +124,26 @@ class TimeoutBlocker(Blocker): rox.toplevel_unref() self.trigger() +class InputBlocker(Blocker): + """Triggers when os.read(stream) would not block.""" + _tag = None + _stream = None + def __init__(self, stream): + Blocker.__init__(self) + self._stream = stream + + def add_task(self, task): + Blocker.add_task(self, task) + if self._tag is None: + self._tag = g.input_add(self._stream, g.gdk.INPUT_READ, + lambda src, cond: self.trigger()) + + def remove_task(self, task): + Blocker.remove_task(self, task) + if not self._rox_lib_tasks: + g.input_remove(self._tag) + self._tag = None + _idle_blocker = IdleBlocker() class Task: @@ -159,7 +184,7 @@ class Task: def _resume(self): # Remove from our blockers' queues for blocker in self._rox_blockers: - del blocker._rox_lib_tasks[self] + blocker.remove_task(self) # Resume the task try: new_blockers = self.next() diff --git a/tests/python/testtasks.py b/tests/python/testtasks.py new file mode 100755 index 0000000..0e044f0 --- /dev/null +++ b/tests/python/testtasks.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python2.2 +from __future__ import generators +import unittest +import sys +import os, time +from os.path import dirname, abspath, join + +rox_lib = dirname(dirname(dirname(abspath(sys.argv[0])))) +sys.path.insert(0, join(rox_lib, 'python')) + +from rox import tasks, g + +class TestTasks(unittest.TestCase): + def testIdleBlocker(self): + def run(): + yield None + g.mainquit() + tasks.Task(run()) + g.mainloop() + + def testTimeoutBlocker(self): + def run(): + start = time.time() + yield tasks.TimeoutBlocker(0.5) + end = time.time() + assert end > start + 0.5 + g.mainquit() + tasks.Task(run()) + g.mainloop() + + def testInputBlocker(self): + readable, writeable = os.pipe() + def run(): + ib = tasks.InputBlocker(readable) + tb = tasks.TimeoutBlocker(0.2) + yield ib, tb + assert not ib.happened + assert tb.happened + os.write(writeable, "!") + + tb = tasks.TimeoutBlocker(0.2) + yield ib, tb + assert ib.happened + assert not tb.happened + + g.mainquit() + tasks.Task(run()) + g.mainloop() + +sys.argv.append('-v') +unittest.main() -- 2.11.4.GIT