diff options
-rw-r--r-- | broadcast.py | 93 |
1 files changed, 86 insertions, 7 deletions
diff --git a/broadcast.py b/broadcast.py index 1007af5..ad27283 100644 --- a/broadcast.py +++ b/broadcast.py @@ -102,6 +102,84 @@ print len(notestreams), 'notestreams' print len(clients), 'clients' print len(groups), 'groups' +class Route(object): + def __init__(self, fattr, fvalue, group, excl=False): + if fattr == 'U': + self.map = uid_groups + elif fattr == 'T': + self.map = type_groups + else: + raise ValueError('Not a valid attribute specifier: %r'%(fattr,)) + self.value = fvalue + if group not in groups: + raise ValueError('Not a present group: %r'%(group,)) + self.group = group + self.excl = excl + @classmethod + def Parse(cls, s): + fspecs, _, grpspecs = map(lambda x: x.strip(), s.partition('=')) + fpairs = [] + ret = [] + for fspec in [i.strip() for i in fspecs.split(',')]: + fattr, _, fvalue = map(lambda x: x.strip(), fspec.partition(':')) + fpairs.append((fattr, fvalue)) + for part in [i.strip() for i in grpspecs.split(',')]: + for fattr, fvalue in fpairs: + if part[0] == '+': + ret.append(Route(fattr, fvalue, part[1:], False)) + elif part[0] == '-': + ret.append(Route(fattr, fvalue, part[1:], True)) + else: + raise ValueError('Not an exclusivity: %r'%(part[0],)) + return ret + def __repr__(self): + return '<Route of %r to %s:%s>'%(self.group, ('U' if self.map is uid_groups else 'T'), self.value) + +class RouteSet(object): + def __init__(self, clis=None): + if clis is None: + clis = clients + self.clients = clis + self.routes = [] + def Route(self, stream): + grp = stream.get('group') + if options.verbose: + print 'Routing', grp, '...' + excl = False + for route in self.routes: + if route.group == grp: + if options.verbose: + print 'Matches route', route + excl = excl or route.excl + matches = filter(lambda x, route=route: route.Apply(x), self.clients) + if matches: + if options.verbose: + print 'Using client', matches[0] + self.clients.remove(matches[0]) + return matches[0] + print 'No matches, moving on...' + if excl: + if options.verbose: + print 'Exclusively routed, no route matched.' + return None + if not self.clients: + if options.verbose: + print 'Out of clients, no route matched.' + return None + cli = self.clients.pop(0) + if options.verbose: + print 'Default route to', cli + return cli + +routeset = RouteSet() +for rspec in options.routes: + routeset.routes.extend(Route.Parse(rspec)) + +if options.verbose: + print 'All routes:' + for route in routeset.routes: + print route + class NSThread(threading.Thread): def wait_for(self, t): if t <= 0: @@ -117,17 +195,18 @@ class NSThread(threading.Thread): while time.time() - BASETIME < factor*ttime: self.wait_for(factor*ttime - (time.time() - BASETIME)) s.sendto(str(Packet(CMD.PLAY, int(dur), int((dur*1000000)%1000000), int(440.0 * 2**((pitch-69)/12.0)), vel*2)), cl) - print (time.time() - BASETIME), cl, ': PLAY', pitch, dur, vel + if options.verbose: + print (time.time() - BASETIME), cl, ': PLAY', pitch, dur, vel self.wait_for(dur - ((time.time() - BASETIME) - factor*ttime)) - print '% 6.5f'%(time.time() - BASETIME,), cl, ': DONE' + if options.verbose: + print '% 6.5f'%(time.time() - BASETIME,), cl, ': DONE' threads = [] for ns in notestreams: - if not clients: - print 'WARNING: Out of clients!', - break - nsq = ns.findall('note') - threads.append(NSThread(args=(nsq, clients.pop(0)))) + cli = routeset.Route(ns) + if cli: + nsq = ns.findall('note') + threads.append(NSThread(args=(nsq, clients.pop(0)))) BASETIME = time.time() for thr in threads: |