ppb/pursuedpybear

Occasional SdlMixerError for keyboard_and_mouse_controls example

Opened this issue · 5 comments

When running the keyboard_and_mouse_controls example, I almost always get an error saying that the Mixer audio device hasn't been opened. Here's the full traceback:

ahurst@d420:~/downloads/pursuedpybear/examples/keyboard_and_mouse_controls$ python3 targets.py
UserWarning: Using SDL2 binaries from pysdl2-dll 2.0.14
INFO:ppb.engine:Entering context
DEBUG:ppb.vfs:Opening laser1.ogg (__main__, laser1.ogg)
DEBUG:ppb.vfs:Opening target.png (__main__, target.png)
DEBUG:ppb.vfs:Opening target.png (__main__, target.png)
DEBUG:ppb.vfs:Opening target.png (__main__, target.png)
DEBUG:ppb.vfs:Opening target.png (__main__, target.png)
DEBUG:ppb.vfs:Opening player.png (__main__, player.png)
DEBUG:ppb.vfs:Opening target.png (__main__, target.png)
INFO:ppb.engine:Exiting context
Traceback (most recent call last):
  File "targets.py", line 90, in <module>
    log_level=logging.DEBUG,
  File "/home/ahurst/.local/lib/python3.7/site-packages/ppb/__init__.py", line 125, in run
    eng.run()
  File "/home/ahurst/.local/lib/python3.7/site-packages/ppb/engine.py", line 316, in run
    self.main_loop()
  File "/home/ahurst/.local/lib/python3.7/site-packages/ppb/engine.py", line 345, in main_loop
    self.loop_once()
  File "/home/ahurst/.local/lib/python3.7/site-packages/ppb/engine.py", line 361, in loop_once
    self.publish()
  File "/home/ahurst/.local/lib/python3.7/site-packages/ppb/engine.py", line 387, in publish
    method(event, self.signal)
  File "/home/ahurst/.local/lib/python3.7/site-packages/ppb/systems/sound.py", line 117, in on_play_sound
    chunk = event.sound.load()
  File "/home/ahurst/.local/lib/python3.7/site-packages/ppb/assetlib.py", line 221, in load
    return self._future.result(timeout)
  File "/usr/lib/python3.7/concurrent/futures/_base.py", line 425, in result
    return self.__get_result()
  File "/usr/lib/python3.7/concurrent/futures/_base.py", line 384, in __get_result
    raise self._exception
  File "/usr/lib/python3.7/concurrent/futures/thread.py", line 57, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/home/ahurst/.local/lib/python3.7/site-packages/ppb/assetlib.py", line 304, in _background
    return self.background_parse(raw)
  File "/home/ahurst/.local/lib/python3.7/site-packages/ppb/systems/sound.py", line 35, in background_parse
    _check_error=lambda rv: not rv
  File "/home/ahurst/.local/lib/python3.7/site-packages/ppb/systems/sdl_utils.py", line 94, in mix_call
    raise SdlMixerError(f"Error calling {func.__name__}: {err.decode('utf-8')}")
ppb.systems.sdl_utils.SdlMixerError: Error calling Mix_LoadWAV_RW: Audio device hasn't been opened

However, on one of my 4 attempts to run the demo, it loaded and seemed to work as expected, which probably means there's a race condition of some sort.

This should be an invariant of assetlib: The assets won't begin loading until the systems have initialized and __enter__()'d.

And, of course, this goes away if you add any debugging.

well that's exciting. I just got the error, even though it absolutely has.

