From f4d6db2db03246d9d85d8ae70024d17f33a9baa6 Mon Sep 17 00:00:00 2001 From: Hans Kokx Date: Mon, 23 Mar 2026 17:36:49 +0100 Subject: [PATCH] feat: Enhance audio management by implementing shutdown procedures on exit Signed-off-by: Hans Kokx --- apps/wolf_3d_gui/lib/screens/game_screen.dart | 28 ++++++++++++++++++- .../audio/native_subprocess_audio_io.dart | 23 +++++++++++++-- 2 files changed, 48 insertions(+), 3 deletions(-) diff --git a/apps/wolf_3d_gui/lib/screens/game_screen.dart b/apps/wolf_3d_gui/lib/screens/game_screen.dart index cc1ef02..4f7546c 100644 --- a/apps/wolf_3d_gui/lib/screens/game_screen.dart +++ b/apps/wolf_3d_gui/lib/screens/game_screen.dart @@ -143,6 +143,7 @@ class _GameScreenState extends State { DefaultRendererSettingsPersistence(); final DefaultSaveGamePersistence _savePersistence = DefaultSaveGamePersistence(); + Future? _audioShutdownFuture; /// Mirrors [WolfRendererSettings.mode] into the Flutter renderer enum. RendererMode _rendererMode = RendererMode.hardware; @@ -180,7 +181,7 @@ class _GameScreenState extends State { Navigator.of(context).pop(); }, onQuit: () { - SystemNavigator.pop(); + unawaited(_quitApplication()); }, saveGamePersistence: _savePersistence, ); @@ -210,6 +211,31 @@ class _GameScreenState extends State { } } + @override + void dispose() { + unawaited(_shutdownAudioForExit()); + super.dispose(); + } + + Future _quitApplication() async { + await _shutdownAudioForExit(); + await SystemNavigator.pop(); + } + + Future _shutdownAudioForExit() { + final existing = _audioShutdownFuture; + if (existing != null) { + return existing; + } + + final shutdown = () async { + await widget.wolf3d.audio.stopAllAudio(); + widget.wolf3d.audio.dispose(); + }(); + _audioShutdownFuture = shutdown; + return shutdown; + } + @override Widget build(BuildContext context) { return PopScope( diff --git a/packages/wolf_3d_dart/lib/src/engine/audio/native_subprocess_audio_io.dart b/packages/wolf_3d_dart/lib/src/engine/audio/native_subprocess_audio_io.dart index f12a6dd..8098a41 100644 --- a/packages/wolf_3d_dart/lib/src/engine/audio/native_subprocess_audio_io.dart +++ b/packages/wolf_3d_dart/lib/src/engine/audio/native_subprocess_audio_io.dart @@ -21,6 +21,7 @@ class NativeSubprocessAudio implements EngineAudio, DebugMusicPlayer { bool _initialized = false; bool _isSupported = false; + bool _disposed = false; _AudioBackend _backend = _AudioBackend.none; String _windowsShellCommand = 'powershell'; @@ -32,7 +33,7 @@ class NativeSubprocessAudio implements EngineAudio, DebugMusicPlayer { @override Future init() async { - if (_initialized) { + if (_initialized || _disposed) { return; } @@ -49,7 +50,25 @@ class NativeSubprocessAudio implements EngineAudio, DebugMusicPlayer { @override void dispose() { - unawaited(stopAllAudio()); + if (_disposed) { + return; + } + _disposed = true; + + _musicLoopToken++; + _musicProcess?.kill(); + _musicProcess = null; + + for (final process in List.from(_sfxProcesses)) { + process.kill(); + } + _sfxProcesses.clear(); + + final path = _musicTempFilePath; + _musicTempFilePath = null; + if (path != null) { + unawaited(_cleanupTempWav(path)); + } } @override