]> git.immae.eu Git - perso/Immae/Projets/Python/MusicSampler.git/blame - music_sampler/action.py
Use pip setup file
[perso/Immae/Projets/Python/MusicSampler.git] / music_sampler / action.py
CommitLineData
b7ca3fc2 1from transitions.extensions import HierarchicalMachine as Machine
6ebe6247 2from .helpers import debug_print, error_print
c4f4f2a1 3from . import actions
a24c34bc 4
be27763f 5class Action:
b7ca3fc2
IB
6 STATES = [
7 'initial',
8 'loading',
9 'failed',
10 {
11 'name': 'loaded',
12 'children': ['running']
13 }
14 ]
15
16 TRANSITIONS = [
17 {
18 'trigger': 'load',
19 'source': 'initial',
20 'dest': 'loading'
21 },
22 {
23 'trigger': 'fail',
24 'source': 'loading',
e55b29bb
IB
25 'dest': 'failed',
26 'after': 'poll_loaded'
b7ca3fc2
IB
27 },
28 {
29 'trigger': 'success',
30 'source': 'loading',
e55b29bb
IB
31 'dest': 'loaded',
32 'after': 'poll_loaded'
b7ca3fc2
IB
33 },
34 {
35 'trigger': 'run',
36 'source': 'loaded',
37 'dest': 'loaded_running',
e55b29bb
IB
38 'after': 'finish_action',
39 # if a child has no transitions, then it is bubbled to the parent,
40 # and we don't want that. Not useful in that machine precisely.
41 'conditions': ['is_loaded']
b7ca3fc2
IB
42 },
43 {
44 'trigger': 'finish_action',
45 'source': 'loaded_running',
46 'dest': 'loaded'
47 }
48 ]
49
be27763f 50 def __init__(self, action, key, **kwargs):
b7ca3fc2
IB
51 Machine(model=self, states=self.STATES,
52 transitions=self.TRANSITIONS, initial='initial',
53 ignore_invalid_triggers=True, queued=True)
be27763f 54
b7ca3fc2 55 self.action = action
be27763f 56 self.key = key
1b4b78f5 57 self.mapping = key.parent
be27763f 58 self.arguments = kwargs
0deb82a5 59 self.sleep_event = None
b7ca3fc2 60 self.waiting_music = None
be27763f 61
e55b29bb
IB
62 def is_loaded_or_failed(self):
63 return self.is_loaded(allow_substates=True) or self.is_failed()
b7ca3fc2 64
e55b29bb 65 def callback_music_loaded(self, success):
b7ca3fc2
IB
66 if success:
67 self.success()
68 else:
69 self.fail()
70
71 # Machine states / events
72 def on_enter_loading(self):
c4f4f2a1 73 if hasattr(actions, self.action):
b7ca3fc2 74 if 'music' in self.arguments:
6c42e32d
IB
75 self.arguments['music'].subscribe_loaded(
76 self.callback_music_loaded)
b7ca3fc2
IB
77 else:
78 self.success()
be27763f 79 else:
b7ca3fc2
IB
80 error_print("Unknown action {}".format(self.action))
81 self.fail()
82
62a8b07a 83 def on_enter_loaded_running(self, key_start_time):
a24c34bc 84 debug_print(self.description())
c4f4f2a1 85 if hasattr(actions, self.action):
62a8b07a
IB
86 getattr(actions, self.action).run(self,
87 key_start_time=key_start_time, **self.arguments)
be27763f 88
e55b29bb
IB
89 def poll_loaded(self):
90 self.key.callback_action_ready(self,
91 self.is_loaded(allow_substates=True))
92
93 # This one cannot be in the Machine state since it would be queued to run
94 # *after* the wait is ended...
95 def interrupt(self):
c4f4f2a1
IB
96 if getattr(actions, self.action, None) and\
97 hasattr(getattr(actions, self.action), 'interrupt'):
98 return getattr(getattr(actions, self.action), 'interrupt')(
99 self, **self.arguments)
0deb82a5 100
b7ca3fc2 101 # Helpers
29597680 102 def music_list(self, music):
be27763f 103 if music is not None:
29597680 104 return [music]
be27763f 105 else:
1b4b78f5 106 return self.mapping.open_files.values()
29597680 107
b7ca3fc2 108 def description(self):
c4f4f2a1
IB
109 if hasattr(actions, self.action):
110 return getattr(actions, self.action)\
111 .description(self, **self.arguments)
b7ca3fc2
IB
112 else:
113 return "unknown action {}".format(self.action)