Package _Framework :: Module Task
[hide private]
[frames] | no frames]

Source Code for Module _Framework.Task

  1  #Embedded file name: /Users/versonator/Hudson/live/Projects/AppLive/Resources/MIDI Remote Scripts/_Framework/Task.py 
  2  """ 
  3  Task management. 
  4  """ 
  5  import functools 
  6  import Util 
7 8 -class TaskError(Exception):
9 pass
10 11 12 KILLED = 0 13 RUNNING = 1 14 PAUSED = 2
15 16 -class Task(object):
17
18 - def __init__(self, *a, **k):
19 super(Task, self).__init__(*a, **k) 20 self._state = RUNNING 21 self._next = [] 22 self._task_manager = None
23
24 - def clear(self):
25 pass
26
27 - def do_update(self, timer):
28 pass
29
30 - def do_restart(self):
31 pass
32
33 - def add_next(self, task):
34 self._next.append(task) 35 return task
36
37 - def update(self, timer):
38 if self._state == RUNNING: 39 self.do_update(timer) 40 return self._state
41
42 - def pause(self):
43 if self._state != KILLED: 44 self._state = PAUSED 45 return self
46
47 - def resume(self):
48 if self._state != KILLED: 49 self._state = RUNNING 50 return self
51
52 - def toggle_pause(self):
53 if self._state != KILLED: 54 self._state = RUNNING if self._state == PAUSED else PAUSED 55 return self
56
57 - def restart(self):
58 self.do_restart() 59 self._state = RUNNING 60 if self._task_manager and self._task_manager.find(self) == None: 61 manager = self._task_manager 62 self._task_manager = None 63 manager.add(self) 64 return self
65
66 - def kill(self):
67 self._state = KILLED 68 if self._task_manager: 69 for task in self._next: 70 self._task_manager.add(task) 71 72 return self
73 74 @property
75 - def is_running(self):
76 return self._state == RUNNING
77 78 @property
79 - def is_paused(self):
80 return self._state == PAUSED
81 82 @property
83 - def is_killed(self):
84 return self._state == KILLED
85 86 @property
87 - def state(self):
88 return self._state
89 90 @property
91 - def parent_task(self):
92 return self._task_manager
93
94 - def _set_parent(self, manager):
95 if self._task_manager and manager: 96 raise TaskError('Already attached to: ' + str(self._task_manager)) 97 self._task_manager = manager
98
99 - def _task_equivalent(self, other):
100 return self == other
101
102 103 -class WrapperTask(Task):
104
105 - def __init__(self, wrapped_task = None, *a, **k):
106 super(WrapperTask, self).__init__(*a, **k) 107 self.wrapped_task = wrapped_task
108
109 - def update(self, delta):
110 super(WrapperTask, self).update(delta) 111 self.wrapped_task.update(delta)
112
113 - def _set_parent(self, manager):
114 super(WrapperTask, self)._set_parent(manager) 115 self.wrapped_task._set_parent(manager)
116
117 - def _task_equivalent(self, other):
118 return self.wrapped_task._task_equivalent(other)
119
120 121 -class FuncTask(Task):
122
123 - def __init__(self, func = None, equivalent = None, *a, **k):
124 raise func != None or AssertionError 125 super(FuncTask, self).__init__(*a, **k) 126 self._func = func 127 self._equivalent = equivalent
128
129 - def _set_func(self, func):
130 self._func = func
131
132 - def _get_func(self):
133 return self._orig
134
135 - def do_update(self, timer):
136 super(FuncTask, self).do_update(timer) 137 action = self._func(timer) 138 if not action or action == KILLED: 139 self.kill() 140 elif action == PAUSED: 141 self.pause()
142
143 - def _task_equivalent(self, other):
144 return self == other or self._func == other or self._equivalent == other
145 146 func = property(_get_func, _set_func)
147
148 149 -class GeneratorTask(Task):
150
151 - class Param(object):
152 delta = 0
153
154 - def __init__(self, generator = None, equivalent = None, *a, **k):
155 raise generator != None and callable(generator) or AssertionError 156 super(GeneratorTask, self).__init__(*a, **k) 157 self._param = GeneratorTask.Param() 158 self._set_generator(generator) 159 self._equivalent = equivalent
160
161 - def _set_generator(self, generator):
162 self._orig = generator 163 self._iter = generator(self._param)
164
165 - def _get_generator(self):
166 return self._orig
167
168 - def do_update(self, delta):
169 super(GeneratorTask, self).do_update(delta) 170 self._param.delta = delta 171 try: 172 action = self._iter.next() 173 except StopIteration: 174 action = KILLED 175 176 if not action or action == KILLED: 177 self.kill() 178 elif action == PAUSED: 179 self.pause()
180
181 - def _task_equivalent(self, other):
182 return self == other or self._orig == other or self._equivalent == other
183 184 generator = property(_get_generator, _set_generator)
185
186 187 -class TaskGroup(Task):
188 auto_kill = True 189 auto_remove = True 190 loop = False 191
192 - def __init__(self, tasks = [], auto_kill = None, auto_remove = None, loop = None, *a, **k):
193 super(TaskGroup, self).__init__(*a, **k) 194 if auto_kill is not None: 195 self.auto_kill = auto_kill 196 if auto_remove is not None: 197 self.auto_remove = auto_remove 198 if loop is not None: 199 self.loop = loop 200 self._tasks = [] 201 for task in tasks: 202 self.add(task)
203
204 - def clear(self):
205 for t in self._tasks: 206 t._set_parent(None) 207 208 self._tasks = [] 209 super(TaskGroup, self).clear()
210
211 - def do_update(self, timer):
212 super(TaskGroup, self).do_update(timer) 213 for task in self._tasks: 214 if not task.is_killed: 215 task.update(timer) 216 217 if self.auto_remove: 218 self._tasks = Util.remove_if(lambda t: t.is_killed, self._tasks) 219 all_killed = len(filter(lambda t: t.is_killed, self._tasks)) == self.count 220 if self.auto_kill and all_killed: 221 self.kill() 222 elif self.loop and all_killed: 223 self.restart()
224
225 - def add(self, task):
226 task = totask(task) 227 task._set_parent(self) 228 self._tasks.append(task) 229 if self.is_killed: 230 super(TaskGroup, self).restart() 231 return task
232
233 - def remove(self, task):
234 self._tasks.remove(task) 235 task._set_parent(None)
236
237 - def find(self, task):
238 return Util.find_if(lambda t: t._task_equivalent(task), self._tasks)
239
240 - def restart(self):
241 super(TaskGroup, self).restart() 242 for x in self._tasks: 243 x.restart()
244 245 @property
246 - def count(self):
247 return len(self._tasks)
248
249 250 -class WaitTask(Task):
251 duration = 1.0 252
253 - def __init__(self, duration = None, *a, **k):
254 super(WaitTask, self).__init__(*a, **k) 255 if duration is not None: 256 self.duration = duration 257 self.remaining = self.duration
258
259 - def do_update(self, delta):
260 super(WaitTask, self).do_update(delta) 261 self.remaining -= delta 262 if self.remaining <= 0: 263 self.kill() 264 self.remaining = 0
265
266 - def do_restart(self):
267 self.remaining = self.duration
268
269 270 -class DelayTask(Task):
271 duration = 1 272
273 - def __init__(self, duration = None, *a, **k):
274 super(DelayTask, self).__init__(*a, **k) 275 if duration is not None: 276 self.duration = duration 277 self.remaining = self.duration
278
279 - def do_restart(self):
280 self.remaining = self.duration
281
282 - def do_update(self, delta):
283 super(DelayTask, self).do_update(delta) 284 self.remaining -= 1 285 if self.remaining <= 0: 286 self.kill() 287 self.remaining = 0
288
289 290 -class TimerTask(WaitTask):
291
292 - def do_update(self, timer):
293 super(TimerTask, self).do_update(timer) 294 if self.remaining == 0: 295 self.on_finish() 296 else: 297 self.on_tick()
298
299 - def on_tick(self):
300 pass
301
302 - def on_finish(self):
303 pass
304
305 306 -class FadeTask(Task):
307
308 - def __init__(self, func = lambda x: x, duration = 1.0, loop = False, init = False, *a, **k):
309 super(FadeTask, self).__init__(*a, **k) 310 self.func = func 311 self.curr = 0.0 312 self.loop = loop 313 self.duration = duration 314 if init: 315 func(0.0)
316
317 - def do_update(self, delta):
318 super(FadeTask, self).do_update(delta) 319 self.func(self.curr / self.duration) 320 self.curr += delta 321 if self.curr >= self.duration: 322 if self.loop: 323 self.curr -= self.duration 324 else: 325 self.curr = self.duration 326 self.kill() 327 self.func(self.curr / self.duration)
328
329 - def do_restart(self):
330 super(FadeTask, self).do_restart() 331 self.curr = 0.0
332
333 334 -class SequenceTask(Task):
335
336 - def __init__(self, tasks = [], *a, **k):
337 super(SequenceTask, self).__init__(*a, **k) 338 self._tasks = tasks 339 self._iter = iter(tasks) 340 self._current = None 341 self._advance_sequence()
342
343 - def _advance_sequence(self):
344 try: 345 self._current = self._iter.next() 346 except StopIteration: 347 self.kill()
348
349 - def do_update(self, delta):
350 super(SequenceTask, self).do_update(delta) 351 if self._current is not None: 352 self._current.update(delta) 353 if self._current.is_killed: 354 self._advance_sequence()
355
356 - def do_restart(self):
357 for x in self._tasks: 358 x.restart() 359 360 self._iter = iter(self._tasks) 361 self._advance_sequence()
362
363 364 -def totask(task):
365 if not isinstance(task, Task): 366 if not callable(task): 367 raise TaskError('You can add either tasks or callables. ' + str(task)) 368 task = FuncTask(func=task) 369 return task
370
371 372 -def generator(orig):
373 equiv = [None] 374 375 @functools.wraps(orig) 376 def wrapper(): 377 return GeneratorTask(orig, equiv[0])
378 379 equiv[0] = wrapper 380 return wrapper 381
382 383 -def sequence(*tasks):
384 return SequenceTask(map(totask, tasks))
385
386 387 -def parallel(*tasks):
388 return TaskGroup(tasks=tasks, auto_remove=False)
389
390 391 -def loop(*tasks):
392 return TaskGroup(tasks=tasks, auto_remove=False, auto_kill=False, loop=True)
393 394 395 wait = WaitTask 396 fade = FadeTask 397 delay = DelayTask
398 399 -def invfade(f, *a, **k):
400 return fade((lambda x: f(1.0 - x)), *a, **k)
401
402 403 -def linear(f, min, max, *a, **k):
404 return fade((lambda x: f(Util.linear(min, max, x))), *a, **k)
405 406 407 try: 408 import math
409 410 - def sinusoid(f, min = 0.0, max = 1.0, *a, **k):
411 return fade((lambda x: f(min + (max - min) * math.sin(x * math.pi / 2.0))), *a, **k)
412 413 414 except ImportError as err: 415 pass
416 417 -def run(func, *a, **k):
418 return FuncTask(lambda t: None if func(*a, **k) else None)
419
420 421 -def repeat(task):
422 task = totask(task) 423 task.kill = task.restart 424 return WrapperTask(task)
425