1use std::{
2 boxed::Box,
3 future::Future,
4 mem, panic,
5 panic::{catch_unwind, AssertUnwindSafe},
6 pin::Pin,
7 task::{Context, Poll, Waker},
8};
9
10use crate::{application::ApplicationHandle, core::application::*, HasHandle};
11
12
13struct DelegateData<'a, 'b, O, H, R> {
15 handle: O,
16 result: &'a mut Option<Result<R, DelegateError>>,
17 func: Box<dyn FnOnce(&H) -> R + Send + 'b>,
18 waker: Waker,
19}
20struct DelegateFutureData<'a, 'b, R>
24where
25 R: Send,
26{
27 inner: &'b mut DelegateFutureInner<'a, R>,
28 waker: Waker,
29}
30
31#[derive(Debug)]
34pub enum DelegateError {
35 RuntimeNotAvailable,
38 ClosurePanicked,
40}
41
42pub struct DelegateFuture<'a, O, H, R>
44where
45 R: Send,
46{
47 handle: O,
48 func: Option<Box<dyn FnOnce(&H) -> R + Send + 'a>>,
49 result: Option<Result<R, DelegateError>>,
50 started: bool,
51}
52impl<'a, O, H, R> Unpin for DelegateFuture<'a, O, H, R> where R: Send {}
53unsafe impl<'a, O, H, R> Send for DelegateFuture<'a, O, H, R> where R: Send {}
60
61pub struct DelegateFutureFuture<'a, R>
63where
64 R: Send,
65{
66 app_handle: ApplicationHandle,
67 inner: DelegateFutureInner<'a, R>,
68 started: bool,
69}
70unsafe impl<'a, R> Send for DelegateFutureFuture<'a, R> where R: Send {}
77impl<'a, R> Unpin for DelegateFutureFuture<'a, R> where R: Send {}
78
79struct DelegateFutureInner<'a, R>
82where
83 R: Send,
84{
85 result: Option<Result<R, DelegateError>>,
86 future: Pin<Box<dyn Future<Output = R> + 'a>>,
87}
88unsafe impl<'a, R> Send for DelegateFutureInner<'a, R> where R: Send {}
101
102
103#[cfg(feature = "threadsafe")]
104impl<'a, O, H, R> DelegateFuture<'a, O, H, R>
105where
106 R: Send,
107{
108 pub(super) fn new<F>(handle: O, func: F) -> Self
109 where
110 F: FnOnce(&H) -> R + Send + 'a,
111 R: Send,
112 {
113 Self {
114 handle,
115 func: Some(Box::new(func)),
116 result: None,
117 started: false,
118 }
119 }
120}
121
122#[cfg(feature = "threadsafe")]
123impl<'a, O, H, R> Future for DelegateFuture<'a, O, H, R>
124where
125 O: HasHandle<H> + HasHandle<ApplicationHandle> + Clone,
126 H: 'static,
127 R: Send + 'static,
128{
129 type Output = Result<R, DelegateError>;
130
131 fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
132 if !self.started {
133 self.started = true;
134 let app_inner = HasHandle::<ApplicationHandle>::handle(&self.handle)
135 .inner
136 .clone();
137
138 let mut func = None;
140 mem::swap(&mut self.func, &mut func);
141
142 let data = DelegateData {
147 handle: self.handle.clone(),
148 func: func.unwrap(),
149 result: &mut self.result,
150 waker: cx.waker().clone(),
151 };
152
153 let succeeded = {
154 let data_ptr = Box::into_raw(Box::new(data));
155
156 app_inner.dispatch(delegate_handler::<O, H, R>, data_ptr as _)
157 };
158
159 if !succeeded {
161 return Poll::Ready(Err(DelegateError::RuntimeNotAvailable));
162 }
163
164 Poll::Pending
165 } else {
166 if self.result.is_none() {
167 return Poll::Pending;
168 }
169
170 let mut temp: Option<Result<R, DelegateError>> = None;
172 mem::swap(&mut self.result, &mut temp);
173
174 Poll::Ready(temp.unwrap())
175 }
176 }
177}
178
179#[cfg(feature = "threadsafe")]
180impl<'a, R> DelegateFutureFuture<'a, R>
181where
182 R: Send,
183{
184 pub(super) fn new(app_handle: ApplicationHandle, future: impl Future<Output = R> + 'a) -> Self {
185 Self {
186 app_handle,
187 inner: DelegateFutureInner {
188 result: None,
189 future: Box::pin(future),
190 },
191 started: false,
192 }
193 }
194}
195
196#[cfg(feature = "threadsafe")]
197impl<'a, R> Future for DelegateFutureFuture<'a, R>
198where
199 R: Send,
200{
201 type Output = Result<R, DelegateError>;
202
203 fn poll(mut self: Pin<&mut Self>, ctx: &mut Context) -> Poll<Self::Output> {
204 if !self.started {
206 self.started = true;
207 let app_inner = self.app_handle.inner.clone();
208
209 let data_ptr = Box::into_raw(Box::new(DelegateFutureData {
210 inner: &mut self.inner,
211 waker: ctx.waker().clone(),
212 }));
213
214 let succeeded = app_inner.dispatch(delegate_async_handler::<R>, data_ptr as _);
215
216 if !succeeded {
219 return Poll::Ready(Err(DelegateError::RuntimeNotAvailable));
220 }
221
222 Poll::Pending
223 } else {
224 let mut temp: Option<Result<R, DelegateError>> = None;
226 mem::swap(&mut self.inner.result, &mut temp);
227
228 Poll::Ready(temp.unwrap())
229 }
230 }
231}
232
233
234fn delegate_handler<O, H, R>(app: ApplicationImpl, _data: *mut ())
235where
236 H: 'static,
237 O: HasHandle<H>,
238 R: 'static,
239{
240 let data_ptr = _data as *mut DelegateData<'static, 'static, O, H, R>;
241 let data = unsafe { Box::from_raw(data_ptr) }; match *data {
244 DelegateData {
245 handle,
246 func,
247 result,
248 waker,
249 } => {
250 match catch_unwind(AssertUnwindSafe(|| {
252 let h = handle.handle();
253 *result = Some(Ok(func(h)));
254 waker.clone().wake();
255 })) {
256 Ok(()) => {}
257 Err(_) => {
258 *result = Some(Err(DelegateError::ClosurePanicked));
259
260 waker.wake();
263
264 app.exit(-1);
265 }
266 }
267 }
268 }
269}
270
271#[cfg(feature = "threadsafe")]
272fn delegate_async_handler<R>(app: ApplicationImpl, _data: *mut ())
273where
274 R: Send,
275{
276 let data_ptr = _data as *mut DelegateFutureData<R>;
277 let data = unsafe { Box::from_raw(data_ptr) }; match *data {
280 DelegateFutureData { inner, waker } => {
281 match panic::catch_unwind(AssertUnwindSafe(|| {
283 let mut ctx = Context::from_waker(&waker);
284 match inner.future.as_mut().poll(&mut ctx) {
285 Poll::Pending => {}
286 Poll::Ready(result) => {
287 inner.result = Some(Ok(result));
289 waker.clone().wake();
290 }
291 }
292 })) {
293 Ok(()) => {}
294 Err(_) => {
295 inner.result = Some(Err(DelegateError::ClosurePanicked));
296
297 waker.wake();
300
301 app.exit(-1);
302 }
303 }
304 }
305 }
306}