Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: fallback to dummy audio backend if the real audio backend fails. #244

Merged
merged 1 commit into from
Oct 19, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 43 additions & 3 deletions framework_crates/bones_framework/src/render/audio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ use crate::prelude::*;

pub use kira::{self, sound::static_sound::StaticSoundData};
use kira::{
manager::{backend::cpal::CpalBackend, AudioManager as KiraAudioManager},
manager::{
backend::{cpal::CpalBackend, mock::MockBackend, Backend},
AudioManager as KiraAudioManager,
},
sound::SoundData,
};

Expand All @@ -20,10 +23,47 @@ pub fn game_plugin(game: &mut Game) {
/// The audio manager resource which can be used to play sounds.
#[derive(HasSchema, Deref, DerefMut)]
#[schema(no_clone)]
pub struct AudioManager(KiraAudioManager);
pub struct AudioManager(KiraAudioManager<CpalWithFallbackBackend>);
impl Default for AudioManager {
fn default() -> Self {
Self(KiraAudioManager::<CpalBackend>::new(default()).unwrap())
Self(KiraAudioManager::<CpalWithFallbackBackend>::new(default()).unwrap())
}
}

/// Kira audio backend that will fall back to a dummy backend if setting up the Cpal backend
/// fails with an error.
#[allow(clippy::large_enum_variant)]
pub enum CpalWithFallbackBackend {
/// This is a working Cpal backend.
Cpal(CpalBackend),
/// This is a dummy backend since Cpal didn't work.
Dummy(MockBackend),
}

impl Backend for CpalWithFallbackBackend {
type Settings = <CpalBackend as Backend>::Settings;
type Error = <CpalBackend as Backend>::Error;

fn setup(settings: Self::Settings) -> Result<(Self, u32), Self::Error> {
match CpalBackend::setup(settings) {
Ok((back, bit)) => Ok((Self::Cpal(back), bit)),
Err(e) => {
tracing::error!("Error starting audio backend, using dummy backend instead: {e}");
Ok(MockBackend::setup(default())
.map(|(back, bit)| (Self::Dummy(back), bit))
.unwrap())
}
}
}

fn start(&mut self, renderer: kira::manager::backend::Renderer) -> Result<(), Self::Error> {
match self {
CpalWithFallbackBackend::Cpal(cpal) => cpal.start(renderer),
CpalWithFallbackBackend::Dummy(dummy) => {
dummy.start(renderer).unwrap();
Ok(())
}
}
}
}

Expand Down
Loading