jay-compositor 1.15.0

The Jay compositor
use crate::async_engine::AsyncEngine;
use crate::async_engine::SpawnedFuture;
use crate::utils::queue::AsyncQueue;
use std::cell::Cell;
use std::rc::Rc;

pub struct RunToplevelFuture {
    _future: SpawnedFuture<()>,
}

pub struct RunToplevel {
    cleared: Cell<bool>,
    queue: AsyncQueue<Box<dyn FnOnce()>>,
}

impl RunToplevel {
    pub fn install(eng: &Rc<AsyncEngine>) -> (RunToplevelFuture, Rc<RunToplevel>) {
        let slf = Rc::new(RunToplevel {
            cleared: Default::default(),
            queue: Default::default(),
        });
        let future = eng.spawn("run toplevel", {
            let slf = slf.clone();
            async move {
                loop {
                    let f = slf.queue.pop().await;
                    f();
                }
            }
        });
        let future = RunToplevelFuture { _future: future };
        (future, slf)
    }

    pub fn schedule<F: FnOnce() + 'static>(&self, f: F) {
        self.schedule_dyn(Box::new(f));
    }

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

    fn schedule_dyn(&self, f: Box<dyn FnOnce()>) {
        if self.cleared.get() {
            return;
        }
        self.queue.push(f);
    }
}