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}