예제 #1
0
def test_sanity_checks():
    seq = Sequence(log_level=SequenceLogLevel.disabled)
    seq.done()
    assert seq._state == SequenceState.TERMINATED

    with pytest.raises(SequenceError):
        seq.add(wait=3)

    with pytest.raises(SequenceError):
        Sequence(log_level=SequenceLogLevel.disabled).done().done()
예제 #2
0
def test_has_callback_queue_result():
    test_res = []

    class Example(AbstractObject):
        __subject_events__ = ('test', )

        def __init__(self):
            super(Example, self).__init__()
            self.listener_normal.subject = self
            self.listener_sequence.subject = self
            self.callback_called = False

        @defer
        def test(self):
            # noinspection PyUnresolvedReferences
            self.notify_test()

        @subject_slot("test")
        def listener_normal(self):
            pass

        @subject_slot("test")
        def listener_sequence(self):
            return Sequence(log_level=SequenceLogLevel.disabled).done()

    test_res = {"callback_called": False}

    # 'normal' listener
    obj = Example()
    seq = Sequence(log_level=SequenceLogLevel.disabled)
    seq.add(obj.test, complete_on=obj.listener_normal)
    seq.add(lambda: setattr(obj, "callback_called", True))

    def check_called():
        assert obj.callback_called

    seq.add(check_called)
    seq.done()

    # listener returning sequence
    test_res = {"callback_called": False}
    seq = Sequence(log_level=SequenceLogLevel.disabled)
    seq.add(obj.test, complete_on=obj.listener_sequence)
    seq.add(lambda: setattr(obj, "callback_called", True))

    def check_called():
        assert obj.callback_called

    seq.add(check_called)
    seq.done()
예제 #3
0
 def handle_error(self):
     seq = Sequence(bypass_errors=True)
     self.errored = True
     self.parent.keyboardShortcutManager.focus_window("logs terminal")
     seq.add(wait=1)
     seq.add(lambda: setattr(self, "errored", False))
     return seq.done()
    def clear_devices(self):
        seq = Sequence()
        for _ in range(len(self.devices)):
            seq.add(lambda: self.delete_device(self.devices[0]))
            seq.add(wait=1)

        return seq.done()
    def set_device_parameter_value(self,
                                   device_name,
                                   parameter_name,
                                   value,
                                   raise_if_not_exists=False):
        # type: (str, str, Any) -> None
        device = find_if(lambda d: d.name.lower() == device_name.lower(),
                         self.song.current_track.all_devices)
        if not device:
            if not raise_if_not_exists:
                return
            raise Protocol0Error("Couldn't find device %s in track devices" %
                                 device_name)

        param = find_if(lambda d: d.name.lower() == parameter_name.lower(),
                        device.parameters)

        if not param:
            if not raise_if_not_exists:
                return
            raise Protocol0Error("Couldn't find parameter %s in device %s" %
                                 (parameter_name, device_name))

        if param.is_enabled:
            seq = Sequence().add(wait=1)
            seq.add(lambda: setattr(param, "value", value))
            return seq.done()
    def _added_track_init(self):
        seq = Sequence()
        seq.add(wait=1)
        seq.add(self.link_audio_tracks)
        seq.add(lambda: setattr(self, "name", self.wrapped_track.name))

        return seq.done()
    def __init__(self, c_instance=None, init_song=True):
        super(Protocol0, self).__init__(c_instance=c_instance)
        # noinspection PyProtectedMember
        Protocol0.SELF = self
        self._c_instance.log_message = types.MethodType(
            lambda s, message: None, self._c_instance)
        self._is_dev_booted = False
        with self.component_guard():
            self.protocol0_song = Song(song=self.song())
            self.deviceManager = DeviceManager()  # needs to be here first
            self.songManager = SongManager()
            self.sessionManager = SessionManager()
            self.mixingManager = MixingManager()
            self.playTrackManager = PlayTrackManager()
            self.push2Manager = Push2Manager()
            self.trackManager = TrackManager()
            self.trackAutomationManager = AutomationTrackManager()
            self.keyboardShortcutManager = KeyBoardShortcutManager()
            self.midiManager = MidiManager()
            self.browserManager = BrowserManager()
            self.clyphxNavigationManager = NavAndViewActions()
            self.clyphxGlobalManager = GlobalActions()
            self.utilsManager = UtilsManager()
            self.actionManager = ActionManager()
            self.actionSetManager = ActionSetManager()
            self.actionTestManager = ActionTestManager()
            if init_song:
                seq = Sequence()
                seq.add(wait=2)
                seq.add(self.songManager.init_song)
                seq.add(self.dev_boot)
                seq.done()

        self.log_info("Protocol0 script loaded")
    def create_automation_group(self, parameter):
        # type: (DeviceParameter) -> None
        """ first step, instrument track is selected """
        seq = Sequence()
        self.parent.songManager.abstract_group_track_creation_in_progress = True

        if self.song.current_track.is_foldable:
            seq.add(
                lambda: setattr(self.song.current_track, "is_folded", False))
        else:
            seq.add(self.parent.trackManager.group_track)

        # this cannot be parallelized
        seq.add(
            partial(self.parent.trackManager.create_audio_track,
                    self.song.current_track.index + 1,
                    name="%s:%s:%s" % (AUTOMATION_TRACK_NAME,
                                       parameter.device.name, parameter.name)))
        seq.add(
            partial(self.parent.trackManager.create_midi_track,
                    self.song.current_track.index + 2,
                    name="%s:%s:%s" % (AUTOMATION_TRACK_NAME,
                                       parameter.device.name, parameter.name)))
        seq.add(lambda:
                setattr(self.parent.songManager,
                        "abstract_group_track_creation_in_progress", False))
        seq.add(wait=1)
        seq.add(self.parent.songManager._tracks_listener)

        return seq.done()
