aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--helpers/action.py251
-rw-r--r--helpers/actions/__init__.py10
-rw-r--r--helpers/actions/command.py6
-rw-r--r--helpers/actions/interrupt_wait.py5
-rw-r--r--helpers/actions/pause.py10
-rw-r--r--helpers/actions/play.py44
-rw-r--r--helpers/actions/seek.py19
-rw-r--r--helpers/actions/stop.py42
-rw-r--r--helpers/actions/stop_all_actions.py5
-rw-r--r--helpers/actions/unpause.py10
-rw-r--r--helpers/actions/volume.py28
-rw-r--r--helpers/actions/wait.py38
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 @@
1import threading
2import time
3
4from transitions.extensions import HierarchicalMachine as Machine 1from transitions.extensions import HierarchicalMachine as Machine
5from . import debug_print, error_print 2from . import debug_print, error_print
3from . import actions
6 4
7class Action: 5class 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 @@
1from . import command
2from . import interrupt_wait
3from . import pause
4from . import play
5from . import seek
6from . import stop
7from . import stop_all_actions
8from . import unpause
9from . import volume
10from . 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 @@
1def run(action, command="", **kwargs):
2 # FIXME: todo
3 pass
4
5def 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 @@
1def run(action, wait_id=None):
2 action.mapping.interrupt_wait(wait_id)
3
4def 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 @@
1def run(action, music=None, **kwargs):
2 for music in action.music_list(music):
3 if music.is_loaded_playing():
4 music.pause()
5
6def 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 @@
1def 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
20def 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 @@
1def 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
5def 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 @@
1def 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
19def 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
39def 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 @@
1def run(action, **kwargs):
2 action.mapping.stop_all_running()
3
4def 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 @@
1def run(action, music=None, **kwargs):
2 for music in action.music_list(music):
3 if music.is_loaded_paused():
4 music.unpause()
5
6def 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 @@
1def 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
7def 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 @@
1import threading
2
3def 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
16def 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
33def 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()