ya2 · news · projects · code · about

housekeeping: pmachines.audio.music
authorFlavio Calva <f.calva@gmail.com>
Sat, 7 Jan 2023 07:05:10 +0000 (09:05 +0200)
committerFlavio Calva <f.calva@gmail.com>
Thu, 5 Jan 2023 15:36:21 +0000 (16:36 +0100)
pmachines/application/application.py
pmachines/audio/music.py
tests/pmachines/__init__.py [new file with mode: 0644]
tests/pmachines/audio/__init__.py [new file with mode: 0644]
tests/pmachines/audio/test_music.py [new file with mode: 0644]
tests/ya2/utils/test_audio.py [new file with mode: 0644]
ya2/utils/audio.py [new file with mode: 0644]

index b54c41d1531712b345ca4d384d823920f22dd14a..f6cb6a35483f3907a1a4ad634daf44fd872fa4ad 100755 (executable)
@@ -14,7 +14,7 @@ from panda3d.bullet import BulletWorld, BulletDebugNode
 from direct.showbase.ShowBase import ShowBase
 from direct.gui.OnscreenText import OnscreenText
 from direct.fsm.FSM import FSM
-from pmachines.audio.music import MusicMgr
+from pmachines.audio.music import MusicManager
 from pmachines.items.background import Background
 from pmachines.gui.menu import Menu
 from pmachines.scene.scene import Scene
@@ -95,7 +95,7 @@ class Pmachines:
             return
         if args.functional_test:
             self._options['settings']['volume'] = 0
-        self._music = MusicMgr(self._options['settings']['volume'])
+        self._music = MusicManager(self._options['settings']['volume'], 'pmachines')
         self.lang_mgr = LanguageManager(self._options['settings']['language'],
                                 'pmachines',
                                 'assets/locale/')
index 47779a2dcd695bf96a8323ce00f94a13c2b896b3..e0d18bb69c66650f14f25fdbc7a652498b9daf3f 100644 (file)
@@ -1,58 +1,36 @@
-from os.path import exists, basename
-from platform import system
+from os.path import basename
 from glob import glob
-from pathlib import Path
 from random import choice
 from logging import info
 from panda3d.core import AudioSound, Filename
+from ya2.utils.audio import AudioTools
+from ya2.utils.logics import LogicsTools
 
 
-class MusicMgr:
+class MusicManager:
 
-    def __init__(self, volume):
-        files = self.curr_path + 'assets/audio/music/*.ogg'
-        self._start_music(glob(files))
-        base.musicManager.setVolume(.8 * volume)
-        base.sfxManagerList[0].setVolume(volume)
-        taskMgr.add(self._on_frame, 'on frame music')
+    def __init__(self, volume, app_name):
+        self.__current_path = LogicsTools.current_path(app_name)
+        musics = self.__current_path + 'assets/audio/music/*.ogg'
+        self.__start_music(glob(musics))
+        AudioTools.set_volume(volume)
+        taskMgr.add(self.__on_frame, 'on frame music')
 
-    @property
-    def is_appimage(self):
-        par_path = str(Path(__file__).parent.absolute())
-        is_appimage = par_path.startswith('/tmp/.mount_Pmachi')
-        return is_appimage and par_path.endswith('/usr/bin')
+    def __start_music(self, file_names):
+        self.__music = loader.load_music(choice(file_names))
+        info('playing music ' + self.__music.get_name())
+        self.__music.play()
 
-    @property
-    def curr_path(self):
-        if system() == 'Windows':
-            return ''
-        if exists('main.py'):
-            return ''
-        else:
-            par_path = str(Path(__file__).parent.absolute())
-        if self.is_appimage:
-            par_path = str(Path(par_path).absolute())
-        par_path += '/'
-        return par_path
-
-    def _start_music(self, files):
-        self._music = loader.load_music(choice(files))
-        info('playing music ' + self._music.get_name())
-        self._music.play()
-
-    def set_volume(self, volume):
-        base.musicManager.setVolume(.8 * volume)
-        base.sfxManagerList[0].setVolume(volume)
-
-    def _on_frame(self, task):
-        if self._music.status() == AudioSound.READY:
-            oggs = Filename(
-                self.curr_path + 'assets/audio/music/*.ogg').to_os_specific()
-            files = glob(oggs)
-            rm_music = Filename(
-                self.curr_path + 'assets/audio/music/' +
-                basename(self._music.get_name())).to_os_specific()
-            # basename is needed in windows
-            files.remove(rm_music)
-            self._start_music(files)
+    def __on_frame(self, task):
+        if self.__music.status() == AudioSound.READY: self.__restart_music()
         return task.cont
