]> git.immae.eu Git - perso/Immae/Projets/Python/MusicSampler.git/commitdiff
wait actions are now pausable and resettable tags/1.2.3 1.2.3
authorIsmaël Bouya <ismael.bouya@normalesup.org>
Fri, 12 Aug 2016 16:21:22 +0000 (18:21 +0200)
committerIsmaël Bouya <ismael.bouya@normalesup.org>
Fri, 12 Aug 2016 16:23:02 +0000 (18:23 +0200)
This fixes https://git.immae.eu/mantisbt/view.php?id=6

config.yml
documentation_en.md
documentation_fr.md
music_sampler/action.py
music_sampler/actions/__init__.py
music_sampler/actions/pause_wait.py [new file with mode: 0644]
music_sampler/actions/reset_wait.py [new file with mode: 0644]
music_sampler/actions/unpause_wait.py [new file with mode: 0644]
music_sampler/actions/wait.py
music_sampler/locales/fr/LC_MESSAGES/music_sampler.po
music_sampler/mapping.py

index 37e085a87573c78a254df1c7a87213f97234ed33..36c804b01cddca59a820a7e3b6dc5c93817b3918 100644 (file)
@@ -75,6 +75,8 @@ music_properties:
 key_properties:
   'common':
     repeat_delay: 1
+    include: blue
+
   'a':
     description:
       -  
@@ -145,6 +147,11 @@ key_properties:
       - Low vol
       - Up vol
     include: green
+  'ù':
+    description:
+      - 
+      - stop
+      - wait
 
   'home':
     description:
@@ -160,18 +167,21 @@ key_properties:
       - "!"
       - STOP!
     include: red
+    repeat_delay: 0
 
   'F5':
     description:
       - "||"
       - PAUSE
     include: light_green
+    repeat_delay: 0
 
   'F6':
     description:
       - ">"
       - UNPAUSE
     include: light_green
+    repeat_delay: 0
 
   'F1':
     description:
@@ -179,6 +189,7 @@ key_properties:
       - Stop
       - fade
     include: orange
+    repeat_delay: 0
 
   'F2':
     description:
@@ -186,6 +197,7 @@ key_properties:
       - Stop
       - actions
     include: orange
+    repeat_delay: 0
 
   'F4':
     description:
@@ -193,30 +205,51 @@ key_properties:
       - Skip
       - wait
     include: pink
+    repeat_delay: 0
+
+  'F8':
+    description:
+      - 
+      - Pause
+      - wait
+  'F9':
+    description:
+      - 
+      - Unpause
+      - wait
+  'F10':
+    description:
+      - 
+      - Reset
+      - wait
 
   'F12':
     description:
       - 
       - vol+
     include: yellow
+    repeat_delay: 0
 
   'F11':
     description:
       - 
       - "vol-"
     include: yellow
+    repeat_delay: 0
 
   'right':
     description:
       - 
       - +10s
     include: blue
+    repeat_delay: 0
 
   'left':
     description:
       - 
       - -10s
     include: blue
+    repeat_delay: 0
 
 #################################################################
 ##### Keys: what do the key actually do when you press them #####
@@ -246,10 +279,8 @@ keys:
     - stop: 
         fade_out: 3
         wait: true
-        set_wait_id: y1
     - wait:
         duration: 3
-        set_wait_id: y2
     - play: 
         include: music2
 
@@ -263,7 +294,6 @@ keys:
         include: music1
     - wait:
         duration: 3
-        set_wait_id: u
     - play: 
         include: music2
 
@@ -274,7 +304,6 @@ keys:
         start_at: 30
     - wait: 
         duration: 5
-        set_wait_id: g
     - seek:
         include: music1
         delta: false
@@ -293,6 +322,11 @@ keys:
     - play:
         include: music2
 
+# skip waiting for the end of music1
+  'ù':
+    - interrupt_wait:
+        wait_id: m
+
 # Lowers the volume of music 1 and 2 (if playing), during the duration of noise + 1 second
   'i':
     - volume:
@@ -306,7 +340,6 @@ keys:
     - wait:
         include: noise
         duration: 1
-        set_wait_id: i
     - volume:
         include: music1
         value: 100
