[FIX] Callback hell of AudioDevice construction while opening audio settings window.

This commit is contained in:
Sheldon Knuth 2019-07-23 09:54:41 +00:00 committed by Joshua Barretto
parent 0091419ace
commit c2fa8bd615
3 changed files with 46 additions and 59 deletions

View File

@ -230,13 +230,18 @@ impl Jukebox {
}
}
pub struct AudioDevice {
struct MonoEmitter {
device: Device,
devices: Vec<Device>,
stream: Sink,
}
impl AudioDevice {
pub(crate) fn new(settings: &AudioSettings) -> Self {
// struct StereoEmitter {
// device: Device,
// stream: SpatialSink,
// }
impl MonoEmitter {
fn new(settings: &AudioSettings) -> Self {
let device = match &settings.audio_device {
Some(dev) => rodio::output_devices()
.find(|x| &x.name() == dev)
@ -244,46 +249,7 @@ impl AudioDevice {
.expect("No Audio devices found!"),
None => rodio::default_output_device().expect("No Audio devices found!"),
};
Self {
device,
devices: list_devices_raw(),
}
}
/// Returns a vec of the audio devices available.
/// Does not return rodio Device struct in case our audio backend changes.
pub(crate) fn list_devices(&self) -> Vec<String> {
self.devices.iter().map(|x| x.name()).collect()
}
/// Caches vec of devices for later reference
// pub(crate) fn update_devices(&mut self) {
// self.devices = list_devices_raw()
// }
/// Returns the name of the current audio device.
/// Does not return rodio Device struct in case our audio backend changes.
pub(crate) fn get_device(&self) -> String {
self.device.name()
}
}
struct MonoEmitter {
device: AudioDevice,
stream: Sink,
}
// struct StereoEmitter {
// device: AudioDevice,
// stream: SpatialSink,
// }
impl MonoEmitter {
fn new(settings: &AudioSettings) -> Self {
let device = AudioDevice::new(settings);
let sink = Sink::new(&device.device);
let sink = Sink::new(&device);
sink.set_volume(settings.music_volume);
Self {
@ -292,6 +258,12 @@ impl MonoEmitter {
}
}
// /// Returns the name of the current audio device.
// /// Does not return rodio Device struct in case our audio backend changes.
// fn get_device(&self) -> String {
// self.device.name()
// }
fn play_from(&mut self, path: &str) {
let bufreader = load_from_path(path).unwrap();
let src = Decoder::new(bufreader).unwrap();
@ -309,16 +281,21 @@ impl AudioConfig for MonoEmitter {
/// If the string is an invalid audio device, then no change is made.
fn set_device(&mut self, name: String) {
if let Some(dev) = rodio::output_devices().find(|x| x.name() == name) {
self.device.device = dev;
self.stream = Sink::new(&self.device.device);
self.device = dev;
self.stream = Sink::new(&self.device);
}
}
}
// impl StereoEmitter {
// fn new(settings: &AudioSettings) -> Self {
// let device = AudioDevice::new(settings);
// let device = match &settings.audio_device {
// Some(dev) => rodio::output_devices()
// .find(|x| &x.name() == dev)
// .or_else(rodio::default_output_device)
// .expect("No Audio devices found!"),
// None => rodio::default_output_device().expect("No Audio devices found!"),
// };
// let sink = SpatialSink::new(
// &device.device,
// [0.0, 0.0, 0.0],
@ -350,9 +327,9 @@ impl AudioConfig for MonoEmitter {
// /// If the string is an invalid audio device, then no change is made.
// fn set_device(&mut self, name: String) {
// if let Some(dev) = rodio::output_devices().find(|x| x.name() == name) {
// self.device.device = dev;
// self.device = dev;
// self.stream = SpatialSink::new(
// &self.device.device,
// &self.device,
// [0.0, 0.0, 0.0],
// [1.0, 0.0, 0.0],
// [-1.0, 0.0, 0.0],
@ -419,9 +396,10 @@ pub(crate) fn select_random_music(genre: &Genre) -> String {
soundtracks[index].clone()
}
fn send_msg(tx: &mut Sender<AudioPlayerMsg>, msg: AudioPlayerMsg) {
tx.send(msg)
.expect("Failed on attempting to send a message into audio channel.");
/// Returns a vec of the audio devices available.
/// Does not return rodio Device struct in case our audio backend changes.
pub(crate) fn list_devices() -> Vec<String> {
list_devices_raw().iter().map(|x| x.name()).collect()
}
/// Returns vec of devices
@ -429,6 +407,11 @@ fn list_devices_raw() -> Vec<Device> {
rodio::output_devices().collect()
}
fn send_msg(tx: &mut Sender<AudioPlayerMsg>, msg: AudioPlayerMsg) {
tx.send(msg)
.expect("Failed on attempting to send a message into audio channel.");
}
#[test]
fn test_load_soundtracks() {
use crate::audio::base::{load_soundtracks, Genre};

View File

@ -3,12 +3,16 @@ use base::{Genre, Jukebox};
pub struct AudioFrontend {
pub(crate) model: Jukebox,
pub(crate) default_device: String,
pub(crate) device_list: Vec<String>,
}
impl AudioFrontend {
pub(crate) fn new() -> Self {
Self {
model: Jukebox::new(Genre::Bgm),
default_device: base::get_default_device(),
device_list: base::list_devices(),
}
}
@ -30,6 +34,8 @@ impl AudioFrontend {
pub(crate) fn no_audio() -> Self {
Self {
model: Jukebox::new(Genre::None),
default_device: "None".to_owned(),
device_list: Vec::new(),
}
}
}

View File

@ -1,7 +1,6 @@
use super::{img_ids::Imgs, CrosshairType, Fonts, Show, TEXT_COLOR};
use crate::{
audio::base::{AudioDevice, Genre},
settings::AudioSettings,
audio::base::Genre,
ui::{ImageSlider, ToggleButton},
GlobalState,
};
@ -906,9 +905,8 @@ impl<'a> Widget for SettingsWindow<'a> {
// Audio Device Selector --------------------------------------------
match self.global_state.audio.model.get_genre() {
Genre::Bgm => {
let init = AudioDevice::new(&AudioSettings::default());
let device = init.get_device();
let device_list = init.list_devices();
let device = &self.global_state.audio.default_device;
let device_list = &self.global_state.audio.device_list;
Text::new("Volume")
.down_from(state.ids.audio_volume_slider, 10.0)
.font_size(14)
@ -917,7 +915,7 @@ impl<'a> Widget for SettingsWindow<'a> {
.set(state.ids.audio_device_text, ui);
// Get which device is currently selected
let selected = device_list.iter().position(|x| x.contains(&device));
let selected = device_list.iter().position(|x| x.contains(device));
if let Some(clicked) = DropDownList::new(&device_list, selected)
.w_h(400.0, 22.0)