jay-compositor 1.15.0

The Jay compositor
use crate::state::State;
use crate::utils::event_listener::EventSource;
use crate::utils::queue::AsyncQueue;
use std::cell::Cell;
use std::ops::Deref;
use std::rc::Rc;

pub async fn handle_lazy_event_sources(state: Rc<State>) {
    loop {
        let source = state.lazy_event_sources.queue.pop().await;
        source.queued.set(false);
        source.listeners.for_each(|listener| {
            listener.triggered();
        });
    }
}

#[derive(Default)]
pub struct LazyEventSources {
    queue: AsyncQueue<Rc<LazyEventSource>>,
}

pub trait LazyEventSourceListener {
    fn triggered(self: Rc<Self>);
}

pub struct LazyEventSource {
    sources: Rc<LazyEventSources>,
    queued: Cell<bool>,
    listeners: EventSource<dyn LazyEventSourceListener>,
}

impl Deref for LazyEventSource {
    type Target = EventSource<dyn LazyEventSourceListener>;

    fn deref(&self) -> &Self::Target {
        &self.listeners
    }
}

impl LazyEventSource {
    pub fn trigger(self: &Rc<Self>) {
        if self.listeners.is_empty() {
            return;
        }
        if self.queued.replace(true) {
            return;
        }
        self.sources.queue.push(self.clone());
    }
}

impl LazyEventSources {
    pub fn create_source(self: &Rc<Self>) -> Rc<LazyEventSource> {
        Rc::new(LazyEventSource {
            sources: self.clone(),
            queued: Default::default(),
            listeners: Default::default(),
        })
    }

    pub fn clear(&self) {
        self.queue.clear();
    }
}