diff options
author | Ismaël Bouya <ismael.bouya@normalesup.org> | 2016-07-14 15:39:54 +0200 |
---|---|---|
committer | Ismaël Bouya <ismael.bouya@normalesup.org> | 2016-07-14 15:39:54 +0200 |
commit | 0deb82a57ae3abefd44509dc88c546f6e5a94d1b (patch) | |
tree | cf082f141a89425f9014eb5b203336e49f5c0252 | |
parent | ecaf3148af1d9adff1819f9536f483ebf7c85a95 (diff) | |
download | MusicSampler-0deb82a57ae3abefd44509dc88c546f6e5a94d1b.tar.gz MusicSampler-0deb82a57ae3abefd44509dc88c546f6e5a94d1b.tar.zst MusicSampler-0deb82a57ae3abefd44509dc88c546f6e5a94d1b.zip |
Make 'wait' action interruptible
-rw-r--r-- | helpers/action.py | 38 | ||||
-rw-r--r-- | helpers/key.py | 7 | ||||
-rw-r--r-- | helpers/mapping.py | 3 | ||||
-rw-r--r-- | helpers/music_file.py | 9 |
4 files changed, 43 insertions, 14 deletions
diff --git a/helpers/action.py b/helpers/action.py index 69ae96f..9145629 100644 --- a/helpers/action.py +++ b/helpers/action.py | |||
@@ -1,4 +1,4 @@ | |||
1 | import pygame | 1 | import threading |
2 | import time | 2 | import time |
3 | 3 | ||
4 | class Action: | 4 | class Action: |
@@ -21,6 +21,7 @@ class Action: | |||
21 | 21 | ||
22 | self.key = key | 22 | self.key = key |
23 | self.arguments = kwargs | 23 | self.arguments = kwargs |
24 | self.sleep_event = None | ||
24 | 25 | ||
25 | def ready(self): | 26 | def ready(self): |
26 | if 'music' in self.arguments: | 27 | if 'music' in self.arguments: |
@@ -35,7 +36,13 @@ class Action: | |||
35 | def description(self): | 36 | def description(self): |
36 | return getattr(self, self.action + "_print")(**self.arguments) | 37 | return getattr(self, self.action + "_print")(**self.arguments) |
37 | 38 | ||
39 | def interrupt(self): | ||
40 | if getattr(self, self.action + "_interrupt", None): | ||
41 | return getattr(self, self.action + "_interrupt")(**self.arguments) | ||
42 | |||
43 | # Actions | ||
38 | def command(self, command = "", **kwargs): | 44 | def command(self, command = "", **kwargs): |
45 | # FIXME: todo | ||
39 | pass | 46 | pass |
40 | 47 | ||
41 | def music_list(self, music): | 48 | def music_list(self, music): |
@@ -81,14 +88,15 @@ class Action: | |||
81 | pass | 88 | pass |
82 | 89 | ||
83 | def wait(self, duration = 0, music = None, **kwargs): | 90 | def wait(self, duration = 0, music = None, **kwargs): |
84 | # FIXME: Make it stoppable | 91 | self.sleep_event = threading.Event() |
85 | # http://stackoverflow.com/questions/29082268/python-time-sleep-vs-event-wait | 92 | |
86 | if music is None: | 93 | if music is not None: |
87 | time.sleep(duration) | ||
88 | else: | ||
89 | # TODO | ||
90 | music.wait_end() | 94 | music.wait_end() |
91 | 95 | ||
96 | threading.Timer(duration, self.sleep_event.set).start() | ||
97 | self.sleep_event.wait() | ||
98 | |||
99 | # Action messages | ||
92 | def command_print(self, command = "", **kwargs): | 100 | def command_print(self, command = "", **kwargs): |
93 | return "running command {}".format(command) | 101 | return "running command {}".format(command) |
94 | 102 | ||
@@ -146,7 +154,19 @@ class Action: | |||
146 | else: | 154 | else: |
147 | return "setting volume to {}%".format(value) | 155 | return "setting volume to {}%".format(value) |
148 | 156 | ||
149 | def wait_print(self, duration, **kwargs): | 157 | def wait_print(self, duration = 0, music = None, **kwargs): |
150 | return "waiting {}s".format(duration) | 158 | if music is None: |
159 | return "waiting {}s".format(duration) | ||
160 | elif duration == 0: | ||
161 | return "waiting the end of « {} »".format(music.name) | ||
162 | else: | ||
163 | return "waiting the end of « {} » + {}s".format(music.name, duration) | ||
151 | 164 | ||
152 | 165 | ||
166 | # Interruptions | ||
167 | def wait_interrupt(self, duration = 0, music = None, **kwargs): | ||
168 | if self.sleep_event is not None: | ||
169 | self.sleep_event.set() | ||
170 | if music is not None: | ||
171 | music.wait_event.set() | ||
172 | |||
diff --git a/helpers/key.py b/helpers/key.py index ca73b87..5eaf481 100644 --- a/helpers/key.py +++ b/helpers/key.py | |||
@@ -79,6 +79,9 @@ class Key(ButtonBehavior, Widget): | |||
79 | def add_action(self, action_name, **arguments): | 79 | def add_action(self, action_name, **arguments): |
80 | self.actions.append(Action(action_name, self, **arguments)) | 80 | self.actions.append(Action(action_name, self, **arguments)) |
81 | 81 | ||
82 | def interrupt_action(self): | ||
83 | self.current_action.interrupt() | ||
84 | |||
82 | def do_actions(self): | 85 | def do_actions(self): |
83 | if not self.enabled: | 86 | if not self.enabled: |
84 | return None | 87 | return None |
@@ -88,10 +91,10 @@ class Key(ButtonBehavior, Widget): | |||
88 | start_time = time.time() | 91 | start_time = time.time() |
89 | self.parent.start_running(self, start_time) | 92 | self.parent.start_running(self, start_time) |
90 | action_number = 0 | 93 | action_number = 0 |
91 | for action in self.actions: | 94 | for self.current_action in self.actions: |
92 | if self.parent.keep_running(self, start_time): | 95 | if self.parent.keep_running(self, start_time): |
93 | self.list_actions(action_number = action_number + 0.5) | 96 | self.list_actions(action_number = action_number + 0.5) |
94 | action.run() | 97 | self.current_action.run() |
95 | action_number += 1 | 98 | action_number += 1 |
96 | self.list_actions(action_number = action_number) | 99 | self.list_actions(action_number = action_number) |
97 | 100 | ||
diff --git a/helpers/mapping.py b/helpers/mapping.py index 95c9d67..ea9d075 100644 --- a/helpers/mapping.py +++ b/helpers/mapping.py | |||
@@ -65,7 +65,10 @@ class Mapping(RelativeLayout): | |||
65 | return False | 65 | return False |
66 | 66 | ||
67 | def stop_all_running(self): | 67 | def stop_all_running(self): |
68 | running = self.running | ||
68 | self.running = [] | 69 | self.running = [] |
70 | for (key, start_time) in running: | ||
71 | key.interrupt_action() | ||
69 | 72 | ||
70 | def start_running(self, key, start_time): | 73 | def start_running(self, key, start_time): |
71 | self.running.append((key, start_time)) | 74 | self.running.append((key, start_time)) |
diff --git a/helpers/music_file.py b/helpers/music_file.py index b40de1a..e6a340d 100644 --- a/helpers/music_file.py +++ b/helpers/music_file.py | |||
@@ -40,8 +40,8 @@ class MusicFile(Machine): | |||
40 | self.audio_segment = None | 40 | self.audio_segment = None |
41 | self.gain = gain | 41 | self.gain = gain |
42 | self.music_lock = Lock("music__" + filename) | 42 | self.music_lock = Lock("music__" + filename) |
43 | self.wait_event = threading.Event() | ||
43 | 44 | ||
44 | self.flag_paused = False | ||
45 | threading.Thread(name = "MSMusicLoad", target = self.load).start() | 45 | threading.Thread(name = "MSMusicLoad", target = self.load).start() |
46 | 46 | ||
47 | def on_enter_loading(self): | 47 | def on_enter_loading(self): |
@@ -109,6 +109,9 @@ class MusicFile(Machine): | |||
109 | if self.is_loaded_stopping(): | 109 | if self.is_loaded_stopping(): |
110 | self.stopped() | 110 | self.stopped() |
111 | 111 | ||
112 | def on_enter_loaded_stopped(self): | ||
113 | self.wait_event.set() | ||
114 | |||
112 | def play_callback(self, out_data, frame_count, time_info, status_flags): | 115 | def play_callback(self, out_data, frame_count, time_info, status_flags): |
113 | with self.music_lock: | 116 | with self.music_lock: |
114 | audio_segment = self.current_audio_segment.get_sample_slice_data( | 117 | audio_segment = self.current_audio_segment.get_sample_slice_data( |
@@ -147,8 +150,8 @@ class MusicFile(Machine): | |||
147 | return 20 * math.log10(max(volume, 0.0001) / 100) | 150 | return 20 * math.log10(max(volume, 0.0001) / 100) |
148 | 151 | ||
149 | def wait_end(self): | 152 | def wait_end(self): |
150 | # FIXME: todo | 153 | self.wait_event.clear() |
151 | pass | 154 | self.wait_event.wait() |
152 | 155 | ||
153 | # Add some more functions to AudioSegments | 156 | # Add some more functions to AudioSegments |
154 | def get_sample_slice_data(self, start_sample=0, end_sample=float('inf')): | 157 | def get_sample_slice_data(self, start_sample=0, end_sample=float('inf')): |