@@ -328,7 +361,6 @@ keys:
         fade: 5
     - wait:
         duration: 5
-        set_wait_id: n
     - volume:
         include: music1
         value: 100
@@ -381,20 +413,15 @@ keys:
 # Skip wait
   'F4':
     - interrupt_wait:
-        wait_id: n
-    - interrupt_wait:
-        wait_id: m
-    - interrupt_wait:
-        wait_id: i
-    - interrupt_wait:
-        wait_id: y1
-    - interrupt_wait:
-        wait_id: y2
-    - interrupt_wait:
-        wait_id: u
-    - interrupt_wait:
-        wait_id: g
 
+  'F8':
+    - pause_wait:
+
+  'F9':
+    - unpause_wait:
+
+  'F10':
+    - reset_wait:
 
 # Changing volume
   'F12':
index 899ef1ad77ba8eda0fc58a8073fe0ca30dc652b5..e92b85c60d69a53cd489336c9fb0dae722440749 100644 (file)
@@ -386,9 +386,22 @@ actions.
       action. When false, it is thus useless to add actions after that one.
 - `interrupt_wait`: stop a wait event (normal `wait` or fade out wait). The keys
   that were waiting will move to the next actions. Parameters:
-    * `wait_id: name` (optional) gives the id of the `wait` to interrupt (defined with
-      `set_wait_id`, see actions `wait` and `stop`). If not given, interrupts
-      all wait events.
+    * `wait_id: name` (optional) gives the id of the `wait` to interrupt
+      (defined with `set_wait_id`, see actions `wait` and `stop`). If not given,
+      interrupts all wait events.
+- `pause_wait`: pauses a wait event (only for a wait with duration). The key
+  that were waiting will keep waiting until the `wait` is unpaused. Parameters:
+    * `wait_id: name` (optional) gives the id of the `wait` to pause. If not
+      given, pauses all compatible wait events.
+- `unpause_wait`: unpauses a paused wait event (only a wait with duration). The
+  countdown will resume for the corresponding keys. Parameters:
+    * `wait_id: name` (optional) gives the id of the `wait` to unpause. If not
+      given, unpauses all compatible wait events.
+- `reset_wait`: resets a wait counter (only a wait with duration). If the wait
+  was paused, it will stay paused and start at the beginning once it is
+  unpaused. Parameters:
+    * `wait_id: name` (optional) gives the id of the `wait` to reset. If not
+      given, resets all compatible wait events.
 - `run_command` : Run a command. Parameters:
     * `command: my_command` : Gives the command to run.
     * `wait: true/false` (optional, default false) if true, waits for the
index ff3cfe81cd4139dbbdca0bb5a86c201a5c355a26..cc2bf8f115a9ec2d3fad53437fff5ba2ad6ac627 100644 (file)
@@ -435,6 +435,21 @@ successivement mais sans attendre (donc presque simultanément) : ne pas hésite
     * `wait_id: name` (facultatif) précise l'identifiant du `wait` à stopper
       (défini par `set_wait_id`, voir les actions `wait` et `stop`). Si absent,
       interrompt toutes les attentes.
+- `pause_wait`: met une attente en pause (uniquement pour une attente ayant une
+  durée définie). La touche qui attend cet événement ne continuera pas tant que
+  l'attente n'est pas reprise. Paramètres :
+    * `wait_id: name` (facultatif) précise l'identifiant du `wait` à mettre en
+      pause. Si absent, met en pause toutes les attentes compatibles.
+- `unpause_wait`: reprend une attente en pause (uniquement pour une attente
+  ayant une durée définie). Le compte à rebours reprendra pour la touche
+  correspondante en train d'attendre. Paramètres:
+    * `wait_id: name` (facultatif) précise l'identifiant du `wait` à reprendre.
+      Si absent, reprend toutes les attentes compatibles.
+- `reset_wait`: réinitialise une attente (uniquement pour une attente ayant une
+  durée définie). Si l'attente est en pause, le compte à rebours ne recommencera
+  au début que lorsque l'attente sera reprise. Paramètres:
+    * `wait_id: name` (facultatif) précise l'identifiant du `wait` à
+      réinitialiser. Si absent, réinitialise toutes les attentes compatibles.
 - `run_command` : lance une commande. Paramètres :
     * `command: my_command` : précise la commande à lancer.
     * `wait: true/false` (facultatif, défaut : false) : si `wait` est true,