예제 #9
0
def test_async_callback_execution_order():
    test_res = []

    class Example:
        @has_callback_queue
        def listener(self):
            seq = Sequence(log_level=SequenceLogLevel.disabled)
            seq.add(lambda: test_res.append(0))
            seq.add(wait=1)
            seq.add(lambda: test_res.append(1))
            return seq.done()

    obj = Example()

    seq = Sequence(log_level=SequenceLogLevel.disabled)
    seq.add(nop, complete_on=obj.listener, name="timeout step", check_timeout=2)
    seq.add(lambda: test_res.append(2))
    seq.add(nop, name="after listener step")

    def check_res():
        assert test_res == [0, 1, 2]

    seq.add(check_res)

    seq.done()
    obj.listener()
예제 #10
0
    def focus_window(self, window_name):
        # type: (str) -> None
        seq = Sequence(bypass_errors=True)
        seq.add(self.parent.clyphxNavigationManager.focus_main)
        seq.add(partial(self._execute_python, "focus_window.py", window_name))

        return seq.done()
예제 #11
0
        def subject_slot_listener(self):
            seq = Sequence(log_level=SequenceLogLevel.disabled)

            self.test_res.append(self.val)
            seq.add(wait=3)
            seq.add(lambda: self.test_res.append(self.val + 1))

            return seq.done()
 def replace_all_notes(self, notes, cache=True):
     # type: (Clip, List[Note], bool) -> None
     self.select_all_notes()
     new_clip = not len(self._prev_notes)
     seq = Sequence()
     seq.add(partial(self.replace_selected_notes, notes, cache=cache))
     seq.add(self.deselect_all_notes)
     return seq.done()
예제 #13
0
        def callback_listener(self):
            seq = Sequence(log_level=SequenceLogLevel.disabled)

            self.test_res.append(self.val)
            seq.add(wait=1)
            seq.add(lambda: self.test_res.append(self.val + 1))

            return seq.done()
 def check_plugin_window_showable(self, device):
     # type: (Device) -> Optional[Sequence]
     seq = Sequence()
     seq.add(partial(self._make_device_showable, device),
             do_if_not=partial(self.is_plugin_window_visible,
                               device,
                               try_show=True))
     return seq.done()
예제 #15
0
 def _post_record(self):
     self.song.metronome = False
     self.midi.has_monitor_in = False
     seq = Sequence().add(wait=2)
     seq.add(lambda: setattr(self.audio.playable_clip, "warp_mode", Live.
                             Clip.WarpMode.complex_pro))
     seq.add(lambda: self.audio.playable_clip.quantize())
     return seq.done()
