1use fltk_sys::fl;
2use std::any::Any;
3use std::marker;
4use std::sync::LazyLock;
5
6type Chan = (
7 crossbeam_channel::Sender<Box<dyn Any + Send + Sync>>,
8 crossbeam_channel::Receiver<Box<dyn Any + Send + Sync>>,
9);
10
11static CHANNEL: LazyLock<Chan> = LazyLock::new(crossbeam_channel::unbounded);
12static SENDER: LazyLock<crossbeam_channel::Sender<Box<dyn Any + Send + Sync>>> =
13 LazyLock::new(|| CHANNEL.clone().0);
14static RECEIVER: LazyLock<crossbeam_channel::Receiver<Box<dyn Any + Send + Sync>>> =
15 LazyLock::new(|| CHANNEL.clone().1);
16
17#[doc(hidden)]
18pub unsafe fn awake_msg<T>(msg: T) {
22 unsafe {
23 fl::Fl_awake_msg(Box::into_raw(Box::from(msg)) as *mut std::os::raw::c_void);
24 }
25}
26
27#[doc(hidden)]
28pub unsafe fn thread_msg<T>() -> Option<T> {
38 unsafe {
39 let msg = fl::Fl_thread_msg();
40 if msg.is_null() {
41 None
42 } else {
43 let msg = Box::from_raw(msg as *const _ as *mut T);
44 Some(*msg)
45 }
46 }
47}
48
49#[derive(Debug)]
51pub struct Sender<T> {
52 data: marker::PhantomData<T>,
53}
54
55unsafe impl<T: Send + Sync> Send for Sender<T> {}
56unsafe impl<T: Send + Sync> Sync for Sender<T> {}
57impl<T: Send + Sync> Copy for Sender<T> {}
58
59impl<T: Send + Sync> Clone for Sender<T> {
61 fn clone(&self) -> Self {
62 *self
63 }
64}
65
66impl<T: 'static + Send + Sync> Sender<T> {
67 pub fn send(&self, val: T) {
69 SENDER.try_send(Box::new(val)).ok();
70 crate::app::awake();
71 }
72 pub fn get() -> Self {
74 Sender {
75 data: marker::PhantomData,
76 }
77 }
78}
79
80#[derive(Debug)]
82pub struct Receiver<T> {
83 data: marker::PhantomData<T>,
84}
85
86unsafe impl<T: Send + Sync> Send for Receiver<T> {}
87unsafe impl<T: Send + Sync> Sync for Receiver<T> {}
88impl<T: Send + Sync> Copy for Receiver<T> {}
89
90impl<T: Send + Sync> Clone for Receiver<T> {
92 fn clone(&self) -> Self {
93 *self
94 }
95}
96
97impl<T: 'static + Send + Sync> Receiver<T> {
98 pub fn recv(&self) -> Option<T> {
100 if let Ok(msg) = RECEIVER.try_recv() {
101 if let Ok(t) = (msg as Box<dyn Any + 'static>).downcast::<T>() {
102 Some(*t)
103 } else {
104 None
105 }
106 } else {
107 None
108 }
109 }
110 pub fn get() -> Self {
112 Receiver {
113 data: marker::PhantomData,
114 }
115 }
116}
117
118pub fn channel<T: Send + Sync>() -> (Sender<T>, Receiver<T>) {
120 let s = Sender {
121 data: marker::PhantomData,
122 };
123 let r = Receiver {
124 data: marker::PhantomData,
125 };
126 (s, r)
127}