iced_winit/
proxy.rs
1use crate::futures::futures::{
2 Future, Sink, StreamExt,
3 channel::mpsc,
4 select,
5 task::{Context, Poll},
6};
7use crate::runtime::Action;
8use std::pin::Pin;
9
10#[derive(Debug)]
12pub struct Proxy<T: 'static> {
13 raw: winit::event_loop::EventLoopProxy<Action<T>>,
14 sender: mpsc::Sender<Action<T>>,
15 notifier: mpsc::Sender<usize>,
16}
17
18impl<T: 'static> Clone for Proxy<T> {
19 fn clone(&self) -> Self {
20 Self {
21 raw: self.raw.clone(),
22 sender: self.sender.clone(),
23 notifier: self.notifier.clone(),
24 }
25 }
26}
27
28impl<T: 'static> Proxy<T> {
29 const MAX_SIZE: usize = 100;
30
31 pub fn new(
33 raw: winit::event_loop::EventLoopProxy<Action<T>>,
34 ) -> (Self, impl Future<Output = ()>) {
35 let (notifier, mut processed) = mpsc::channel(Self::MAX_SIZE);
36 let (sender, mut receiver) = mpsc::channel(Self::MAX_SIZE);
37 let proxy = raw.clone();
38
39 let worker = async move {
40 let mut count = 0;
41
42 loop {
43 if count < Self::MAX_SIZE {
44 select! {
45 message = receiver.select_next_some() => {
46 let _ = proxy.send_event(message);
47 count += 1;
48
49 }
50 amount = processed.select_next_some() => {
51 count = count.saturating_sub(amount);
52 }
53 complete => break,
54 }
55 } else {
56 select! {
57 amount = processed.select_next_some() => {
58 count = count.saturating_sub(amount);
59 }
60 complete => break,
61 }
62 }
63 }
64 };
65
66 (
67 Self {
68 raw,
69 sender,
70 notifier,
71 },
72 worker,
73 )
74 }
75
76 pub fn send(&mut self, value: T)
81 where
82 T: std::fmt::Debug,
83 {
84 self.send_action(Action::Output(value));
85 }
86
87 pub fn send_action(&mut self, action: Action<T>)
92 where
93 T: std::fmt::Debug,
94 {
95 self.raw
96 .send_event(action)
97 .expect("Send message to event loop");
98 }
99
100 pub fn free_slots(&mut self, amount: usize) {
103 let _ = self.notifier.start_send(amount);
104 }
105}
106
107impl<T: 'static> Sink<Action<T>> for Proxy<T> {
108 type Error = mpsc::SendError;
109
110 fn poll_ready(
111 mut self: Pin<&mut Self>,
112 cx: &mut Context<'_>,
113 ) -> Poll<Result<(), Self::Error>> {
114 self.sender.poll_ready(cx)
115 }
116
117 fn start_send(
118 mut self: Pin<&mut Self>,
119 action: Action<T>,
120 ) -> Result<(), Self::Error> {
121 self.sender.start_send(action)
122 }
123
124 fn poll_flush(
125 mut self: Pin<&mut Self>,
126 cx: &mut Context<'_>,
127 ) -> Poll<Result<(), Self::Error>> {
128 match self.sender.poll_ready(cx) {
129 Poll::Ready(Err(ref e)) if e.is_disconnected() => {
130 Poll::Ready(Ok(()))
132 }
133 x => x,
134 }
135 }
136
137 fn poll_close(
138 mut self: Pin<&mut Self>,
139 _cx: &mut Context<'_>,
140 ) -> Poll<Result<(), Self::Error>> {
141 self.sender.disconnect();
142 Poll::Ready(Ok(()))
143 }
144}