예제 #16
0
def test_simple_timeout():
    seq = Sequence(log_level=SequenceLogLevel.disabled)
    seq.add(nop, complete_on=lambda: False, name="timeout step", check_timeout=0)
    seq.add(nop, name="unreachable step")
    seq.done()

    assert seq._state == SequenceState.TERMINATED
    assert seq._errored
    def _has_clip_listener(self):
        super(AutomationAudioClipSlot, self)._has_clip_listener()
        seq = Sequence().add(wait=1)

        if not self.has_clip and self.automated_midi_clip_slot and self.automated_midi_clip_slot.has_clip:
            seq.add(self.automated_midi_clip_slot.clip.delete)

        return seq.done()
    def _make_device_showable(self, device):
        # type: (Device) -> Sequence
        """ handles only one level of grouping in racks. Should be enough for now """
        seq = Sequence()
        parent_rack = self._find_parent_rack(device)

        if not parent_rack:
            [
                setattr(d._view, "is_collapsed", True)
                for d in device.track.devices
            ]
            (x_device,
             y_device) = self._get_device_show_button_click_coordinates(device)
            seq.add(lambda: self.parent.keyboardShortcutManager.send_click(
                x=x_device, y=y_device),
                    wait=1,
                    name="click on device show button")
            seq.add(lambda: setattr(device._view, "is_collapsed", False),
                    wait=1,
                    name="uncollapse all devices")
        else:
            [
                setattr(d._view, "is_collapsed", True)
                for d in device.track.devices if d != parent_rack
            ]
            [
                setattr(d._view, "is_collapsed", True)
                for d in parent_rack.chains[0].devices
            ]

            (x_rack,
             y_rack) = self._get_rack_show_macros_button_click_coordinates(
                 parent_rack)
            (x_device,
             y_device) = self._get_device_show_button_click_coordinates(
                 device, parent_rack)

            seq.add(lambda: self.parent.keyboardShortcutManager.
                    toggle_device_button(x=x_rack, y=y_rack, activate=False),
                    wait=1,
                    name="hide rack macro controls")
            seq.add(lambda: self.parent.keyboardShortcutManager.send_click(
                x=x_device, y=y_device),
                    wait=1,
                    name="click on device show button")
            seq.add(lambda: self.parent.keyboardShortcutManager.
                    toggle_device_button(x=x_rack, y=y_rack, activate=True),
                    wait=1,
                    name="show rack macro controls")
            seq.add(lambda: [
                setattr(d._view, "is_collapsed", False)
                for d in parent_rack.chains[0].devices
            ],
                    wait=0,
                    name="uncollapse all rack devices")
            # at this point the rack macro controls could still be hidden if the plugin window masks the button

        return seq.done()
    def exclusive_activate(self):
        # type: () -> Sequence
        self.active_instance = self

        seq = Sequence()
        seq.add(partial(self.song.select_track, self.device_track))
        seq.add(self.parent.keyboardShortcutManager.show_and_activate_rev2_editor, wait=3)

        return seq.done()
예제 #20
0
 def select_track(self, selected_track):
     # type: (Song, AbstractTrack, bool) -> Sequence
     seq = Sequence()
     seq.add(partial(setattr, self._view, "selected_track",
                     selected_track.base_track._track),
             do_if=lambda: selected_track != self.song.selected_track,
             complete_on=lambda: lambda: self.song.selected_track ==
             selected_track)
     return seq.done()
 def load_rack_device(self, rack_name, hide=False):
     # type: (str, bool) -> None
     seq = Sequence()
     seq.add(partial(self.load_from_user_library, None,
                     "'%s.adg'" % rack_name),
             complete_on=lambda: find_if(lambda d: d.name == rack_name, self
                                         .song.selected_track.devices))
     if hide:
         seq.add(self.parent.keyboardShortcutManager.hide_plugins, wait=1)
     return seq.done()
def test_do_if():
    class Obj:
        a = 2

    obj = Obj()
    seq = Sequence(log_level=SequenceLogLevel.disabled)
    seq.add(lambda: setattr(obj, "a", 3), do_if=lambda: obj.a == 0)
    seq.add(lambda: setattr(obj, "a", 4), do_if_not=lambda: obj.a == 0)
    seq.done()
    assert seq._state == SequenceState.TERMINATED
    assert obj.a == 4
