Updating from skeleton
[gonvert] / src / util / qore_utils.py
1 import logging
2
3 import qt_compat
4 QtCore = qt_compat.QtCore
5
6 import misc
7
8
9 _moduleLogger = logging.getLogger(__name__)
10
11
12 class QThread44(QtCore.QThread):
13         """
14         This is to imitate QThread in Qt 4.4+ for when running on older version
15         See http://labs.trolltech.com/blogs/2010/06/17/youre-doing-it-wrong
16         (On Lucid I have Qt 4.7 and this is still an issue)
17         """
18
19         def __init__(self, parent = None):
20                 QtCore.QThread.__init__(self, parent)
21
22         def run(self):
23                 self.exec_()
24
25
26 class _WorkerThread(QtCore.QObject):
27
28         _taskComplete  = qt_compat.Signal(object)
29
30         def __init__(self, futureThread):
31                 QtCore.QObject.__init__(self)
32                 self._futureThread = futureThread
33                 self._futureThread._addTask.connect(self._on_task_added)
34                 self._taskComplete.connect(self._futureThread._on_task_complete)
35
36         @qt_compat.Slot(object)
37         def _on_task_added(self, task):
38                 self.__on_task_added(task)
39
40         @misc.log_exception(_moduleLogger)
41         def __on_task_added(self, task):
42                 if not self._futureThread._isRunning:
43                         _moduleLogger.error("Dropping task")
44
45                 func, args, kwds, on_success, on_error = task
46
47                 try:
48                         result = func(*args, **kwds)
49                         isError = False
50                 except Exception, e:
51                         _moduleLogger.error("Error, passing it back to the main thread")
52                         result = e
53                         isError = True
54
55                 taskResult = on_success, on_error, isError, result
56                 self._taskComplete.emit(taskResult)
57
58
59 class FutureThread(QtCore.QObject):
60
61         _addTask = qt_compat.Signal(object)
62
63         def __init__(self):
64                 QtCore.QObject.__init__(self)
65                 self._thread = QThread44()
66                 self._isRunning = False
67                 self._worker = _WorkerThread(self)
68                 self._worker.moveToThread(self._thread)
69
70         def start(self):
71                 self._thread.start()
72                 self._isRunning = True
73
74         def stop(self):
75                 self._isRunning = False
76                 self._thread.quit()
77
78         def add_task(self, func, args, kwds, on_success, on_error):
79                 assert self._isRunning, "Task queue not started"
80                 task = func, args, kwds, on_success, on_error
81                 self._addTask.emit(task)
82
83         @qt_compat.Slot(object)
84         def _on_task_complete(self, taskResult):
85                 self.__on_task_complete(taskResult)
86
87         @misc.log_exception(_moduleLogger)
88         def __on_task_complete(self, taskResult):
89                 on_success, on_error, isError, result = taskResult
90                 if not self._isRunning:
91                         if isError:
92                                 _moduleLogger.error("Masking: %s" % (result, ))
93                         isError = True
94                         result = StopIteration("Cancelling all callbacks")
95                 callback = on_success if not isError else on_error
96                 try:
97                         callback(result)
98                 except Exception:
99                         _moduleLogger.exception("Callback errored")