Switching timeouts to seconds for whenever platforms support it
[theonering] / src / util / go_utils.py
1 #!/usr/bin/env python
2
3 from __future__ import with_statement
4
5 import time
6 import functools
7
8 import gobject
9
10
11 def async(func):
12         """
13         Make a function mainloop friendly. the function will be called at the
14         next mainloop idle state.
15
16         >>> import misc
17         >>> misc.validate_decorator(async)
18         """
19
20         @functools.wraps(func)
21         def new_function(*args, **kwargs):
22
23                 def async_function():
24                         func(*args, **kwargs)
25                         return False
26
27                 gobject.idle_add(async_function)
28
29         return new_function
30
31
32 def throttled(minDelay, queue):
33         """
34         Throttle the calls to a function by queueing all the calls that happen
35         before the minimum delay
36
37         >>> import misc
38         >>> import Queue
39         >>> misc.validate_decorator(throttled(0, Queue.Queue()))
40         """
41
42         def actual_decorator(func):
43
44                 lastCallTime = [None]
45
46                 def process_queue():
47                         if 0 < len(queue):
48                                 func, args, kwargs = queue.pop(0)
49                                 lastCallTime[0] = time.time() * 1000
50                                 func(*args, **kwargs)
51                         return False
52
53                 @functools.wraps(func)
54                 def new_function(*args, **kwargs):
55                         now = time.time() * 1000
56                         if (
57                                 lastCallTime[0] is None or
58                                 (now - lastCallTime >= minDelay)
59                         ):
60                                 lastCallTime[0] = now
61                                 func(*args, **kwargs)
62                         else:
63                                 queue.append((func, args, kwargs))
64                                 lastCallDelta = now - lastCallTime[0]
65                                 processQueueTimeout = int(minDelay * len(queue) - lastCallDelta)
66                                 gobject.timeout_add(processQueueTimeout, process_queue)
67
68                 return new_function
69
70         return actual_decorator
71
72
73 def _old_timeout_add_seconds(timeout, callback):
74         return gobject.timeout_add(timeout * 1000, callback)
75
76
77 def _timeout_add_seconds(timeout, callback):
78         return gobject.timeout_add_seconds(timeout, callback)
79
80
81 try:
82         gobject.timeout_add_seconds
83         timeout_add_seconds = _timeout_add_seconds
84 except AttributeError:
85         timeout_add_seconds = _old_timeout_add_seconds