22084edb4da857712a016eaee483c0f5a5836552
[gc-dialer] / hand_tests / producer_consumer.py
1 #!/usr/bin/env python
2
3 from __future__ import with_statement
4 from __future__ import division
5
6 import functools
7 import time
8
9
10 FORCE_PYQT = False
11 DECORATE = True
12
13
14 try:
15         if FORCE_PYQT:
16                 raise ImportError()
17         import PySide.QtCore as _QtCore
18         QtCore = _QtCore
19         USES_PYSIDE = True
20 except ImportError:
21         import sip
22         sip.setapi('QString', 2)
23         sip.setapi('QVariant', 2)
24         import PyQt4.QtCore as _QtCore
25         QtCore = _QtCore
26         USES_PYSIDE = False
27
28
29 if USES_PYSIDE:
30         Signal = QtCore.Signal
31         Slot = QtCore.Slot
32         Property = QtCore.Property
33 else:
34         Signal = QtCore.pyqtSignal
35         Slot = QtCore.pyqtSlot
36         Property = QtCore.pyqtProperty
37
38
39 def log_exception():
40
41         def log_exception_decorator(func):
42
43                 @functools.wraps(func)
44                 def wrapper(*args, **kwds):
45                         try:
46                                 return func(*args, **kwds)
47                         except Exception:
48                                 print "Exception", func.__name__
49                                 raise
50
51                 if DECORATE:
52                         return wrapper
53                 else:
54                         return func
55
56         return log_exception_decorator
57
58
59 class QThread44(QtCore.QThread):
60         """
61         This is to imitate QThread in Qt 4.4+ for when running on older version
62         See http://labs.trolltech.com/blogs/2010/06/17/youre-doing-it-wrong
63         (On Lucid I have Qt 4.7 and this is still an issue)
64         """
65
66         def __init__(self, parent = None):
67                 QtCore.QThread.__init__(self, parent)
68
69         def run(self):
70                 self.exec_()
71
72
73 class Producer(QtCore.QObject):
74
75         data = Signal(int)
76         done = Signal()
77
78         def __init__(self):
79                 QtCore.QObject.__init__(self)
80
81         @Slot()
82         @log_exception()
83         def process(self):
84                 print "Starting producer"
85                 for i in xrange(10):
86                         self.data.emit(i)
87                         time.sleep(0.1)
88                 self.done.emit()
89
90
91 class Consumer(QtCore.QObject):
92
93         def __init__(self):
94                 QtCore.QObject.__init__(self)
95
96         @Slot()
97         @log_exception()
98         def process(self):
99                 print "Starting consumer"
100
101         @Slot()
102         @log_exception()
103         def print_done(self):
104                 print "Done"
105
106         @Slot(int)
107         @log_exception()
108         def print_data(self, i):
109                 print i
110
111
112 def run_producer_consumer():
113         app = QtCore.QCoreApplication([])
114
115         producerThread = QThread44()
116         producer = Producer()
117         producer.moveToThread(producerThread)
118         producerThread.started.connect(producer.process)
119
120         consumerThread = QThread44()
121         consumer = Consumer()
122         consumer.moveToThread(consumerThread)
123         consumerThread.started.connect(consumer.process)
124
125         producer.data.connect(consumer.print_data)
126         producer.done.connect(consumer.print_done)
127
128         @Slot()
129         @log_exception()
130         def producer_done():
131                 print "Shutting down"
132                 producerThread.quit()
133                 consumerThread.quit()
134                 print "Done"
135         producer.done.connect(producer_done)
136
137         count = [0]
138
139         @Slot()
140         @log_exception()
141         def thread_done():
142                 print "Thread done"
143                 count[0] += 1
144                 if count[0] == 2:
145                         print "Quitting"
146                         app.exit(0)
147                 print "Done"
148         producerThread.finished.connect(thread_done)
149         consumerThread.finished.connect(thread_done)
150
151         producerThread.start()
152         consumerThread.start()
153         print "Status %s" % app.exec_()
154
155
156 if __name__ == "__main__":
157         run_producer_consumer()