index d269d0e4dd3749e06edacb5e5e9c2e27881a8d65..22a2bdc9feeb3231fa8a9c80f7b7d72f02c0d71a 100644 (file)
@@ -98,6 +98,24 @@ class Action:
             return getattr(getattr(actions, self.action), 'interrupt')(
                     self, **self.arguments)
 
+    def pause(self):
+        if getattr(actions, self.action, None) and\
+                hasattr(getattr(actions, self.action), 'pause'):
+            return getattr(getattr(actions, self.action), 'pause')(
+                    self, **self.arguments)
+
+    def unpause(self):
+        if getattr(actions, self.action, None) and\
+                hasattr(getattr(actions, self.action), 'unpause'):
+            return getattr(getattr(actions, self.action), 'unpause')(
+                    self, **self.arguments)
+
+    def reset(self):
+        if getattr(actions, self.action, None) and\
+                hasattr(getattr(actions, self.action), 'reset'):
+            return getattr(getattr(actions, self.action), 'reset')(
+                    self, **self.arguments)
+
     # Helpers
     def music_list(self, music):
         if music is not None:
index 658cef0883f5939637a8f3a0b2652acfeb682c59..7c812cb7097d70e3d69ba2bf1831e52a5d48e090 100644 (file)
@@ -1,10 +1,13 @@
 from . import interrupt_wait
 from . import pause
+from . import pause_wait
 from . import play
+from . import reset_wait
 from . import run_command
 from . import seek
 from . import stop
 from . import stop_all_actions
 from . import unpause
+from . import unpause_wait
 from . import volume
 from . import wait
diff --git a/music_sampler/actions/pause_wait.py b/music_sampler/actions/pause_wait.py
new file mode 100644 (file)
index 0000000..e4ab6ea
--- /dev/null
@@ -0,0 +1,8 @@
+def run(action, wait_id=None, **kwargs):
+    action.mapping.pause_wait(wait_id)
+
+def description(action, wait_id=None, **kwargs):
+    if wait_id is None:
+        return _("pause all waits")
+    else:
+        return _("pause wait with id {}").format(wait_id)
diff --git a/music_sampler/actions/reset_wait.py b/music_sampler/actions/reset_wait.py
new file mode 100644 (file)
index 0000000..500bcca
--- /dev/null
@@ -0,0 +1,8 @@
+def run(action, wait_id=None, **kwargs):
+    action.mapping.reset_wait(wait_id)
+
+def description(action, wait_id=None, **kwargs):
+    if wait_id is None:
+        return _("reset all waits")
+    else:
+        return _("reset wait with id {}").format(wait_id)
diff --git a/music_sampler/actions/unpause_wait.py b/music_sampler/actions/unpause_wait.py
new file mode 100644 (file)
index 0000000..25e9a11
--- /dev/null
@@ -0,0 +1,8 @@
+def run(action, wait_id=None, **kwargs):
+    action.mapping.unpause_wait(wait_id)
+
+def description(action, wait_id=None, **kwargs):
+    if wait_id is None:
+        return _("unpause all waits")
+    else:
+        return _("unpause wait with id {}").format(wait_id)
index bcee64941cc93c160b0673612146c2740abecc9a..31439b80bdb2011cf3a51e730d8d62ecb6290e40 100644 (file)
@@ -1,4 +1,5 @@
 import threading
+import time
 
 def run(action, duration=0, music=None, set_wait_id=None, **kwargs):
     action.mapping.add_wait(action, wait_id=set_wait_id)
@@ -8,10 +9,17 @@ def run(action, duration=0, music=None, set_wait_id=None, **kwargs):
             duration,
             action.sleep_event.set)
 
+    action.sleep_event_initial_duration = duration
+    action.sleep_event_paused = False
+    action.sleep_event_left_time = duration
+
     if music is not None:
         music.wait_end()
 
