5
|
1 |
import threading # Only used in SetupEvent
|
|
2 |
|
|
3 |
class _Callback(object):
|
|
4 |
def __init__(self, callback, errorback, threaded = False):
|
|
5 |
self.callback = callback
|
|
6 |
self.errorback = errorback
|
|
7 |
self.next = None
|
|
8 |
self.threaded = threaded
|
|
9 |
def Chain(self, next):
|
|
10 |
# Can only be called once
|
|
11 |
assert(self.next is None)
|
|
12 |
self.next = next
|
|
13 |
return next
|
|
14 |
def Next(self):
|
|
15 |
return self.next
|
|
16 |
|
|
17 |
##
|
|
18 |
# A task, representing a series of linked pairs of callback and error
|
|
19 |
# handler Concept is similar to twisted, but you need to put all your
|
|
20 |
# callback on the task before giving it to the Scheduler. For this
|
|
21 |
# reason, you shouldnt call the callback/errorback method yourself (or
|
|
22 |
# at least, don't put it back in the scheduler after that).
|
|
23 |
|
|
24 |
class Task(object):
|
|
25 |
|
|
26 |
@staticmethod
|
|
27 |
def DefaultCallback(result):
|
|
28 |
return result
|
|
29 |
|
|
30 |
@staticmethod
|
|
31 |
def DefaultErrorback(error):
|
|
32 |
return error
|
|
33 |
|
|
34 |
def __init__(self, func = None, *args, **kwargs):
|
|
35 |
super(Task, self).__init__()
|
|
36 |
self.head = None
|
|
37 |
self.tail = None
|
|
38 |
if func:
|
|
39 |
def callback(result):
|
|
40 |
return func(*args, **kwargs)
|
|
41 |
self.AddCallback(callback)
|
|
42 |
|
|
43 |
def _AddCallback(self, callback):
|
|
44 |
if self.head is None:
|
|
45 |
self.head = self.tail = callback
|
|
46 |
else:
|
|
47 |
self.tail = self.tail.Chain(callback)
|
|
48 |
|
|
49 |
def _GetNext(self):
|
|
50 |
head = self.head
|
|
51 |
if head:
|
|
52 |
self.head = head.Next()
|
|
53 |
return head
|
|
54 |
|
|
55 |
def AddCallback(self, callback, errorback = None, threaded = False):
|
|
56 |
if errorback == None:
|
|
57 |
errorback = self.DefaultErrorback
|
|
58 |
cb = _Callback(callback, errorback, threaded)
|
|
59 |
self._AddCallback(cb)
|
|
60 |
# permit chained calls
|
|
61 |
return self
|
|
62 |
|
|
63 |
def AddThreadedCallback(self, callback, errorback = None):
|
|
64 |
return self.AddCallback(callback, errorback, True)
|
|
65 |
|
|
66 |
def ChainTask(self, task):
|
|
67 |
self.tail.Chain(task.head)
|
|
68 |
self.tail = task.tail
|
|
69 |
|
|
70 |
def GrabResult(self, data = None):
|
|
71 |
if data is None:
|
|
72 |
data = {}
|
|
73 |
def SetResult(result):
|
|
74 |
data["result"] = result
|
|
75 |
return result
|
|
76 |
def SetError(error):
|
|
77 |
data["error"] = error
|
|
78 |
self.AddCallback(SetResult, SetError)
|
|
79 |
return data
|
|
80 |
|
|
81 |
def SetupEvent(self, event = None, data = None):
|
|
82 |
if not event:
|
|
83 |
event = threading.Event()
|
|
84 |
def SetEvent(dummy):
|
|
85 |
event.set()
|
|
86 |
self.AddCallback(SetEvent, SetEvent)
|
|
87 |
return event
|
|
88 |
|
|
89 |
##
|
|
90 |
# Helper class
|
|
91 |
class ThreadedTask(Task):
|
|
92 |
def __init__(self, func, *args, **kwargs):
|
|
93 |
super(ThreadedTask, self).__init__(func, *args, **kwargs)
|
|
94 |
self.head.threaded = True
|
|
95 |
|