diff options
-rw-r--r-- | helpers/action.py | 251 | ||||
-rw-r--r-- | helpers/actions/__init__.py | 10 | ||||
-rw-r--r-- | helpers/actions/command.py | 6 | ||||
-rw-r--r-- | helpers/actions/interrupt_wait.py | 5 | ||||
-rw-r--r-- | helpers/actions/pause.py | 10 | ||||
-rw-r--r-- | helpers/actions/play.py | 44 | ||||
-rw-r--r-- | helpers/actions/seek.py | 19 | ||||
-rw-r--r-- | helpers/actions/stop.py | 42 | ||||
-rw-r--r-- | helpers/actions/stop_all_actions.py | 5 | ||||
-rw-r--r-- | helpers/actions/unpause.py | 10 | ||||
-rw-r--r-- | helpers/actions/volume.py | 28 | ||||
-rw-r--r-- | helpers/actions/wait.py | 38 |
12 files changed, 228 insertions, 240 deletions
diff --git a/helpers/action.py b/helpers/action.py index 010a6ca..1f374ec 100644 --- a/helpers/action.py +++ b/helpers/action.py | |||
@@ -1,23 +1,8 @@ | |||
1 | import threading | ||
2 | import time | ||
3 | |||
4 | from transitions.extensions import HierarchicalMachine as Machine | 1 | from transitions.extensions import HierarchicalMachine as Machine |
5 | from . import debug_print, error_print | 2 | from . import debug_print, error_print |
3 | from . import actions | ||
6 | 4 | ||
7 | class Action: | 5 | class Action: |
8 | ACTION_TYPES = [ | ||
9 | 'command', | ||
10 | 'interrupt_wait', | ||
11 | 'pause', | ||
12 | 'play', | ||
13 | 'seek', | ||
14 | 'stop', | ||
15 | 'stop_all_actions', | ||
16 | 'unpause', | ||
17 | 'volume', | ||
18 | 'wait', | ||
19 | ] | ||
20 | |||
21 | STATES = [ | 6 | STATES = [ |
22 | 'initial', | 7 | 'initial', |
23 | 'loading', | 8 | 'loading', |
@@ -85,7 +70,7 @@ class Action: | |||
85 | 70 | ||
86 | # Machine states / events | 71 | # Machine states / events |
87 | def on_enter_loading(self): | 72 | def on_enter_loading(self): |
88 | if self.action in self.ACTION_TYPES: | 73 | if hasattr(actions, self.action): |
89 | if 'music' in self.arguments: | 74 | if 'music' in self.arguments: |
90 | self.arguments['music'].subscribe_loaded(self.callback_music_loaded) | 75 | self.arguments['music'].subscribe_loaded(self.callback_music_loaded) |
91 | else: | 76 | else: |
@@ -96,7 +81,8 @@ class Action: | |||
96 | 81 | ||
97 | def on_enter_loaded_running(self): | 82 | def on_enter_loaded_running(self): |
98 | debug_print(self.description()) | 83 | debug_print(self.description()) |
99 | getattr(self, self.action)(**self.arguments) | 84 | if hasattr(actions, self.action): |
85 | getattr(actions, self.action).run(self, **self.arguments) | ||
100 | 86 | ||
101 | def poll_loaded(self): | 87 | def poll_loaded(self): |
102 | self.key.callback_action_ready(self, | 88 | self.key.callback_action_ready(self, |
@@ -105,8 +91,10 @@ class Action: | |||
105 | # This one cannot be in the Machine state since it would be queued to run | 91 | # This one cannot be in the Machine state since it would be queued to run |
106 | # *after* the wait is ended... | 92 | # *after* the wait is ended... |
107 | def interrupt(self): | 93 | def interrupt(self): |
108 | if getattr(self, self.action + "_interrupt", None): | 94 | if getattr(actions, self.action, None) and\ |
109 | return getattr(self, self.action + "_interrupt")(**self.arguments) | 95 | hasattr(getattr(actions, self.action), 'interrupt'): |
96 | return getattr(getattr(actions, self.action), 'interrupt')( | ||
97 | self, **self.arguments) | ||
110 | 98 | ||
111 | # Helpers | 99 | # Helpers |
112 | def music_list(self, music): | 100 | def music_list(self, music): |
@@ -116,225 +104,8 @@ class Action: | |||
116 | return self.mapping.open_files.values() | 104 | return self.mapping.open_files.values() |
117 | 105 | ||
118 | def description(self): | 106 | def description(self): |
119 | if getattr(self, self.action + "_print", None): | 107 | if hasattr(actions, self.action): |
120 | return getattr(self, self.action + "_print")(**self.arguments) | 108 | return getattr(actions, self.action)\ |
109 | .description(self, **self.arguments) | ||
121 | else: | 110 | else: |
122 | return "unknown action {}".format(self.action) | 111 | return "unknown action {}".format(self.action) |
123 | |||
124 | # Actions | ||
125 | def command(self, command="", **kwargs): | ||
126 | # FIXME: todo | ||
127 | pass | ||
128 | |||
129 | def pause(self, music=None, **kwargs): | ||
130 | for music in self.music_list(music): | ||
131 | if music.is_loaded_playing(): | ||
132 | music.pause() | ||
133 | |||
134 | def unpause(self, music=None, **kwargs): | ||
135 | for music in self.music_list(music): | ||
136 | if music.is_loaded_paused(): | ||
137 | music.unpause() | ||
138 | |||
139 | def play(self, music=None, fade_in=0, start_at=0, | ||
140 | restart_if_running=False, volume=100, | ||
141 | loop=0, **kwargs): | ||
142 | for music in self.music_list(music): | ||
143 | if restart_if_running: | ||
144 | if music.is_in_use(): | ||
145 | music.stop() | ||
146 | music.play( | ||
147 | volume=volume, | ||
148 | fade_in=fade_in, | ||
149 | start_at=start_at, | ||
150 | loop=loop) | ||
151 | elif not music.is_in_use(): | ||
152 | music.play( | ||
153 | volume=volume, | ||
154 | fade_in=fade_in, | ||
155 | start_at=start_at, | ||
156 | loop=loop) | ||
157 | |||
158 | def seek(self, music=None, value=0, delta=False, **kwargs): | ||
159 | for music in self.music_list(music): | ||
160 | music.seek(value=value, delta=delta) | ||
161 | |||
162 | def interrupt_wait(self, wait_id=None): | ||
163 | self.mapping.interrupt_wait(wait_id) | ||
164 | |||
165 | def stop(self, music=None, fade_out=0, wait=False, | ||
166 | set_wait_id=None, **kwargs): | ||
167 | previous = None | ||
168 | for music in self.music_list(music): | ||
169 | if music.is_loaded_paused() or music.is_loaded_playing(): | ||
170 | if previous is not None: | ||
171 | previous.stop(fade_out=fade_out) | ||
172 | previous = music | ||
173 | else: | ||
174 | music.stop(fade_out=fade_out) | ||
175 | |||
176 | if previous is not None: | ||
177 | self.waiting_music = previous | ||
178 | previous.stop( | ||
179 | fade_out=fade_out, | ||
180 | wait=wait, | ||
181 | set_wait_id=set_wait_id) | ||
182 | |||
183 | def stop_all_actions(self, **kwargs): | ||
184 | self.mapping.stop_all_running() | ||
185 | |||
186 | def volume(self, music=None, value=100, fade=0, delta=False, **kwargs): | ||
187 | if music is not None: | ||
188 | music.set_volume(value, delta=delta, fade=fade) | ||
189 | else: | ||
190 | self.mapping.set_master_volume(value, delta=delta, fade=fade) | ||
191 | |||
192 | def wait(self, duration=0, music=None, set_wait_id=None, **kwargs): | ||
193 | if set_wait_id is not None: | ||
194 | self.mapping.add_wait_id(set_wait_id, self) | ||
195 | |||
196 | self.sleep_event = threading.Event() | ||
197 | self.sleep_event_timer = threading.Timer(duration, self.sleep_event.set) | ||
198 | |||
199 | if music is not None: | ||
200 | music.wait_end() | ||
201 | |||
202 | self.sleep_event_timer.start() | ||
203 | self.sleep_event.wait() | ||
204 | |||
205 | # Action messages | ||
206 | def command_print(self, command="", **kwargs): | ||
207 | return "running command {}".format(command) | ||
208 | |||
209 | def interrupt_wait_print(self, wait_id=None, **kwargs): | ||
210 | return "interrupt wait with id {}".format(wait_id) | ||
211 | |||
212 | def pause_print(self, music=None, **kwargs): | ||
213 | if music is not None: | ||
214 | return "pausing « {} »".format(music.name) | ||
215 | else: | ||
216 | return "pausing all musics" | ||
217 | |||
218 | def unpause_print(self, music=None, **kwargs): | ||
219 | if music is not None: | ||
220 | return "unpausing « {} »".format(music.name) | ||
221 | else: | ||
222 | return "unpausing all musics" | ||
223 | |||
224 | def play_print(self, music=None, fade_in=0, start_at=0, | ||
225 | restart_if_running=False, volume=100, loop=0, **kwargs): | ||
226 | message = "starting " | ||
227 | if music is not None: | ||
228 | message += "« {} »".format(music.name) | ||
229 | else: | ||
230 | message += "all musics" | ||
231 | |||
232 | if start_at != 0: | ||
233 | message += " at {}s".format(start_at) | ||
234 | |||
235 | if fade_in != 0: | ||
236 | message += " with {}s fade_in".format(fade_in) | ||
237 | |||
238 | message += " at volume {}%".format(volume) | ||
239 | |||
240 | if loop > 0: | ||
241 | message += " {} times".format(loop + 1) | ||
242 | elif loop < 0: | ||
243 | message += " in loop" | ||
244 | |||
245 | if restart_if_running: | ||
246 | message += " (restarting if already running)" | ||
247 | |||
248 | return message | ||
249 | |||
250 | def stop_print(self, music=None, fade_out=0, wait=False, | ||
251 | set_wait_id=None, **kwargs): | ||
252 | |||
253 | message = "stopping " | ||
254 | if music is not None: | ||
255 | message += "music « {} »".format(music.name) | ||
256 | else: | ||
257 | message += "all musics" | ||
258 | |||
259 | if fade_out > 0: | ||
260 | message += " with {}s fadeout".format(fade_out) | ||
261 | if wait: | ||
262 | if set_wait_id is not None: | ||
263 | message += " (waiting the end of fadeout, with id {})"\ | ||
264 | .format(set_wait_id) | ||
265 | else: | ||
266 | message += " (waiting the end of fadeout)" | ||
267 | |||
268 | return message | ||
269 | |||
270 | def stop_all_actions_print(self, **kwargs): | ||
271 | return "stopping all actions" | ||
272 | |||
273 | def seek_print(self, music=None, value=0, delta=False, **kwargs): | ||
274 | if delta: | ||
275 | if music is not None: | ||
276 | return "moving music « {} » by {:+d}s" \ | ||
277 | .format(music.name, value) | ||
278 | else: | ||
279 | return "moving all musics by {:+d}s" \ | ||
280 | .format(value) | ||
281 | else: | ||
282 | if music is not None: | ||
283 | return "moving music « {} » to position {}s" \ | ||
284 | .format(music.name, value) | ||
285 | else: | ||
286 | return "moving all musics to position {}s" \ | ||
287 | .format(value) | ||
288 | |||
289 | def volume_print(self, music=None, | ||
290 | value=100, delta=False, fade=0, **kwargs): | ||
291 | message = "" | ||
292 | if delta: | ||
293 | if music is not None: | ||
294 | message += "{:+d}% to volume of « {} »" \ | ||
295 | .format(value, music.name) | ||
296 | else: | ||
297 | message += "{:+d}% to volume" \ | ||
298 | .format(value) | ||
299 | else: | ||
300 | if music is not None: | ||
301 | message += "setting volume of « {} » to {}%" \ | ||
302 | .format(music.name, value) | ||
303 | else: | ||
304 | message += "setting volume to {}%" \ | ||
305 | .format(value) | ||
306 | |||
307 | if fade > 0: | ||
308 | message += " with {}s fade".format(fade) | ||
309 | |||
310 | return message | ||
311 | |||
312 | def wait_print(self, duration=0, music=None, set_wait_id=None, **kwargs): | ||
313 | message = "" | ||
314 | if music is None: | ||
315 | message += "waiting {}s" \ | ||
316 | .format(duration) | ||
317 | elif duration == 0: | ||
318 | message += "waiting the end of « {} »" \ | ||
319 | .format(music.name) | ||
320 | else: | ||
321 | message += "waiting the end of « {} » + {}s" \ | ||
322 | .format(music.name, duration) | ||
323 | |||
324 | if set_wait_id is not None: | ||
325 | message += " (setting id = {})".format(set_wait_id) | ||
326 | |||
327 | return message | ||
328 | |||
329 | # Interruptions (only for non-"atomic" actions) | ||
330 | def wait_interrupt(self, duration=0, music=None, **kwargs): | ||
331 | if self.sleep_event is not None: | ||
332 | self.sleep_event.set() | ||
333 | self.sleep_event_timer.cancel() | ||
334 | if music is not None: | ||
335 | music.wait_event.set() | ||
336 | |||
337 | def stop_interrupt(self, music=None, fade_out=0, wait=False, | ||
338 | set_wait_id=None, **kwargs): | ||
339 | if self.waiting_music is not None: | ||
340 | self.waiting_music.wait_event.set() | ||
diff --git a/helpers/actions/__init__.py b/helpers/actions/__init__.py new file mode 100644 index 0000000..ea1e800 --- /dev/null +++ b/helpers/actions/__init__.py | |||
@@ -0,0 +1,10 @@ | |||
1 | from . import command | ||
2 | from . import interrupt_wait | ||
3 | from . import pause | ||
4 | from . import play | ||
5 | from . import seek | ||
6 | from . import stop | ||
7 | from . import stop_all_actions | ||
8 | from . import unpause | ||
9 | from . import volume | ||
10 | from . import wait | ||
diff --git a/helpers/actions/command.py b/helpers/actions/command.py new file mode 100644 index 0000000..96f72fe --- /dev/null +++ b/helpers/actions/command.py | |||
@@ -0,0 +1,6 @@ | |||
1 | def run(action, command="", **kwargs): | ||
2 | # FIXME: todo | ||
3 | pass | ||
4 | |||
5 | def description(action, command="", **kwargs): | ||
6 | return "running command {}".format(command) | ||
diff --git a/helpers/actions/interrupt_wait.py b/helpers/actions/interrupt_wait.py new file mode 100644 index 0000000..36766a2 --- /dev/null +++ b/helpers/actions/interrupt_wait.py | |||
@@ -0,0 +1,5 @@ | |||
1 | def run(action, wait_id=None): | ||
2 | action.mapping.interrupt_wait(wait_id) | ||
3 | |||
4 | def description(action, wait_id=None, **kwargs): | ||
5 | return "interrupt wait with id {}".format(wait_id) | ||
diff --git a/helpers/actions/pause.py b/helpers/actions/pause.py new file mode 100644 index 0000000..bb27734 --- /dev/null +++ b/helpers/actions/pause.py | |||
@@ -0,0 +1,10 @@ | |||
1 | def run(action, music=None, **kwargs): | ||
2 | for music in action.music_list(music): | ||
3 | if music.is_loaded_playing(): | ||
4 | music.pause() | ||
5 | |||
6 | def description(action, music=None, **kwargs): | ||
7 | if music is not None: | ||
8 | return "pausing « {} »".format(music.name) | ||
9 | else: | ||
10 | return "pausing all musics" | ||
diff --git a/helpers/actions/play.py b/helpers/actions/play.py new file mode 100644 index 0000000..fdba95b --- /dev/null +++ b/helpers/actions/play.py | |||
@@ -0,0 +1,44 @@ | |||
1 | def run(action, music=None, fade_in=0, start_at=0, | ||
2 | restart_if_running=False, volume=100, | ||
3 | loop=0, **kwargs): | ||
4 | for music in action.music_list(music): | ||
5 | if restart_if_running: | ||
6 | if music.is_in_use(): | ||
7 | music.stop() | ||
8 | music.play( | ||
9 | volume=volume, | ||
10 | fade_in=fade_in, | ||
11 | start_at=start_at, | ||
12 | loop=loop) | ||
13 | elif not music.is_in_use(): | ||
14 | music.play( | ||
15 | volume=volume, | ||
16 | fade_in=fade_in, | ||
17 | start_at=start_at, | ||
18 | loop=loop) | ||
19 | |||
20 | def description(action, music=None, fade_in=0, start_at=0, | ||
21 | restart_if_running=False, volume=100, loop=0, **kwargs): | ||
22 | message = "starting " | ||
23 | if music is not None: | ||
24 | message += "« {} »".format(music.name) | ||
25 | else: | ||
26 | message += "all musics" | ||
27 | |||
28 | if start_at != 0: | ||
29 | message += " at {}s".format(start_at) | ||
30 | |||
31 | if fade_in != 0: | ||
32 | message += " with {}s fade_in".format(fade_in) | ||
33 | |||
34 | message += " at volume {}%".format(volume) | ||
35 | |||
36 | if loop > 0: | ||
37 | message += " {} times".format(loop + 1) | ||
38 | elif loop < 0: | ||
39 | message += " in loop" | ||
40 | |||
41 | if restart_if_running: | ||
42 | message += " (restarting if already running)" | ||
43 | |||
44 | return message | ||
diff --git a/helpers/actions/seek.py b/helpers/actions/seek.py new file mode 100644 index 0000000..467af7d --- /dev/null +++ b/helpers/actions/seek.py | |||
@@ -0,0 +1,19 @@ | |||
1 | def run(action, music=None, value=0, delta=False, **kwargs): | ||
2 | for music in action.music_list(music): | ||
3 | music.seek(value=value, delta=delta) | ||
4 | |||
5 | def description(action, music=None, value=0, delta=False, **kwargs): | ||
6 | if delta: | ||
7 | if music is not None: | ||
8 | return "moving music « {} » by {:+d}s" \ | ||
9 | .format(music.name, value) | ||
10 | else: | ||
11 | return "moving all musics by {:+d}s" \ | ||
12 | .format(value) | ||
13 | else: | ||
14 | if music is not None: | ||
15 | return "moving music « {} » to position {}s" \ | ||
16 | .format(music.name, value) | ||
17 | else: | ||
18 | return "moving all musics to position {}s" \ | ||
19 | .format(value) | ||
diff --git a/helpers/actions/stop.py b/helpers/actions/stop.py new file mode 100644 index 0000000..88cc66d --- /dev/null +++ b/helpers/actions/stop.py | |||
@@ -0,0 +1,42 @@ | |||
1 | def run(action, music=None, fade_out=0, wait=False, | ||
2 | set_wait_id=None, **kwargs): | ||
3 | previous = None | ||
4 | for music in action.music_list(music): | ||
5 | if music.is_loaded_paused() or music.is_loaded_playing(): | ||
6 | if previous is not None: | ||
7 | previous.stop(fade_out=fade_out) | ||
8 | previous = music | ||
9 | else: | ||
10 | music.stop(fade_out=fade_out) | ||
11 | |||
12 | if previous is not None: | ||
13 | action.waiting_music = previous | ||
14 | previous.stop( | ||
15 | fade_out=fade_out, | ||
16 | wait=wait, | ||
17 | set_wait_id=set_wait_id) | ||
18 | |||
19 | def description(action, music=None, fade_out=0, wait=False, | ||
20 | set_wait_id=None, **kwargs): | ||
21 | |||
22 | message = "stopping " | ||
23 | if music is not None: | ||
24 | message += "music « {} »".format(music.name) | ||
25 | else: | ||
26 | message += "all musics" | ||
27 | |||
28 | if fade_out > 0: | ||
29 | message += " with {}s fadeout".format(fade_out) | ||
30 | if wait: | ||
31 | if set_wait_id is not None: | ||
32 | message += " (waiting the end of fadeout, with id {})"\ | ||
33 | .format(set_wait_id) | ||
34 | else: | ||
35 | message += " (waiting the end of fadeout)" | ||
36 | |||
37 | return message | ||
38 | |||
39 | def interrupt(action, music=None, fade_out=0, wait=False, | ||
40 | set_wait_id=None, **kwargs): | ||
41 | if action.waiting_music is not None: | ||
42 | action.waiting_music.wait_event.set() | ||
diff --git a/helpers/actions/stop_all_actions.py b/helpers/actions/stop_all_actions.py new file mode 100644 index 0000000..f3fc5fb --- /dev/null +++ b/helpers/actions/stop_all_actions.py | |||
@@ -0,0 +1,5 @@ | |||
1 | def run(action, **kwargs): | ||
2 | action.mapping.stop_all_running() | ||
3 | |||
4 | def description(action, **kwargs): | ||
5 | return "stopping all actions" | ||
diff --git a/helpers/actions/unpause.py b/helpers/actions/unpause.py new file mode 100644 index 0000000..5fa88c3 --- /dev/null +++ b/helpers/actions/unpause.py | |||
@@ -0,0 +1,10 @@ | |||
1 | def run(action, music=None, **kwargs): | ||
2 | for music in action.music_list(music): | ||
3 | if music.is_loaded_paused(): | ||
4 | music.unpause() | ||
5 | |||
6 | def description(action, music=None, **kwargs): | ||
7 | if music is not None: | ||
8 | return "unpausing « {} »".format(music.name) | ||
9 | else: | ||
10 | return "unpausing all musics" | ||
diff --git a/helpers/actions/volume.py b/helpers/actions/volume.py new file mode 100644 index 0000000..7dda3c1 --- /dev/null +++ b/helpers/actions/volume.py | |||
@@ -0,0 +1,28 @@ | |||
1 | def run(action, music=None, value=100, fade=0, delta=False, **kwargs): | ||
2 | if music is not None: | ||
3 | music.set_volume(value, delta=delta, fade=fade) | ||
4 | else: | ||
5 | action.mapping.set_master_volume(value, delta=delta, fade=fade) | ||
6 | |||
7 | def description(action, music=None, | ||
8 | value=100, delta=False, fade=0, **kwargs): | ||
9 | message = "" | ||
10 | if delta: | ||
11 | if music is not None: | ||
12 | message += "{:+d}% to volume of « {} »" \ | ||
13 | .format(value, music.name) | ||
14 | else: | ||
15 | message += "{:+d}% to volume" \ | ||
16 | .format(value) | ||
17 | else: | ||
18 | if music is not None: | ||
19 | message += "setting volume of « {} » to {}%" \ | ||
20 | .format(music.name, value) | ||
21 | else: | ||
22 | message += "setting volume to {}%" \ | ||
23 | .format(value) | ||
24 | |||
25 | if fade > 0: | ||
26 | message += " with {}s fade".format(fade) | ||
27 | |||
28 | return message | ||
diff --git a/helpers/actions/wait.py b/helpers/actions/wait.py new file mode 100644 index 0000000..f7d2a78 --- /dev/null +++ b/helpers/actions/wait.py | |||
@@ -0,0 +1,38 @@ | |||
1 | import threading | ||
2 | |||
3 | def run(action, duration=0, music=None, set_wait_id=None, **kwargs): | ||
4 | if set_wait_id is not None: | ||
5 | action.mapping.add_wait_id(set_wait_id, action) | ||
6 | |||
7 | action.sleep_event = threading.Event() | ||
8 | action.sleep_event_timer = threading.Timer(duration, action.sleep_event.set) | ||
9 | |||
10 | if music is not None: | ||
11 | music.wait_end() | ||
12 | |||
13 | action.sleep_event_timer.start() | ||
14 | action.sleep_event.wait() | ||
15 | |||
16 | def description(action, duration=0, music=None, set_wait_id=None, **kwargs): | ||
17 | message = "" | ||
18 | if music is None: | ||
19 | message += "waiting {}s" \ | ||
20 | .format(duration) | ||
21 | elif duration == 0: | ||
22 | message += "waiting the end of « {} »" \ | ||
23 | .format(music.name) | ||
24 | else: | ||
25 | message += "waiting the end of « {} » + {}s" \ | ||
26 | .format(music.name, duration) | ||
27 | |||
28 | if set_wait_id is not None: | ||
29 | message += " (setting id = {})".format(set_wait_id) | ||
30 | |||
31 | return message | ||
32 | |||
33 | def interrupt(action, duration=0, music=None, **kwargs): | ||
34 | if action.sleep_event is not None: | ||
35 | action.sleep_event.set() | ||
36 | action.sleep_event_timer.cancel() | ||
37 | if music is not None: | ||
38 | music.wait_event.set() | ||