]>
git.immae.eu Git - perso/Immae/Projets/Python/MusicSampler.git/blob - helpers/action.py
4 from transitions
.extensions
import HierarchicalMachine
as Machine
5 from . import debug_print
, error_print
27 'children': ['running']
41 'after': 'poll_loaded'
47 'after': 'poll_loaded'
52 'dest': 'loaded_running',
53 'after': 'finish_action',
54 # if a child has no transitions, then it is bubbled to the parent,
55 # and we don't want that. Not useful in that machine precisely.
56 'conditions': ['is_loaded']
59 'trigger': 'finish_action',
60 'source': 'loaded_running',
65 def __init__(self
, action
, key
, **kwargs
):
66 Machine(model
=self
, states
=self
.STATES
,
67 transitions
=self
.TRANSITIONS
, initial
='initial',
68 ignore_invalid_triggers
=True, queued
=True)
72 self
.mapping
= key
.parent
73 self
.arguments
= kwargs
74 self
.sleep_event
= None
75 self
.waiting_music
= None
77 def is_loaded_or_failed(self
):
78 return self
.is_loaded(allow_substates
=True) or self
.is_failed()
80 def callback_music_loaded(self
, success
):
86 # Machine states / events
87 def on_enter_loading(self
):
88 if self
.action
in self
.ACTION_TYPES
:
89 if 'music' in self
.arguments
:
90 self
.arguments
['music'].subscribe_loaded(self
.callback_music_loaded
)
94 error_print("Unknown action {}".format(self
.action
))
97 def on_enter_loaded_running(self
):
98 debug_print(self
.description())
99 getattr(self
, self
.action
)(**self
.arguments
)
101 def poll_loaded(self
):
102 self
.key
.callback_action_ready(self
,
103 self
.is_loaded(allow_substates
=True))
105 # This one cannot be in the Machine state since it would be queued to run
106 # *after* the wait is ended...
108 if getattr(self
, self
.action
+ "_interrupt", None):
109 return getattr(self
, self
.action
+ "_interrupt")(**self
.arguments
)
112 def music_list(self
, music
):
113 if music
is not None:
116 return self
.mapping
.open_files
.values()
118 def description(self
):
119 if getattr(self
, self
.action
+ "_print", None):
120 return getattr(self
, self
.action
+ "_print")(**self
.arguments
)
122 return "unknown action {}".format(self
.action
)
125 def command(self
, command
="", **kwargs
):
129 def pause(self
, music
=None, **kwargs
):
130 for music
in self
.music_list(music
):
131 if music
.is_loaded_playing():
134 def unpause(self
, music
=None, **kwargs
):
135 for music
in self
.music_list(music
):
136 if music
.is_loaded_paused():
139 def play(self
, music
=None, fade_in
=0, start_at
=0,
140 restart_if_running
=False, volume
=100,
142 for music
in self
.music_list(music
):
143 if restart_if_running
:
144 if music
.is_in_use():
151 elif not music
.is_in_use():
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
)
162 def interrupt_wait(self
, wait_id
=None):
163 self
.mapping
.interrupt_wait(wait_id
)
165 def stop(self
, music
=None, fade_out
=0, wait
=False,
166 set_wait_id
=None, **kwargs
):
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
)
174 music
.stop(fade_out
=fade_out
)
176 if previous
is not None:
177 self
.waiting_music
= previous
181 set_wait_id
=set_wait_id
)
183 def stop_all_actions(self
, **kwargs
):
184 self
.mapping
.stop_all_running()
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
)
190 self
.mapping
.set_master_volume(value
, delta
=delta
, fade
=fade
)
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
)
196 self
.sleep_event
= threading
.Event()
197 self
.sleep_event_timer
= threading
.Timer(duration
, self
.sleep_event
.set)
199 if music
is not None:
202 self
.sleep_event_timer
.start()
203 self
.sleep_event
.wait()
206 def command_print(self
, command
="", **kwargs
):
207 return "running command {}".format(command
)
209 def interrupt_wait_print(self
, wait_id
=None, **kwargs
):
210 return "interrupt wait with id {}".format(wait_id
)
212 def pause_print(self
, music
=None, **kwargs
):
213 if music
is not None:
214 return "pausing « {} »".format(music
.name
)
216 return "pausing all musics"
218 def unpause_print(self
, music
=None, **kwargs
):
219 if music
is not None:
220 return "unpausing « {} »".format(music
.name
)
222 return "unpausing all musics"
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
)
230 message
+= "all musics"
233 message
+= " at {}s".format(start_at
)
236 message
+= " with {}s fade_in".format(fade_in
)
238 message
+= " at volume {}%".format(volume
)
241 message
+= " {} times".format(loop
+ 1)
243 message
+= " in loop"
245 if restart_if_running
:
246 message
+= " (restarting if already running)"
250 def stop_print(self
, music
=None, fade_out
=0, wait
=False,
251 set_wait_id
=None, **kwargs
):
253 message
= "stopping "
254 if music
is not None:
255 message
+= "music « {} »".format(music
.name
)
257 message
+= "all musics"
260 message
+= " with {}s fadeout".format(fade_out
)
262 if set_wait_id
is not None:
263 message
+= " (waiting the end of fadeout, with id {})"\
266 message
+= " (waiting the end of fadeout)"
270 def stop_all_actions_print(self
, **kwargs
):
271 return "stopping all actions"
273 def seek_print(self
, music
=None, value
=0, delta
=False, **kwargs
):
275 if music
is not None:
276 return "moving music « {} » by {:+d}s" \
277 .format(music
.name
, value
)
279 return "moving all musics by {:+d}s" \
282 if music
is not None:
283 return "moving music « {} » to position {}s" \
284 .format(music
.name
, value
)
286 return "moving all musics to position {}s" \
289 def volume_print(self
, music
=None,
290 value
=100, delta
=False, fade
=0, **kwargs
):
293 if music
is not None:
294 message
+= "{:+d}% to volume of « {} »" \
295 .format(value
, music
.name
)
297 message
+= "{:+d}% to volume" \
300 if music
is not None:
301 message
+= "setting volume of « {} » to {}%" \
302 .format(music
.name
, value
)
304 message
+= "setting volume to {}%" \
308 message
+= " with {}s fade".format(fade
)
312 def wait_print(self
, duration
=0, music
=None, set_wait_id
=None, **kwargs
):
315 message
+= "waiting {}s" \
318 message
+= "waiting the end of « {} »" \
321 message
+= "waiting the end of « {} » + {}s" \
322 .format(music
.name
, duration
)
324 if set_wait_id
is not None:
325 message
+= " (setting id = {})".format(set_wait_id
)
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()
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()