3 from __future__ import with_statement
14 _moduleLogger = logging.getLogger("go_utils")
19 Decorator that makes a generator-function into a function that will continue execution on next call
23 @functools.wraps(func)
24 def decorated_func(*args, **kwds):
26 a.append(func(*args, **kwds))
39 Make a function mainloop friendly. the function will be called at the
40 next mainloop idle state.
43 >>> misc.validate_decorator(async)
46 @functools.wraps(func)
47 def new_function(*args, **kwargs):
53 gobject.idle_add(async_function)
60 def __init__(self, func, once = True):
66 assert self.__idleId is None
68 self.__idleId = gobject.idle_add(self._on_once)
70 self.__idleId = gobject.idle_add(self.__func)
73 return self.__idleId is not None
76 if self.__idleId is not None:
77 gobject.source_remove(self.__idleId)
83 @misc.log_exception(_moduleLogger)
92 class Timeout(object):
94 def __init__(self, func):
96 self.__timeoutId = None
98 def start(self, **kwds):
99 assert self.__timeoutId is None
101 assert len(kwds) == 1
102 timeoutInSeconds = kwds["seconds"]
103 assert 0 <= timeoutInSeconds
104 if timeoutInSeconds == 0:
105 self.__timeoutId = gobject.idle_add(self._on_once)
107 self.__timeoutId = timeout_add_seconds(timeoutInSeconds, self._on_once)
109 def is_running(self):
110 return self.__timeoutId is not None
113 if self.__timeoutId is not None:
114 gobject.source_remove(self.__timeoutId)
115 self.__timeoutId = None
117 def __call__(self, **kwds):
118 return self.start(**kwds)
120 @misc.log_exception(_moduleLogger)
129 def throttled(minDelay, queue):
131 Throttle the calls to a function by queueing all the calls that happen
132 before the minimum delay
136 >>> misc.validate_decorator(throttled(0, Queue.Queue()))
139 def actual_decorator(func):
141 lastCallTime = [None]
145 func, args, kwargs = queue.pop(0)
146 lastCallTime[0] = time.time() * 1000
147 func(*args, **kwargs)
150 @functools.wraps(func)
151 def new_function(*args, **kwargs):
152 now = time.time() * 1000
154 lastCallTime[0] is None or
155 (now - lastCallTime >= minDelay)
157 lastCallTime[0] = now
158 func(*args, **kwargs)
160 queue.append((func, args, kwargs))
161 lastCallDelta = now - lastCallTime[0]
162 processQueueTimeout = int(minDelay * len(queue) - lastCallDelta)
163 gobject.timeout_add(processQueueTimeout, process_queue)
167 return actual_decorator
170 def _old_timeout_add_seconds(timeout, callback):
171 return gobject.timeout_add(timeout * 1000, callback)
174 def _timeout_add_seconds(timeout, callback):
175 return gobject.timeout_add_seconds(timeout, callback)
179 gobject.timeout_add_seconds
180 timeout_add_seconds = _timeout_add_seconds
181 except AttributeError:
182 timeout_add_seconds = _old_timeout_add_seconds