🐚 python examples/keyboard_and_mouse_controls/targets.py                                                            canon
INFO:ppb.engine:Entering context
(1, c_int(44100), c_ushort(32784), c_int(2))
DEBUG:ppb.vfs:Opening laser1.ogg (__main__, laser1.ogg)
DEBUG:ppb.vfs:Opening target.png (__main__, target.png)
DEBUG:ppb.vfs:Opening player.png (__main__, player.png)
DEBUG:ppb.vfs:Opening target.png (__main__, target.png)
DEBUG:ppb.vfs:Opening target.png (__main__, target.png)
DEBUG:ppb.vfs:Opening target.png (__main__, target.png)
DEBUG:ppb.vfs:Opening target.png (__main__, target.png)
INFO:ppb.engine:Exiting context
Traceback (most recent call last):
  File "/home/astraluma/code/ppb/pursuedpybear/examples/keyboard_and_mouse_controls/targets.py", line 88, in <module>
    ppb.run(
  File "/home/astraluma/code/ppb/pursuedpybear/ppb/__init__.py", line 125, in run
    eng.run()
  File "/home/astraluma/code/ppb/pursuedpybear/ppb/engine.py", line 323, in run
    self.main_loop()
  File "/home/astraluma/code/ppb/pursuedpybear/ppb/engine.py", line 352, in main_loop
    self.loop_once()
  File "/home/astraluma/code/ppb/pursuedpybear/ppb/engine.py", line 368, in loop_once
    self.publish()
  File "/home/astraluma/code/ppb/pursuedpybear/ppb/engine.py", line 394, in publish
    method(event, self.signal)
  File "/home/astraluma/code/ppb/pursuedpybear/ppb/systems/sound.py", line 135, in on_play_sound
    chunk = event.sound.load()
  File "/home/astraluma/code/ppb/pursuedpybear/ppb/assetlib.py", line 221, in load
    return self._future.result(timeout)
  File "/usr/lib/python3.9/concurrent/futures/_base.py", line 433, in result
    return self.__get_result()
  File "/usr/lib/python3.9/concurrent/futures/_base.py", line 389, in __get_result
    raise self._exception
  File "/usr/lib/python3.9/concurrent/futures/thread.py", line 52, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/home/astraluma/code/ppb/pursuedpybear/ppb/assetlib.py", line 304, in _background
    return self.background_parse(raw)
  File "/home/astraluma/code/ppb/pursuedpybear/ppb/systems/sound.py", line 34, in background_parse
    return mix_call(
  File "/home/astraluma/code/ppb/pursuedpybear/ppb/systems/sdl_utils.py", line 94, in mix_call
    raise SdlMixerError(f"Error calling {func.__name__}: {err.decode('utf-8')}")
ppb.systems.sdl_utils.SdlMixerError: Error calling Mix_LoadWAV_RW: Audio device hasn't been opened

ah, there we go

INFO:ppb.engine:Entering context
DEBUG:ppb.vfs:Opening laser1.ogg (__main__, laser1.ogg)
DEBUG:ppb.vfs:Opening target.png (__main__, target.png)
DEBUG:ppb.vfs:Opening target.png (__main__, target.png)
Sound (0, c_int(0), c_ushort(0), c_int(0))
SoundController (1, c_int(44100), c_ushort(32784), c_int(2))
DEBUG:ppb.vfs:Opening player.png (__main__, player.png)
DEBUG:ppb.vfs:Opening target.png (__main__, target.png)
DEBUG:ppb.vfs:Opening target.png (__main__, target.png)
DEBUG:ppb.vfs:Opening target.png (__main__, target.png)
INFO:ppb.engine:Exiting context
Traceback (most recent call last):
  File "/home/astraluma/code/ppb/pursuedpybear/examples/keyboard_and_mouse_controls/targets.py", line 88, in <module>
    ppb.run(
  File "/home/astraluma/code/ppb/pursuedpybear/ppb/__init__.py", line 125, in run
    eng.run()
  File "/home/astraluma/code/ppb/pursuedpybear/ppb/engine.py", line 323, in run
    self.main_loop()
  File "/home/astraluma/code/ppb/pursuedpybear/ppb/engine.py", line 352, in main_loop
    self.loop_once()
  File "/home/astraluma/code/ppb/pursuedpybear/ppb/engine.py", line 368, in loop_once
    self.publish()
  File "/home/astraluma/code/ppb/pursuedpybear/ppb/engine.py", line 394, in publish
    method(event, self.signal)
  File "/home/astraluma/code/ppb/pursuedpybear/ppb/systems/sound.py", line 138, in on_play_sound
    chunk = event.sound.load()
  File "/home/astraluma/code/ppb/pursuedpybear/ppb/assetlib.py", line 221, in load
    return self._future.result(timeout)
  File "/usr/lib/python3.9/concurrent/futures/_base.py", line 433, in result
    return self.__get_result()
  File "/usr/lib/python3.9/concurrent/futures/_base.py", line 389, in __get_result
    raise self._exception
  File "/usr/lib/python3.9/concurrent/futures/thread.py", line 52, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/home/astraluma/code/ppb/pursuedpybear/ppb/assetlib.py", line 304, in _background
    return self.background_parse(raw)
  File "/home/astraluma/code/ppb/pursuedpybear/ppb/systems/sound.py", line 37, in background_parse
    return mix_call(
  File "/home/astraluma/code/ppb/pursuedpybear/ppb/systems/sdl_utils.py", line 94, in mix_call
    raise SdlMixerError(f"Error calling {func.__name__}: {err.decode('utf-8')}")
ppb.systems.sdl_utils.SdlMixerError: Error calling Mix_LoadWAV_RW: Audio device hasn't been opened

So yes, we are breaking the invariant that systems are initialized before assets begin loading.