azul_webrender_api/
channel.rs1use crate::{Epoch, PipelineId};
6use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
7use serde::{Deserialize, Deserializer, Serialize, Serializer};
8use std::io::{self, Cursor, Error, ErrorKind, Read};
9use std::mem;
10
11pub use crossbeam_channel as crossbeam;
12
13#[cfg(not(target_os = "windows"))]
14pub use crossbeam_channel::{Sender, Receiver};
15
16#[cfg(target_os = "windows")]
17pub use std::sync::mpsc::{Sender, Receiver};
18
19#[derive(Clone)]
20pub struct Payload {
21 pub epoch: Epoch,
27 pub pipeline_id: PipelineId,
29 pub display_list_data: Vec<u8>,
30}
31
32impl Payload {
33 pub fn construct_data(epoch: Epoch, pipeline_id: PipelineId, dl_data: &[u8]) -> Vec<u8> {
37 let mut data = Vec::with_capacity(
38 mem::size_of::<u32>() + 2 * mem::size_of::<u32>() + mem::size_of::<u64>() + dl_data.len(),
39 );
40 data.write_u32::<LittleEndian>(epoch.0).unwrap();
41 data.write_u32::<LittleEndian>(pipeline_id.0).unwrap();
42 data.write_u32::<LittleEndian>(pipeline_id.1).unwrap();
43 data.write_u64::<LittleEndian>(dl_data.len() as u64)
44 .unwrap();
45 data.extend_from_slice(dl_data);
46 data
47 }
48 pub fn to_data(&self) -> Vec<u8> {
51 Self::construct_data(self.epoch, self.pipeline_id, &self.display_list_data)
52 }
53
54 pub fn from_data(data: &[u8]) -> Payload {
56 let mut payload_reader = Cursor::new(data);
57 let epoch = Epoch(payload_reader.read_u32::<LittleEndian>().unwrap());
58 let pipeline_id = PipelineId(
59 payload_reader.read_u32::<LittleEndian>().unwrap(),
60 payload_reader.read_u32::<LittleEndian>().unwrap(),
61 );
62
63 let dl_size = payload_reader.read_u64::<LittleEndian>().unwrap() as usize;
64 let mut built_display_list_data = vec![0; dl_size];
65 payload_reader
66 .read_exact(&mut built_display_list_data[..])
67 .unwrap();
68
69 assert_eq!(payload_reader.position(), data.len() as u64);
70
71 Payload {
72 epoch,
73 pipeline_id,
74 display_list_data: built_display_list_data,
75 }
76 }
77}
78
79pub type PayloadSender = MsgSender<Payload>;
80
81pub type PayloadReceiver = MsgReceiver<Payload>;
82
83pub struct MsgReceiver<T> {
84 rx: Receiver<T>,
85}
86
87impl<T> MsgReceiver<T> {
88 pub fn recv(&self) -> Result<T, Error> {
89 self.rx.recv().map_err(|e| io::Error::new(ErrorKind::Other, e.to_string()))
90 }
91
92 pub fn to_crossbeam_receiver(self) -> Receiver<T> {
93 self.rx
94 }
95}
96
97#[derive(Clone)]
98pub struct MsgSender<T> {
99 tx: Sender<T>,
100}
101
102impl<T> MsgSender<T> {
103 pub fn send(&self, data: T) -> Result<(), Error> {
104 self.tx.send(data).map_err(|_| Error::new(ErrorKind::Other, "cannot send on closed channel"))
105 }
106}
107
108pub fn payload_channel() -> Result<(PayloadSender, PayloadReceiver), Error> {
109 let (tx, rx) = unbounded_channel();
110 Ok((PayloadSender { tx }, PayloadReceiver { rx }))
111}
112
113pub fn msg_channel<T>() -> Result<(MsgSender<T>, MsgReceiver<T>), Error> {
114 let (tx, rx) = unbounded_channel();
115 Ok((MsgSender { tx }, MsgReceiver { rx }))
116}
117
118impl<T> Serialize for MsgSender<T> {
128 fn serialize<S: Serializer>(&self, _: S) -> Result<S::Ok, S::Error> {
129 unreachable!();
130 }
131}
132
133impl<'de, T> Deserialize<'de> for MsgSender<T> {
134 fn deserialize<D>(_: D) -> Result<MsgSender<T>, D::Error>
135 where D: Deserializer<'de> {
136 unreachable!();
137 }
138}
139
140#[cfg(not(target_os = "windows"))]
143pub fn single_msg_channel<T>() -> (Sender<T>, Receiver<T>) {
144 crossbeam_channel::bounded(1)
145}
146
147#[cfg(not(target_os = "windows"))]
156pub fn fast_channel<T>(capacity: usize) -> (Sender<T>, Receiver<T>) {
157 crossbeam_channel::bounded(capacity)
158}
159
160#[cfg(not(target_os = "windows"))]
164pub use crossbeam_channel::unbounded as unbounded_channel;
165
166
167#[cfg(target_os = "windows")]
168pub fn fast_channel<T>(_cap: usize) -> (Sender<T>, Receiver<T>) {
169 std::sync::mpsc::channel()
170}
171
172#[cfg(target_os = "windows")]
173pub fn unbounded_channel<T>() -> (Sender<T>, Receiver<T>) {
174 std::sync::mpsc::channel()
175}
176
177#[cfg(target_os = "windows")]
178pub fn single_msg_channel<T>() -> (Sender<T>, Receiver<T>) {
179 std::sync::mpsc::channel()
180}