fltk/app/
channel.rs

1use std::any::Any;
2use std::marker;
3use std::sync::LazyLock;
4
5type Chan = (
6    crossbeam_channel::Sender<Box<dyn Any + Send + Sync>>,
7    crossbeam_channel::Receiver<Box<dyn Any + Send + Sync>>,
8);
9
10static CHANNEL: LazyLock<Chan> = LazyLock::new(crossbeam_channel::unbounded);
11static SENDER: LazyLock<crossbeam_channel::Sender<Box<dyn Any + Send + Sync>>> =
12    LazyLock::new(|| CHANNEL.clone().0);
13static RECEIVER: LazyLock<crossbeam_channel::Receiver<Box<dyn Any + Send + Sync>>> =
14    LazyLock::new(|| CHANNEL.clone().1);
15
16/// Creates a sender struct
17#[derive(Debug)]
18pub struct Sender<T> {
19    data: marker::PhantomData<T>,
20}
21
22unsafe impl<T: Send + Sync> Send for Sender<T> {}
23unsafe impl<T: Send + Sync> Sync for Sender<T> {}
24impl<T: Send + Sync> Copy for Sender<T> {}
25
26// Manually create the impl so there's no Clone bound on T
27impl<T: Send + Sync> Clone for Sender<T> {
28    fn clone(&self) -> Self {
29        *self
30    }
31}
32
33impl<T: 'static + Send + Sync> Sender<T> {
34    /// Sends a message
35    pub fn send(&self, val: T) {
36        SENDER.try_send(Box::new(val)).ok();
37        crate::app::awake();
38    }
39    /// Get the global sender
40    pub fn get() -> Self {
41        Sender {
42            data: marker::PhantomData,
43        }
44    }
45}
46
47/// Creates a receiver struct
48#[derive(Debug)]
49pub struct Receiver<T> {
50    data: marker::PhantomData<T>,
51}
52
53unsafe impl<T: Send + Sync> Send for Receiver<T> {}
54unsafe impl<T: Send + Sync> Sync for Receiver<T> {}
55impl<T: Send + Sync> Copy for Receiver<T> {}
56
57// Manually create the impl so there's no Clone bound on T
58impl<T: Send + Sync> Clone for Receiver<T> {
59    fn clone(&self) -> Self {
60        *self
61    }
62}
63
64impl<T: 'static + Send + Sync> Receiver<T> {
65    /// Receives a message
66    pub fn recv(&self) -> Option<T> {
67        if let Ok(msg) = RECEIVER.try_recv() {
68            if let Ok(t) = (msg as Box<dyn Any + 'static>).downcast::<T>() {
69                Some(*t)
70            } else {
71                None
72            }
73        } else {
74            None
75        }
76    }
77    /// Get the global receiver
78    pub fn get() -> Self {
79        Receiver {
80            data: marker::PhantomData,
81        }
82    }
83}
84
85/// Creates a channel returning a Sender and Receiver structs (mpsc: multiple producer single consumer).
86pub fn channel<T: Send + Sync>() -> (Sender<T>, Receiver<T>) {
87    let s = Sender {
88        data: marker::PhantomData,
89    };
90    let r = Receiver {
91        data: marker::PhantomData,
92    };
93    (s, r)
94}