+
+    def __restart_music(self):
+        ogg_files = Filename(self.__current_path + 'assets/audio/music/*.ogg').to_os_specific()
+        file_names = glob(ogg_files)
+        music_to_remove = Filename(
+            self.__current_path + 'assets/audio/music/' +
+            basename(self.__music.get_name())).to_os_specific()
+        # basename is needed in windows
+        file_names.remove(music_to_remove)
+        self.__start_music(file_names)
diff --git a/tests/pmachines/__init__.py b/tests/pmachines/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/pmachines/audio/__init__.py b/tests/pmachines/audio/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/pmachines/audio/test_music.py b/tests/pmachines/audio/test_music.py
new file mode 100644 (file)
index 0000000..38abcd6
--- /dev/null
@@ -0,0 +1,43 @@
+from panda3d.core import load_prc_file_data
+load_prc_file_data('', 'window-type none')
+from pathlib import Path
+import sys
+if '' in sys.path: sys.path.remove('')
+sys.path.append(str(Path(__file__).parent.parent.parent))
+from os.path import basename
+from glob import glob
+from unittest import TestCase
+from unittest.mock import patch
+from direct.showbase.ShowBase import ShowBase
+from panda3d.core import AudioSound
+from pmachines.audio.music import MusicManager
+from pmachines.audio import music
+
+
+class MusicTests(TestCase):
+
+    def setUp(self):
+        self.__app = ShowBase()
+
+    def tearDown(self):
+        self.__app.destroy()
+
+    @patch.object(music, 'AudioTools', autospec=True)
+    def test_music(self, a):
+        m = MusicManager(.8, 'pmachines')
+        a.set_volume.assert_called_once()
+        a_args = a.set_volume.call_args_list[0].args
+        self.assertAlmostEqual(a_args[0], .8, delta=.01)
+        self.assertEqual(len(a_args), 1)
+        tasks = [t.name for t in taskMgr.getTasks() + taskMgr.getDoLaters()]
+        self.assertIn('on frame music', tasks)
+        _music = m._MusicManager__music
+        musics = list(map(basename, glob('assets/audio/music/*.ogg')))
+        self.assertIn(_music.get_name(), musics)
+        self.assertEqual(_music.status(), AudioSound.PLAYING)
+        prev_music_name = _music.get_name()
+        m._MusicManager__restart_music()
+        _music = m._MusicManager__music
+        self.assertIn(_music.get_name(), musics)
+        self.assertEqual(_music.status(), AudioSound.PLAYING)
+        self.assertNotEqual(_music.get_name(), prev_music_name)
diff --git a/tests/ya2/utils/test_audio.py b/tests/ya2/utils/test_audio.py
new file mode 100644 (file)
index 0000000..66a8c83
--- /dev/null
@@ -0,0 +1,32 @@
+from panda3d.core import load_prc_file_data
+load_prc_file_data('', 'window-type none')
+from pathlib import Path
+import sys
+if '' in sys.path: sys.path.remove('')
+sys.path.append(str(Path(__file__).parent.parent.parent))
+from unittest import TestCase
+from unittest.mock import patch
+from direct.showbase.ShowBase import ShowBase
+from ya2.utils.audio import AudioTools
+
+
+class AudioTests(TestCase):
+
+    def setUp(self):
+        self.__app = ShowBase()
+
+    def tearDown(self):
+        self.__app.destroy()
+
+    def test_audio(self):
+        with (patch.object(base, 'musicManager', autospec=True) as m,
+              patch.object(base, 'sfxManagerList', autospec=True) as s):
+            AudioTools.set_volume(.8)
+            m.set_volume.assert_called_once()
+            m_args = m.set_volume.call_args_list[0].args
+            self.assertAlmostEqual(m_args[0], .64, delta=.01)
+            self.assertEqual(len(m_args), 1)
+            s[0].set_volume.assert_called_once()
+            s_args = s[0].set_volume.call_args_list[0].args
+            self.assertAlmostEqual(s_args[0], .8, delta=.01)
+            self.assertEqual(len(s_args), 1)
diff --git a/ya2/utils/audio.py b/ya2/utils/audio.py
new file mode 100644 (file)
index 0000000..10b2dd0
--- /dev/null
@@ -0,0 +1,6 @@
+class AudioTools:
+
+    @staticmethod
+    def set_volume(volume):
+        base.musicManager.set_volume(.8 * volume)
+        base.sfxManagerList[0].set_volume(volume)