From 0e97981f8418c08f04f316e2b7e0c7dbe8c7ef42 Mon Sep 17 00:00:00 2001 From: kampffrosch94 Date: Sat, 17 May 2025 17:24:50 +0200 Subject: [PATCH] audio with fine grained global context --- src/audio.rs | 67 ++++++++++++++++++++++++++++++++++------------------ src/lib.rs | 6 ++--- 2 files changed, 46 insertions(+), 27 deletions(-) diff --git a/src/audio.rs b/src/audio.rs index 3885bbf8..901927c0 100644 --- a/src/audio.rs +++ b/src/audio.rs @@ -2,8 +2,8 @@ #![allow(dead_code)] -use crate::{file::load_file, get_context, Error}; -use std::sync::Arc; +use crate::{file::load_file, Error}; +use std::{cell::RefCell, sync::Arc}; #[cfg(feature = "audio")] use quad_snd::{AudioContext as QuadSndContext, Sound as QuadSndSound}; @@ -88,8 +88,9 @@ struct QuadSndSoundGuarded(QuadSndSound); impl Drop for QuadSndSoundGuarded { fn drop(&mut self) { - let ctx = &get_context().audio_context; - self.0.delete(&ctx.native_ctx); + with_audio_context(|ctx| { + self.0.delete(ctx); + }); } } @@ -116,10 +117,7 @@ pub async fn load_sound(path: &str) -> Result { /// /// Attempts to automatically detect the format of the source of data. pub async fn load_sound_from_bytes(data: &[u8]) -> Result { - let sound = { - let ctx = &mut get_context().audio_context; - QuadSndSound::load(&mut ctx.native_ctx, data) - }; + let sound = with_audio_context(|ctx| QuadSndSound::load(ctx, data)); // only on wasm the sound is not ready right away #[cfg(target_arch = "wasm32")] @@ -130,29 +128,52 @@ pub async fn load_sound_from_bytes(data: &[u8]) -> Result { Ok(Sound(Arc::new(QuadSndSoundGuarded(sound)))) } +thread_local! { + static AUDIO_CONTEXT: RefCell> = RefCell::new(None); +} + +pub(crate) fn init_sound() { + AUDIO_CONTEXT.with_borrow_mut(|opt| *opt = Some(QuadSndContext::new())); +} + +fn with_audio_context(f: F) -> R +where + F: FnOnce(&mut QuadSndContext) -> R, +{ + AUDIO_CONTEXT.with_borrow_mut(|opt| { + let ctx = opt + .as_mut() + .expect("the macroquad audiocontext is not initialized on current thread"); + f(ctx) + }) +} + pub fn play_sound_once(sound: &Sound) { - let ctx = &mut get_context().audio_context; - - sound.0 .0.play( - &mut ctx.native_ctx, - PlaySoundParams { - looped: false, - volume: 1.0, - }, - ); + with_audio_context(|ctx| { + sound.0 .0.play( + ctx, + PlaySoundParams { + looped: false, + volume: 1.0, + }, + ); + }); } pub fn play_sound(sound: &Sound, params: PlaySoundParams) { - let ctx = &mut get_context().audio_context; - sound.0 .0.play(&mut ctx.native_ctx, params); + with_audio_context(|ctx| { + sound.0 .0.play(ctx, params); + }); } pub fn stop_sound(sound: &Sound) { - let ctx = &mut get_context().audio_context; - sound.0 .0.stop(&mut ctx.native_ctx); + with_audio_context(|ctx| { + sound.0 .0.stop(ctx); + }); } pub fn set_sound_volume(sound: &Sound, volume: f32) { - let ctx = &mut get_context().audio_context; - sound.0 .0.set_volume(&mut ctx.native_ctx, volume); + with_audio_context(|ctx| { + sound.0 .0.set_volume(ctx, volume); + }); } diff --git a/src/lib.rs b/src/lib.rs index 23b6ae8b..5ead5c67 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -36,6 +36,7 @@ //! } //!``` +use audio::init_sound; use miniquad::*; use std::collections::{HashMap, HashSet}; @@ -175,8 +176,6 @@ pub(crate) mod thread_assert { } } struct Context { - audio_context: audio::AudioContext, - screen_width: f32, screen_height: f32, @@ -354,9 +353,7 @@ impl Context { texture_batcher: texture::Batcher::new(&mut *ctx), camera_stack: vec![], - audio_context: audio::AudioContext::new(), coroutines_context: experimental::coroutines::CoroutinesContext::new(), - pc_assets_folder: None, start_time: miniquad::date::now(), @@ -927,6 +924,7 @@ impl Window { draw_call_index_capacity, ); unsafe { CONTEXT = Some(context) }; + init_sound(); Box::new(Stage { main_future: Box::pin(async {