In [14]:
# Setup, don't modify this
import re
import collections
from pprint import pprint
stencils = collections.OrderedDict()
Patches_Per_Show = 16 # so 1st knob is shows/stencil, 2nd is patch
def make():
marker = "Generated by ipython patchGenerate"
output = []
output.append("// %s:\n" % marker)
patch_names = []
for a_stencil in stencils.values():
output.extend( a_stencil.patch_code_lines() )
# patches[]
patch_decl = []
for a_stencil in stencils.values():
the_patch_names = a_stencil.patch_names()
# fill out the 16/patch
for i in range(len(the_patch_names),16):
the_patch_names.append("empty_patch")
patch_decl.extend(["patch_%s" % x for x in the_patch_names])
output.append(
"const byte** patches[] = {"
+ ", ".join(patch_decl)
+ "};"
)
output.append("")
i=0
name_list = []
output.append('const char empty_patch_name[] PROGMEM = "-";')
for a_stencil in stencils.values():
the_patch_names = a_stencil.patch_names()
for n in the_patch_names :
output.append("const char patch_name_%s[] PROGMEM = \"%s\";" % (i,n))
name_list.append("patch_name_%s" % i)
i += 1
for empty_i in range(len(the_patch_names),16):
name_list.append("empty_patch_name")
output.append(
"PROGMEM char* const patch_names[] = {"
+ ", ".join(name_list)
+ "};"
)
output.append("const byte Patch_Count = count_of(patches);")
output.append("// Generated by ipython patchGenerate")
print "\n".join(output)
the dsl support (execute once)
In [15]:
# for use by "with"
class new_stencil(object):
current = None
def __init__(self,name):
self.name = name
self.patches = collections.OrderedDict()
new_stencil.current = self
def __enter__(self):
pass
def __exit__(self,err_type,err_value,traceback):
# print "exited %s w/%s" % (self,len(self.patches))
stencils[self.name] = self
def patch_names(self):
x=[]
for a_patch in self.patches.values():
x.append(a_patch.token_name())
return x
def patch_code_lines(self):
lines = []
for a_patch in self.patches.values():
lines.extend( a_patch.code_lines())
lines.append("")
return lines
class new_patch(object):
current = None
def __init__(self,name):
self.name = name
self.zones = []
new_patch.current = self
self.stencil = new_stencil.current
def __enter__(self):
pass
def __exit__(self,err_type,err_value,traceback):
self.stencil.patches[self.name] = self
# print "exited %s w/%s" % (self,len(self.zones))
def token_name(self):
n = "%s_%s" % (self.stencil.name,self.name)
n = re.sub('[^a-z0-9_]', '', n, flags=re.IGNORECASE)
return n
def code_lines(self):
lines = [ "// Patch '%s' : '%s'" % (self.stencil.name, self.name) ]
zone_maps = []
for i,zone in enumerate(self.zones):
if (zone and len(zone)>0):
zone_maps.append("patch_%s_z%s" % (self.token_name(),i))
array_lit = "{%s,-1}" % ",".join(("%s" % lunit) for lunit in zone)
lines.append(
" const byte patch_%s_z%s[] = %s;"
% (
self.token_name(),
i,
array_lit
)
)
else:
zone_maps.append('empty_zone')
zone_lit = ''
if len(zone_maps) > 0:
zone_lit = "{%s}" % ", ".join(zone_maps)
else:
zone_lit = 'empty_zones'
lines.append(
"const byte* patch_%s[Zone_Count] = %s;"
% (
self.token_name(),
zone_lit
)
)
return lines
def assign_zone(*lunit_list):
# print "make zone %s for %s of %s" % (lunit_list, new_patch.current, new_stencil.current)
if len(lunit_list) and isinstance(lunit_list[0],list):
new_patch.current.zones.append(lunit_list[0])
else:
new_patch.current.zones.append(lunit_list)
Patches Patches are structured as:
E.g.:
with new_stencil('Show 1'):
with new_patch('squarish'):
assign_zone(0,1,2,3,4,5)
assign_zone(6,7,8)
assign_zone(range(9,16))
assign_zone()
with new_patch('center'):
assign_zone(0,1,2,3,5,8,9,11,12,13,14,15)
assign_zone(4,7,10)
assign_zone()
assign_zone()
with new_patch('squarish #2'):
assign_zone(0,1,2,3,4,5)
assign_zone(6,7,8)
assign_zone(range(9,16))
assign_zone([])
with new_stencil('Show 2'):
with new_patch('cross'):
assign_zone(0,1,2,3,5,8,9,11,12,13,14,15)
assign_zone([])
assign_zone([])
assign_zone(4,7,10)
Keeps the order you specify.
In [16]:
# Edit, and Run to check
In [17]:
# Run this and paste result into patches.h
#------------------------------------------------
# 2016-10-26_RiverBend
with new_stencil('Test'):
with new_patch('Test-00'):
assign_zone(0,5,10)
assign_zone(1,6,11)
assign_zone(2,7,12)
assign_zone(3,8,13)
with new_patch('Test-01'):
assign_zone(0,1,2,3,4)
assign_zone(5,6,8,9)
assign_zone(10,11,13,14)
assign_zone(7,12)
with new_patch('Test-02'):
assign_zone(4,9,14)
assign_zone(11,12,13)
assign_zone(4,9,14)
assign_zone(1,2,5,8,10)
with new_patch('Test-03'):
assign_zone(4,9,14)
assign_zone(11,12,13)
assign_zone(1,2,3,6,7,8)
assign_zone(0,5,10)
with new_stencil('Tester'):
with new_patch('Tester-01'):
assign_zone(1,3,8,13,14)
assign_zone(4,5,9,10,11)
assign_zone(0,6)
assign_zone(2,7,12)
with new_patch('Tester-02'):
assign_zone(3,8,13,14)
assign_zone(5,7,10,11,12)
assign_zone(6,2,9)
assign_zone(0,1,4)
with new_patch('Tester-03'):
assign_zone(1,3,5,8,13)
assign_zone(0,2,7,10,11,12)
assign_zone(6,14)
assign_zone(4,9)
with new_patch('Tester-04'):
assign_zone(1,5,8,13)
assign_zone(0,3,4,7,9,12)
assign_zone(6)
assign_zone(2,10,11,14)
with new_stencil('Tester2'):
with new_patch('Tester2-01'):
assign_zone(1,3,5,8,13,14)
assign_zone(0,4,7,9,10,11,12)
assign_zone(6)
assign_zone(2)
with new_patch('Tester2-02'):
assign_zone(1,5,8,13)
assign_zone(0,3,7,12)
assign_zone(4,6,10,14)
assign_zone(2,9,11)
with new_patch('Tester2-03'):
assign_zone(1,3,5,8,13)
assign_zone(0,7,12)
assign_zone(4,6,10,14)
assign_zone(2,9,11)
with new_patch('Tester2-04'):
assign_zone(1,3,8,13)
assign_zone(0,4,7,9,11,12)
assign_zone(6,14)
assign_zone(2,5,10)
#-----------------------------------------
make()
In [ ]: