use crate::storage::asset::{project::Project, scene::grid::GridLocation};
use kanal::{Receiver, Sender, unbounded};
use once_cell::sync::{Lazy, OnceCell};
use parking_lot::Mutex;
use std::sync::Arc;
static SENDER: OnceCell<Sender<ProjectState>> = OnceCell::new();
static SUBSCRIBERS: Lazy<Mutex<Vec<Sender<ProjectState>>>> = Lazy::new(|| Mutex::new(Vec::new()));
#[derive(Debug, Clone)]
pub(crate) struct ProjectState {
pub(crate) project: Option<Arc<Project>>,
pub(crate) selected_scene_instance: GridLocation,
pub(crate) blackout: bool,
pub(crate) beats_per_minute: f32,
pub(crate) beat_progression: f32,
}
impl ProjectState {
pub(crate) fn enqueue(self) {
SENDER
.get()
.expect("Could not get project state sender")
.send(self)
.expect("Could not send project state");
}
}
pub(crate) fn init() {
let (sender, receiver) = unbounded();
SENDER
.set(sender)
.expect("Could not set project state sender");
std::thread::spawn(move || {
#[cfg(feature = "profiling")]
profiling::register_thread!("output:state");
for state in receiver {
SUBSCRIBERS
.lock()
.retain(|subscriber| subscriber.send(state.clone()).is_ok());
}
});
}
pub(crate) fn new_receiver() -> Receiver<ProjectState> {
let (sender, receiver) = unbounded();
SUBSCRIBERS.lock().push(sender);
receiver
}