-    action.sleep_event_timer.start()
+    if duration <= 0 or not action.sleep_event_paused:
+        action.sleep_event_timer.start()
+        action.sleep_event_started_time = time.time()
+
     action.sleep_event.wait()
 
 def description(action, duration=0, music=None, set_wait_id=None, **kwargs):
@@ -34,6 +42,50 @@ def description(action, duration=0, music=None, set_wait_id=None, **kwargs):
 
     return _(message).format(*formats)
 
+def pause(action, **kwargs):
+    if action.sleep_event_paused:
+        return
+
+    action.sleep_event_paused = True
+
+    if not action.sleep_event_timer.is_alive():
+        return
+
+    action.sleep_event_timer.cancel()
+
+    action.sleep_event_left_time = action.sleep_event_left_time\
+            - (time.time() - action.sleep_event_started_time)
+    if action.sleep_event_left_time < 0:
+        action.sleep_event.set()
+
+def unpause(action, **kwargs):
+    if not action.sleep_event_paused:
+        return
+
+    action.sleep_event_paused = False
+
+    action.sleep_event_timer = threading.Timer(
+            action.sleep_event_left_time,
+            action.sleep_event.set)
+
+    action.sleep_event_timer.start()
+    action.sleep_event_started_time = time.time()
+
+def reset(action, **kwargs):
+    action.sleep_event_timer.cancel()
+
+    action.sleep_event_left_time = action.sleep_event_initial_duration
+
+    if action.sleep_event_paused:
+        return
+
+    action.sleep_event_timer = threading.Timer(
+            action.sleep_event_left_time,
+            action.sleep_event.set)
+
+    action.sleep_event_timer.start()
+    action.sleep_event_started_time = time.time()
+
 def interrupt(action, duration=0, music=None, **kwargs):
     if action.sleep_event is not None:
         action.sleep_event.set()
index 888d7a5e31769c757e273d2cdde98714901c29c1..af27ca91713c4790e8bb3049a07397dccdce7891 100644 (file)
@@ -103,6 +103,14 @@ msgstr "mise en pause de « {} »"
 msgid "pausing all musics"
 msgstr "mise en pause des musiques"
 
+#: music_sampler/actions/pause_wait.py:5
+msgid "pause wait with id {}"
+msgstr "Mettre en pause l'attente d'identifiant {}"
+
+#: music_sampler/actions/pause_wait.py:5
+msgid "pause all waits"
+msgstr "Mettre en pause toutes les attentes"
+
 #: music_sampler/actions/play.py:50
 msgid "starting « {} » at volume {}%"
 msgstr "lance « {} » au volume {}%"
@@ -295,6 +303,14 @@ msgstr "lance « {} » à {}s avec un fondu de {}s au volume {}% en boucle (re
 msgid "starting all musics at {}s with {}s fade_in at volume {}% in loop (restarting if already running)"
 msgstr "lance toutes les musiques à {}s avec un fondu de {}s au volume {}% en boucle (redémarre si déjà lancée)"
 
+#: music_sampler/actions/reset_wait.py:5
+msgid "reset wait with id {}"
+msgstr "Réinitialise l'attente d'identifiant {}"
+
+#: music_sampler/actions/reset_wait.py:5
+msgid "reset all waits"
+msgstr "Réinitialise toutes les attentes"
+
 #: music_sampler/actions/run_command.py:15
 msgid "running command {}"
 msgstr "lance la commande {}"
@@ -367,6 +383,14 @@ msgstr "reprend « {} »"
 msgid "unpausing all musics"
 msgstr "reprend toutes les musiques"
 
+#: music_sampler/actions/unpause_wait.py:5
+msgid "unpause wait with id {}"
+msgstr "Reprendre l'attente d'identifiant {}"
+
+#: music_sampler/actions/unpause_wait.py:5
+msgid "unpause all waits"
+msgstr "Reprendre toutes les attentes"
+
 #: music_sampler/actions/volume.py:32
 msgid "{:+d}% to volume of « {} »"
 msgstr "{:+d}% sur le volume de « {} »"
index 99c99773b7751c213eb2546871fd3d2dfbb9d229..9e40d401852438e410f662cbf6544f70781e5b99 100644 (file)
@@ -206,15 +206,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 +225,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))