]> git.immae.eu Git - perso/Immae/Projets/Python/MusicSampler.git/blobdiff - music_sampler/mapping.py
Don't lock the application when failing while reloading configuration
[perso/Immae/Projets/Python/MusicSampler.git] / music_sampler / mapping.py
index 99c99773b7751c213eb2546871fd3d2dfbb9d229..a526ad2244485174fb03a97a1a3491dc5d184cd3 100644 (file)
@@ -22,8 +22,7 @@ class Mapping(RelativeLayout):
         'configuring',
         'configured',
         'loading',
-        'loaded',
-        'failed'
+        'loaded'
     ]
 
     TRANSITIONS = [
@@ -32,11 +31,6 @@ class Mapping(RelativeLayout):
             'source': 'initial',
             'dest': 'configuring'
         },
-        {
-            'trigger': 'fail',
-            'source': 'configuring',
-            'dest': 'failed'
-        },
         {
             'trigger': 'success',
             'source': 'configuring',
@@ -48,11 +42,6 @@ class Mapping(RelativeLayout):
             'source': 'configured',
             'dest': 'loading'
         },
-        {
-            'trigger': 'fail',
-            'source': 'loading',
-            'dest': 'failed'
-        },
         {
             'trigger': 'success',
             'source': 'loading',
@@ -74,17 +63,18 @@ class Mapping(RelativeLayout):
         self.running = []
         self.wait_ids = {}
         self.open_files = {}
+        self.is_leaving_application = False
 
         Machine(model=self, states=self.STATES,
                 transitions=self.TRANSITIONS, initial='initial',
-                ignore_invalid_triggers=True, queued=True)
+                auto_transitions=False, queued=True)
         super(Mapping, self).__init__(**kwargs)
         self.keyboard = Window.request_keyboard(self.on_keyboard_closed, self)
         self.keyboard.bind(on_key_down=self.on_keyboard_down)
 
-        self.configure()
+        self.configure(initial=True)
 
-    def on_enter_configuring(self):
+    def on_enter_configuring(self, initial=True):
         if Config.builtin_mixing:
             self.mixer = Mixer()
         else:
@@ -94,9 +84,9 @@ class Mapping(RelativeLayout):
             self.key_config, self.open_files = self.parse_config()
         except Exception as e:
             error_print("Error while loading configuration: {}".format(e),
-                    with_trace=True, exit=True)
-        else:
-            self.success()
+                    with_trace=False, exit=initial)
+
+        self.success()
 
     def on_enter_loading(self):
         for key in self.keys:
@@ -127,13 +117,14 @@ class Mapping(RelativeLayout):
         elif 'ctrl' in modifiers and (keycode[0] == 113 or keycode[0] == '99'):
             self.leave_application()
             sys.exit()
-        elif 'ctrl' in modifiers and keycode[0] == 114:
-            threading.Thread(name="MSReload", target=self.reload).start()
+        elif 'ctrl' in modifiers and keycode[0] == 114 and self.is_loaded():
+            self.reload(initial=False)
         return True
 
     def leave_application(self):
         self.keyboard.unbind(on_key_down=self.on_keyboard_down)
         self.stop_all_running()
+        self.is_leaving_application = True
         for music in self.open_files.values():
             music.stop()
         for thread in threading.enumerate():
@@ -167,13 +158,20 @@ class Mapping(RelativeLayout):
 
     # Callbacks
     def key_loaded_callback(self):
+        if hasattr(self, 'finished_loading'):
+            return
+
+        opacity = int(Config.load_all_musics)
+
         result = self.all_keys_ready()
         if result == "success":
-            self.ready_color = [0, 1, 0, 1]
+            self.ready_color = [0, 1, 0, opacity]
+            self.finished_loading = True
         elif result == "partial":
-            self.ready_color = [1, 0, 0, 1]
+            self.ready_color = [1, 0, 0, opacity]
+            self.finished_loading = True
         else:
-            self.ready_color = [1, 165/255, 0, 1]
+            self.ready_color = [1, 165/255, 0, opacity]
 
     ## Some global actions
     def stop_all_running(self, except_key=None, key_start_time=0):
@@ -206,15 +204,17 @@ class Mapping(RelativeLayout):
                 self.wait_ids[None] = []
             self.wait_ids[None].append(action_or_wait)
 
-    def interrupt_wait(self, wait_id=None):
+    def matching_wait_ids(self, wait_id=None):
         if wait_id is None:
-            ids_to_interrupt = list(self.wait_ids.keys())
+            matching_ids = list(self.wait_ids.keys())
         elif wait_id in self.wait_ids:
-            ids_to_interrupt = [wait_id]
+            matching_ids = [wait_id]
         else:
-            ids_to_interrupt = []
+            matching_ids = []
+        return matching_ids
 
-        for _wait_id in ids_to_interrupt:
+    def interrupt_wait(self, wait_id=None):
+        for _wait_id in self.matching_wait_ids(wait_id=wait_id):
             action_or_waits = self.wait_ids[_wait_id]
             del(self.wait_ids[_wait_id])
             for action_or_wait in action_or_waits:
@@ -223,6 +223,27 @@ class Mapping(RelativeLayout):
                 else:
                     action_or_wait.set()
 
+    def pause_wait(self, wait_id=None):
+        for _wait_id in self.matching_wait_ids(wait_id=wait_id):
+            action_or_waits = self.wait_ids[_wait_id]
+            for action_or_wait in action_or_waits:
+                if isinstance(action_or_wait, Action):
+                    action_or_wait.pause()
+
+    def unpause_wait(self, wait_id=None):
+        for _wait_id in self.matching_wait_ids(wait_id=wait_id):
+            action_or_waits = self.wait_ids[_wait_id]
+            for action_or_wait in action_or_waits:
+                if isinstance(action_or_wait, Action):
+                    action_or_wait.unpause()
+
+    def reset_wait(self, wait_id=None):
+        for _wait_id in self.matching_wait_ids(wait_id=wait_id):
+            action_or_waits = self.wait_ids[_wait_id]
+            for action_or_wait in action_or_waits:
+                if isinstance(action_or_wait, Action):
+                    action_or_wait.reset()
+
     # Methods to control running keys
     def start_running(self, key, start_time):
         self.running.append((key, start_time))
@@ -327,13 +348,11 @@ class Mapping(RelativeLayout):
         try:
             config = yaml.safe_load(stream)
         except Exception as e:
-            error_print("Error while loading config file: {}".format(e),
-                    exit=True)
+            raise Exception("Error while loading config file: {}".format(e)) from e
         stream.close()
 
         if not isinstance(config, dict):
-            error_print("Top level config is supposed to be a hash",
-                    exit=True)
+            raise Exception("Top level config is supposed to be a hash")
 
         if 'aliases' in config and isinstance(config['aliases'], dict):
             aliases = config['aliases']