diff options
-rwxr-xr-x | blc/workspace.py | 44 |
1 files changed, 33 insertions, 11 deletions
diff --git a/blc/workspace.py b/blc/workspace.py index 214c374..00848c3 100755 --- a/blc/workspace.py +++ b/blc/workspace.py @@ -102,6 +102,7 @@ from multiprocessing.pool import ThreadPool import os.path import subprocess as subp import xml.etree.ElementTree as etree +import random ## BEGIN Constants @@ -117,6 +118,8 @@ AUDIO = "Audio" FORWARD = "Forward" LOOP = "Loop" SINGLESHOT = "SingleShot" +RANDOM = "Random" +PINGPONG = "PingPong" QXW = "{http://www.qlcplus.org/Workspace}" @@ -486,10 +489,16 @@ class Chaser(Function, Advanceable, PreRenderable): class here.""" repr_attr = ("id", "name", ("steps", lambda s: ",".join((str(i.id) for i in s)))) class ChaserData: - """Current state of a chaser.""" - def __init__(self, step_data, obey_loop): + """Current state of a chaser. + + The structure of step_data is as follows: + + [(step number, step data), ...] + """ + def __init__(self, step_data, obey_loop, forward): self.step_data = step_data self.obey_loop = obey_loop + self.forward = True @staticmethod def advance(t, data): @@ -504,21 +513,34 @@ class Chaser(Function, Advanceable, PreRenderable): return data def get_data(self): - return self.ChaserData(step_data=[], obey_loop=True) + return self.ChaserData(step_data=[], obey_loop=True, forward=True) def copy_data(self, data): return self.ChaserData(step_data=[(a,self.steps[a].copy_data(b)) for a,b in data.step_data], - obey_loop=data.obey_loop) + obey_loop=data.obey_loop, forward=data.forward) - def next_step(self, n) -> int: ## TODO: Implement other chaser types - """Return the next step in the chaser.""" + def next_step(self, data): ## TODO: Implement other chaser types + """Return the next step in the chaser. + + Returns a tuple (next step number, data) + """ + if len(data.step_data) == 0: + return 0, data + + n = data.step_data[-1][0] if self.run_order == LOOP: - return (n+1) % len(self.steps) + return (n+1) % len(self.steps), data elif self.run_order == SINGLESHOT: if n >= len(self.steps) - 1: - return -1 - return n+1 - return None + return -1, data + return n+1, data + elif self.run_order == RANDOM: + return (n+random.randint(1, len(self.steps)-1)) % len(self.steps), data + elif self.run_order == PINGPONG: + if n >= len(self.steps) - 1 or n == 0: ## Reverse direction + data.forward = not data.forward + return n+((-1)**int(data.forward)), data + raise NotImplementedError("Chaser type %s not implemented" % self.run_order) def render(self, t, data=None): if t >= self.actual_duration: ## Quick check @@ -647,7 +669,7 @@ class Chaser(Function, Advanceable, PreRenderable): scope.update(s.scope) cur += s.duration dur = sum(map(lambda s: s.duration, steps)) - elif run_order == LOOP: + elif run_order in (LOOP, PINGPONG, RANDOM): for s in steps: scope.update(s.scope) max_t = QLC_INFTY |