use std::{
path::{Path, PathBuf},
sync::{
atomic::{AtomicBool, AtomicUsize},
Arc, Mutex,
},
};
use crossbeam_channel::{unbounded, Receiver, Sender};
use diskit::Diskit;
use id3::Tag;
use crate::{
audio::{AudioHandler, ChannelAudio},
commands::Command,
conffile::Conffile,
files::ensure_file_existence,
l10n::{L10n, Writer},
songs::Repeat,
Error,
};
pub struct Config
{
pub(crate) audio_handler: Box<dyn AudioHandler>,
pub(crate) source: ChannelAudio,
pub(crate) tx: Sender<(Command, u32)>,
pub(crate) rx: Receiver<(Command, u32)>,
pub(crate) rx_control: Receiver<()>,
pub(crate) tx_paused: Sender<bool>,
pub(crate) tx_path: Sender<(PathBuf, Option<Tag>)>,
pub(crate) tag: Option<Result<Tag, id3::Error>>,
pub(crate) num: u32,
pub(crate) loud: f32,
pub(crate) paused: bool,
pub(crate) pause_after_song: bool,
pub(crate) quit_after_song: bool,
pub(crate) repeat: Repeat,
pub(crate) songlist: Vec<usize>,
pub(crate) song_index: usize,
pub(crate) arc_config: Arc<ArcConfig>,
pub(crate) l10n: L10n,
pub(crate) unsuccessful_tries: u8,
}
#[allow(clippy::module_name_repetitions)]
pub struct ArcConfig
{
pub pic_path: Mutex<Option<String>>,
pub reading_paused: AtomicBool,
pub update_dbus: AtomicBool,
pub current_pos: AtomicUsize,
pub current_len: AtomicUsize,
pub sample_rate: AtomicUsize,
pub channels: AtomicUsize,
pub monotonic_song_index: AtomicUsize,
pub home_dir: PathBuf,
pub config_dir: PathBuf,
pub conffile: Conffile,
pub l10n: L10n,
}
impl ArcConfig
{
fn new<C, D>(get_conffile: C, writer: Writer, diskit: D) -> Result<Self, Error>
where
C: Fn(&Path, D) -> Conffile,
D: Diskit + Send + 'static,
{
let home_dir = home::home_dir().unwrap_or_else(|| PathBuf::from("./"));
ensure_file_existence(&home_dir, diskit.clone())?;
let conffile_dir = home_dir.join(PathBuf::from("./.zvavybir/legacylisten"));
let conffile = get_conffile(&conffile_dir, diskit.clone());
let l10n = L10n::new(conffile.lang.clone(), writer, diskit)?;
Ok(Self {
pic_path: Mutex::new(None),
reading_paused: AtomicBool::new(false),
update_dbus: AtomicBool::new(false),
current_pos: AtomicUsize::new(0),
current_len: AtomicUsize::new(0),
sample_rate: AtomicUsize::new(1),
channels: AtomicUsize::new(1),
monotonic_song_index: AtomicUsize::new(0),
home_dir,
config_dir: conffile_dir,
conffile,
l10n,
})
}
}
impl Config
{
pub fn new<C, A, D>(
rx_control: Receiver<()>,
tx_paused: Sender<bool>,
tx_path: Sender<(PathBuf, Option<Tag>)>,
get_conffile: C,
writer: Writer,
diskit: D,
) -> Result<Self, Error>
where
C: Fn(&Path, D) -> Conffile,
A: AudioHandler,
D: Diskit + Send + 'static,
{
let (tx, rx) = unbounded();
let arc_config = Arc::new(ArcConfig::new(get_conffile, writer, diskit)?);
let l10n = arc_config.l10n;
Ok(Self {
audio_handler: A::new(),
source: ChannelAudio {
sample_rate: 0,
inner: None,
config: arc_config.clone(),
},
tx,
rx,
rx_control,
tx_paused,
tx_path,
tag: None,
num: 0,
loud: 0.0,
paused: false,
pause_after_song: false,
quit_after_song: false,
repeat: Repeat::Not,
songlist: vec![],
song_index: 0,
arc_config,
l10n,
unsuccessful_tries: 0,
})
}
}