예제 #23
0
    def _has_clip_listener(self):
        super(AutomationMidiClipSlot, self)._has_clip_listener()
        seq = Sequence().add(wait=1)

        if not self.has_clip and self.automated_audio_clip_slot and self.automated_audio_clip_slot.has_clip:
            seq.add(self.automated_audio_clip_slot.clip.delete)
        elif self.has_clip and self.automated_audio_clip_slot and not self.automated_audio_clip_slot.has_clip:
            seq.add(self.automated_audio_clip_slot.insert_dummy_clip)
            seq.add(lambda: self.clip._connect(self.automated_audio_clip_slot.clip), name="connect to audio clip slot")

        return seq.done()
예제 #24
0
 def insert_dummy_clip(self):
     seq = Sequence()
     seq.add(partial(
         self.song.simple_tracks[0].clip_slots[0].duplicate_clip_to, self),
             complete_on=self._has_clip_listener)
     seq.add(lambda: setattr(self.clip, "warping", 1),
             name="enable clip warping")
     seq.add(wait=1)
     seq.add(lambda: setattr(self.clip, "looping", 1),
             name="enable clip looping")
     return seq.done()
예제 #25
0
    def send_keys(self, keys, repeat=False):
        # type: (str, bool) -> None
        seq = Sequence()
        seq.add(self.parent.clyphxNavigationManager.focus_main)
        seq.add(partial(self._execute_python, "send_keys.py", keys))
        if repeat:
            # here trying to mitigate shortcuts not received by Live god knows why ..
            seq.add(wait=1)
            seq.add(partial(self._execute_python, "send_keys.py", keys))

        return seq.done()
    def show_hide(self, force_show=False):
        # here we are on the device track
        force_show = force_show or not self.activated
        seq = Sequence()
        seq.add(self.check_activated)
        seq.add(wait=1)
        if force_show:
            seq.add(self.parent.keyboardShortcutManager.show_plugins)
        else:
            seq.add(self.parent.keyboardShortcutManager.show_hide_plugins)

        return seq.done()
        def set_name():
            seq = Sequence()
            seq.add(partial(self.song.selected_track.track_name.set, base_name=name))
            seq.add(self.parent.songManager._tracks_listener)  # rebuild tracks
            # the underlying track object should have changed
            track = self.song.simple_tracks[self.song.selected_track.index]
            seq.add(wait=1)
            seq.add(track._added_track_init)  # manual call is needed, as _added_track_listener is not going to be called
            if track.abstract_group_track:
                seq.add(track.abstract_group_track._added_track_init)  # the group track could change type as well

            return seq.done()
    def action_scroll_presets_or_samples(self, go_next):
        # type: (bool) -> None
        seq = Sequence()
        if self.device:
            seq.add(partial(self.song.select_track, self.device_track))
            # note: in the case of fast scrolling on a simpler, _devices_listener is not called in time
            # so the following could fail but will succeed just after so we just ignore the error
            seq.add(partial(self.song.select_device, self.device), silent=True)
            seq.add(lambda: setattr(self.device._view, "is_collapsed", False))

        seq.add(partial(self._scroll_presets_or_sample, go_next))
        return seq.done()
    def _added_track_init(self):
        seq = Sequence()
        self.is_folded = False
        output_routing_tracks = list(set([sub_track.output_routing_type.attached_object for sub_track in self.sub_tracks]))
        if len(output_routing_tracks) == 1 and output_routing_tracks[0] and output_routing_tracks[0] != self.song.master_track:
            self.set_output_routing_type(output_routing_tracks[0])
            [sub_track.set_output_routing_type(self) for sub_track in self.sub_tracks]

        if len(self.devices) == 0:
            seq.add(partial(self.parent.browserManager.load_rack_device, "Mix Base Rack"))

        return seq.done()
    def _added_track_init(self):
        """ this can be called once, when the Live track is created """
        if self.group_track is None:
            raise Protocol0Error(
                "An automation track should always be grouped")
        seq = Sequence()
        seq.add(wait=1)
        seq.add(lambda: [self.delete_device(d) for d in self.devices])

        if len(self.clips) == 0:
            seq.add(self._create_base_clips)
        return seq.done()