selene-daemon 0.9.0-alpha.2

Official music player daemon for Selene
Documentation
// Deny instead of forbid, as plugin-supoprt requires unsafe code to load libraries
#![deny(unsafe_code)]

use std::{
    fmt::Display,
    sync::{
        OnceLock,
        atomic::{AtomicBool, Ordering},
    },
};

#[cfg(feature = "daemon")]
use lunar_lib::database::{DatabaseError, Db};

// Shutdown atomic. If ever set to true, all threads should exit
static SHUTDOWN: AtomicBool = AtomicBool::new(false);
pub(crate) fn should_shutdown() -> bool {
    SHUTDOWN.load(Ordering::Relaxed)
}
pub(crate) fn shutdown(reason: impl Display) {
    lunar_lib::log::error!("A shutdown has been issued: {reason}");
    SHUTDOWN.store(true, Ordering::Release);
}

// Database
#[cfg(feature = "daemon")]
static LIBRARY_DATABASE: OnceLock<Db<Library>> = OnceLock::new();
#[cfg(feature = "daemon")]
pub(crate) fn init_library_db() -> Result<(), DatabaseError> {
    let db = Db::open()?;
    assert!(LIBRARY_DATABASE.set(db).is_ok());
    Ok(())
}

#[cfg(feature = "daemon")]
pub(crate) fn library_db() -> &'static Db<Library> {
    LIBRARY_DATABASE.get().expect("Database not initialized")
}

#[cfg(feature = "daemon")]
static IMAGE_DATABASE: OnceLock<Db<Images>> = OnceLock::new();
#[cfg(feature = "daemon")]
pub(crate) fn init_images_db() -> Result<(), DatabaseError> {
    let db = Db::open()?;
    assert!(IMAGE_DATABASE.set(db).is_ok());
    Ok(())
}

#[cfg(feature = "daemon")]
pub(crate) fn image_db() -> &'static Db<Images> {
    IMAGE_DATABASE.get().expect("Database not initialized")
}

mod common;
pub use common::*;

mod ipc_common;

#[cfg(feature = "daemon")]
mod session;

/// Items related to hosting the daemon
#[cfg(feature = "daemon")]
pub mod daemon;

mod listener;

#[cfg(feature = "daemon")]
mod process;

#[cfg(feature = "local-session")]
pub(crate) mod local_session;

#[cfg(feature = "plugin-support")]
pub(crate) mod plugin_sdk_ext;

#[cfg(feature = "daemon")]
mod decoder;

/// Items related to connecting to the daemon as a client
#[cfg(feature = "client")]
pub mod client;

/// Config related to the daemon, only important for programs that want to change the local daemon config, this will not update remote server config
pub mod config;

// Other
#[cfg(feature = "daemon")]
mod playlist;

mod shuffle_mode;
#[cfg(feature = "daemon")]
use selene_core::{database::Library, library::image_art::Images};
pub use shuffle_mode::*;

mod loop_mode;
pub use loop_mode::*;

/// Sleep the current thread for 1ms. Used to avoid busy looping
pub(crate) fn wait() {
    std::thread::sleep(std::time::Duration::from_millis(1));
}