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