use std::thread;
use std::sync::mpsc::*;
fn wrap_fnonce<TFn: FnOnce() -> ()>(job: TFn) -> impl FnMut() -> () {
let mut job = Some(job);
move || {
let job = job.take();
if let Some(job) = job {
job()
} else {
panic!("Cannot evaluate a job more than once")
}
}
}
pub struct SchedulerThread {
jobs: Sender<Box<dyn FnMut() -> ()+Send>>,
thread: thread::JoinHandle<()>,
}
impl SchedulerThread {
pub fn new() -> SchedulerThread {
let (jobs_in, jobs_out): (Sender<Box<dyn FnMut() -> ()+Send>>, Receiver<Box<dyn FnMut() -> ()+Send>>) = channel();
let thread = thread::Builder::new()
.name("desync jobs thread".to_string())
.spawn(move || {
while let Ok(mut job) = jobs_out.recv() {
(*job)();
}
}).unwrap();
SchedulerThread {
jobs: jobs_in,
thread: thread
}
}
pub fn run<Job: 'static+FnOnce() -> ()+Send>(&self, job: Job) {
self.jobs.send(Box::new(wrap_fnonce(job))).unwrap();
}
pub fn is_finished(&self) -> bool {
self.thread.is_finished()
}
pub fn despawn(self) -> thread::JoinHandle<()> {
self.thread
}
}