# HG changeset patch # User David McClosky # Date 2005-06-15 01:57:06 # Node ID 89cd37c4314bb22446fa4baed4b431f0c654803e # Parent feb7910eb6d4fa64bd36b841d9152a0004e21753 gyrocontroller and Submaster.combine_subdict gyrocontroller is not tested yet (nor does it have enough interface code for that to be possible) diff --git a/bin/gyrocontroller b/bin/gyrocontroller new file mode 100644 --- /dev/null +++ b/bin/gyrocontroller @@ -0,0 +1,82 @@ +#!/usr/bin/env python +# vi: syntax=python + +from __future__ import division +import run_local +from light9.Submaster import combine_subdict +from light9 import dmxclient, showconfig + +class circcycle: + """Like itertools.cycle, but with a prev() method too. You lose + all iterator benefits by using this, since it will store the whole + sequence/iterator in memory. Also, do not run this on an infinite + iterator, as it tuple'ifies the input.""" + def __init__(self, sequence): + self.sequence = tuple(sequence) + self.index = 0 + def __iter__(self): + return self + def change_index(self, delta): + self.index = (self.index + delta) % len(self.sequence) + def next(self): + ret = self.sequence[self.index] + self._change_index(1) + return ret + def prev(self): + ret = self.sequence[self.index] + self._change_index(-1) + return ret + +class AbstractSimpleController: + """Simple controller with minimal input and output: + + Input is 4 directions and 3 buttons. + Output is an integer and a color and maybe more. + + Left + B1/right + B1: prev/next sub + Y-axis + B2: set current level + B3: toggle keep/solo mode + Double-B3: clear kept levels""" + def __init__(self, subnames): + self.subnames = subnames + self.refresh() + def refresh(self): + # reload subs from disk + self.submasters = Submasters() + self.all_subs = circcycle(self.subnames) + self.current_sub = self.all_subs.next() + self.current_level = 1.0 + self.kept_levels = {} # subname : level [0..1] + self.keep_solo_mode = 'keep' # either 'keep' or 'solo' + def clear_kept_levels(self): + self.kept_levels.clear() + def next(self): + if self.keep_solo_mode == 'keep': + self.kept_levels[self.current_sub] = self.current_level + + self.current_sub = self.submasters.get_sub_by_name(self.all_subs.next()) + def prev(self): + if self.keep_solo_mode == 'keep': + self.kept_levels[self.current_sub] = self.current_level + + self.current_sub = self.submasters.get_sub_by_name(self.all_subs.prev()) + def get_levels_as_sub(self): + if self.keep_solo_mode == 'keep': + # send all levels in self.kept_levels + levels = combine_subdict(self.kept_levels) + else: + levels = {self.current_sub : self.current_level} + + return levels + def get_dmx_list(self): + maxes = self.get_levels_as_sub() + return maxes.get_dmx_list() + def send_levels(self): + levels = self.get_dmx_list() + dmxclient.outputlevels(levels) + +if __name__ == "__main__": + if 0: + x = range(20) + for z in circcycle(x): + print z diff --git a/bin/keyboardcomposer b/bin/keyboardcomposer --- a/bin/keyboardcomposer +++ b/bin/keyboardcomposer @@ -204,6 +204,7 @@ class KeyboardComposer(Frame): return dict([(name, slidervar.get()) for name, slidervar in self.slider_vars.items()]) def get_levels_as_sub(self): + # TODO this should be adapted to use Submaster.combine_subdict scaledsubs = [self.submasters.get_sub_by_name(sub) * level \ for sub, level in self.get_levels().items()] diff --git a/light9/Submaster.py b/light9/Submaster.py --- a/light9/Submaster.py +++ b/light9/Submaster.py @@ -124,6 +124,13 @@ def sub_maxes(*subs): dict_max(*[sub.levels for sub in nonzero_subs]), temporary=1) +def combine_subdict(subdict): + """A subdict is { Submaster objects : values }""" + scaledsubs = [sub * level for sub, level in subdict.items()] + maxes = sub_maxes(*scaledsubs) + + return maxes + class Submasters: "Collection o' Submaster objects" def __init__(self):