summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xblc/workspace.py44
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