-
Notifications
You must be signed in to change notification settings - Fork 16
/
DrumGroupFinderComponent.py
96 lines (81 loc) · 2.77 KB
/
DrumGroupFinderComponent.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
from __future__ import with_statement
from itertools import chain
import Live
from _Framework.Util import find_if
from _Framework.SubjectSlot import Subject, subject_slot_group, subject_slot
from _Framework.ControlSurfaceComponent import ControlSurfaceComponent
try:
from itertools import imap
except ImportError:
# Python 3...
imap=map
class DrumGroupFinderComponent(ControlSurfaceComponent, Subject):
"""
Looks in the hierarchy of devices of a track, looking
for the first available drum-rack (deep-first), updating as the
device list changes.
"""
__subject_events__ = ('drum_group',)
_drum_group = None
def __init__(self, target_track_component, layer = None, is_enabled = True, *a, **k):
super(DrumGroupFinderComponent, self).__init__(*a, **k)
self._target_track_component = target_track_component
self._on_track_changed.subject = self._target_track_component
self.update()
@property
def drum_group(self):
"""
The latest found drum rack.
"""
return self._drum_group
@property
def root(self):
"""
The currently observed track.
"""
return self._target_track_component.target_track
@subject_slot_group('devices')
def _on_devices_changed(self, chain):
self.update()
@subject_slot_group('chains')
def _on_chains_changed(self, chain):
self.update()
@subject_slot('target_track')
def _on_track_changed(self):
self.update()
def update(self):
super(DrumGroupFinderComponent, self).update()
if self.is_enabled():
self._update_listeners()
self._update_drum_group()
def _update_listeners(self):
root = self.root
devices = list(find_instrument_devices(root))
chains = list(chain([root], *[ d.chains for d in devices ]))
self._on_chains_changed.replace_subjects(devices)
self._on_devices_changed.replace_subjects(chains)
def _update_drum_group(self):
drum_group = find_drum_group_device(self.root)
if type(drum_group) != type(self._drum_group) or drum_group != self._drum_group:
self._drum_group = drum_group
self.notify_drum_group()
def find_instrument_devices(track_or_chain):
"""
Returns a list with all instrument rack descendants from a track
or chain.
"""
instrument = find_if(lambda d: d.type == Live.Device.DeviceType.instrument, track_or_chain.devices)
if instrument and not instrument.can_have_drum_pads:
if instrument.can_have_chains:
return chain([instrument], *imap(find_instrument_devices, instrument.chains))
return []
def find_drum_group_device(track_or_chain):
"""
Looks up recursively for a drum_group device in the track.
"""
instrument = find_if(lambda d: d.type == Live.Device.DeviceType.instrument, track_or_chain.devices)
if instrument:
if instrument.can_have_drum_pads:
return instrument
elif instrument.can_have_chains:
return find_if(bool, imap(find_drum_group_device, instrument.chains))