tpx/
lib.rs

1use std::sync::mpsc::{
2    sync_channel,
3    SyncSender,
4};
5
6pub enum Ctn {
7    TASK(Task),
8    DONE,
9}
10
11pub struct Executor {
12    tx: SyncSender<Task>,
13}
14
15impl Executor {
16    pub fn init() -> Self {
17        let (tx, rx) = sync_channel::<Task>(10_000);
18        let tx_c = tx.clone();
19
20        rayon::spawn(move || {
21            rayon::scope(|s| {
22                for task in rx {
23                    s.spawn(|_| {
24                        if let Ctn::TASK(res_task) = task.invoke() {
25                            tx.send(res_task).unwrap();
26                        }
27                    });
28                }
29            });
30        });
31
32        Self {
33            tx: tx_c
34        }
35    }
36
37    pub fn spawn<F>(
38        &self,
39        f: F,
40    ) where
41        F: FnOnce() -> Ctn + Send + 'static,
42    {
43        self.tx.send(Task::new(f)).unwrap();
44    }
45}
46
47pub struct Task {
48    f: Box<dyn FnOnce() -> Ctn + Send + 'static>,
49}
50
51impl Task {
52    fn new<F>(f: F) -> Self
53    where
54        F: FnOnce() -> Ctn + Send + 'static,
55    {
56        let f = Box::new(f);
57        Self {
58            f,
59        }
60    }
61
62    fn invoke(self) -> Ctn {
63        (self.f)()
64    }
65}
66
67pub fn continue_with<F>(f: F) -> Ctn
68where
69    F: FnOnce() -> Ctn + Send + 'static,
70{
71    Ctn::TASK(Task::new(f))
72}